diff --git a/core/fmt.odin b/core/fmt.odin index f3244a748..690365327 100644 --- a/core/fmt.odin +++ b/core/fmt.odin @@ -65,12 +65,12 @@ write_rune :: proc(buf: ^String_Buffer, r: rune) { write_bytes(buf, b[..n]); } -write_int :: proc(buf: ^String_Buffer, i: i128, base: int) { +write_i128 :: proc(buf: ^String_Buffer, i: i128, base: int) { b: [129]byte; s := strconv.append_bits(b[..], u128(i), base, true, 128, strconv.digits, 0); write_string(buf, s); } -write_int :: proc(buf: ^String_Buffer, i: i64, base: int) { +write_i64 :: proc(buf: ^String_Buffer, i: i64, base: int) { b: [129]byte; s := strconv.append_bits(b[..], u128(i), base, true, 64, strconv.digits, 0); write_string(buf, s); @@ -171,7 +171,7 @@ write_type :: proc(buf: ^String_Buffer, ti: ^Type_Info) { case: if info.signed do write_byte(buf, 'i'); else do write_byte(buf, 'u'); - write_int(buf, i64(8*ti.size), 10); + write_i64(buf, i64(8*ti.size), 10); } case Type_Info_Rune: write_string(buf, "rune"); @@ -235,7 +235,7 @@ write_type :: proc(buf: ^String_Buffer, ti: ^Type_Info) { case Type_Info_Array: write_string(buf, "["); fi := Fmt_Info{buf = buf}; - write_int(buf, i64(info.count), 10); + write_i64(buf, i64(info.count), 10); write_string(buf, "]"); write_type(buf, info.elem); case Type_Info_Dynamic_Array: @@ -258,7 +258,7 @@ write_type :: proc(buf: ^String_Buffer, ti: ^Type_Info) { if info.is_raw_union do write_string(buf, "#raw_union "); if info.custom_align { write_string(buf, "#align "); - write_int(buf, i64(ti.align), 10); + write_i64(buf, i64(ti.align), 10); write_byte(buf, ' '); } write_byte(buf, '{'); @@ -292,7 +292,7 @@ write_type :: proc(buf: ^String_Buffer, ti: ^Type_Info) { write_string(buf, "bit_field "); if ti.align != 1 { write_string(buf, "#align "); - write_int(buf, i64(ti.align), 10); + write_i64(buf, i64(ti.align), 10); write_rune(buf, ' '); } write_string(buf, " {"); @@ -300,7 +300,7 @@ write_type :: proc(buf: ^String_Buffer, ti: ^Type_Info) { if i > 0 do write_string(buf, ", "); write_string(buf, name); write_string(buf, ": "); - write_int(buf, i64(info.bits[i]), 10); + write_i64(buf, i64(info.bits[i]), 10); } write_string(buf, "}"); } diff --git a/core/utf16.odin b/core/utf16.odin index 762079c1e..2268fd049 100644 --- a/core/utf16.odin +++ b/core/utf16.odin @@ -38,11 +38,11 @@ encode :: proc(d: []u16, s: []rune) -> int { for r in s { switch r { - case 0.._surr1, _surr3.._surr_self: + case 0.._surr1, _surr3 .. _surr_self: d[n] = u16(r); n += 1; - case _surr_self..MAX_RUNE: + case _surr_self .. MAX_RUNE: r1, r2 := encode_surrogate_pair(r); d[n] = u16(r1); d[n+1] = u16(r2); @@ -66,11 +66,11 @@ encode :: proc(d: []u16, s: string) -> int { for r in s { switch r { - case 0.._surr1, _surr3.._surr_self: + case 0.._surr1, _surr3 .. _surr_self: d[n] = u16(r); n += 1; - case _surr_self..MAX_RUNE: + case _surr_self .. MAX_RUNE: r1, r2 := encode_surrogate_pair(r); d[n] = u16(r1); d[n+1] = u16(r2); diff --git a/examples/demo.odin b/examples/demo.odin index 4992df87f..e218bd7c2 100644 --- a/examples/demo.odin +++ b/examples/demo.odin @@ -120,10 +120,10 @@ default_struct_values :: proc() { heap_one := new(Vector3); defer free(heap_one); heap_two := new_clone(Vector3{}); defer free(heap_two); - fmt.println("stack_default - ", stack_default); - fmt.println("stack_literal - ", stack_literal); - fmt.println("heap_one - ", heap_one^); - fmt.println("heap_two - ", heap_two^); + fmt.println("stack_default - ", stack_default); + fmt.println("stack_literal - ", stack_literal); + fmt.println("heap_one - ", heap_one^); + fmt.println("heap_two - ", heap_two^); N :: 4; @@ -291,15 +291,15 @@ union_type :: proc() { /* Entity :: struct { ... - derived: union{^Frog, ^Monster}; + derived: union{^Frog, ^Monster}, } Frog :: struct { - using entity: Entity; + using entity: Entity, ... } Monster :: struct { - using entity: Entity; + using entity: Entity, ... } @@ -402,7 +402,7 @@ parametric_polymorphism :: proc() { context <- c { old_slots := table.slots; - cap := max(2*cap(table.slots), TABLE_SIZE_MIN); + cap := max(2*len(table.slots), TABLE_SIZE_MIN); allocate(table, cap); for s in old_slots do if s.occupied { @@ -419,16 +419,16 @@ parametric_polymorphism :: proc() { hash := get_hash(key); // Ad-hoc method which would fail in a different scope index := find_index(table, key, hash); if index < 0 { - if f64(table.count) >= 0.75*f64(cap(table.slots)) { + if f64(table.count) >= 0.75*f64(len(table.slots)) { expand(table); } - assert(table.count <= cap(table.slots)); + assert(table.count <= len(table.slots)); hash := get_hash(key); - index = int(hash % u32(cap(table.slots))); + index = int(hash % u32(len(table.slots))); for table.slots[index].occupied { - if index += 1; index >= cap(table.slots) { + if index += 1; index >= len(table.slots) { index = 0; } } @@ -455,9 +455,9 @@ parametric_polymorphism :: proc() { } find_index :: proc(table: ^Table($Key, $Value), key: Key, hash: u32) -> int { - if cap(table.slots) <= 0 do return -1; + if len(table.slots) <= 0 do return -1; - index := int(hash % u32(cap(table.slots))); + index := int(hash % u32(len(table.slots))); for table.slots[index].occupied { if table.slots[index].hash == hash { if table.slots[index].key == key { @@ -465,7 +465,7 @@ parametric_polymorphism :: proc() { } } - if index += 1; index >= cap(table.slots) { + if index += 1; index >= len(table.slots) { index = 0; } } @@ -565,13 +565,60 @@ threading_example :: proc() { } } +array_programming :: proc() { + fmt.println("# array_programming"); + { + a := [3]f32{1, 2, 3}; + b := [3]f32{5, 6, 7}; + c := a * b; + d := a + b; + e := 1 + (c - d) / 2; + fmt.printf("%.1f\n", e); // [0.5, 3.0, 6.5] + } + + { + a := [3]f32{1, 2, 3}; + b := swizzle(a, 2, 1, 0); + assert(b == [3]f32{3, 2, 1}); + + c := swizzle(a, 0, 0); + assert(c == [2]f32{1, 1}); + assert(c == 1); + } + + { + Vector3 :: [3]f32; + a := Vector3{1, 2, 3}; + b := Vector3{5, 6, 7}; + c := (a * b)/2 + 1; + d := c.x + c.y + c.z; + fmt.printf("%.1f\n", d); // 22.0 + + cross :: proc(a, b: Vector3) -> Vector3 { + i := swizzle(a, 1, 2, 0) * swizzle(b, 2, 0, 1); + j := swizzle(a, 2, 0, 1) * swizzle(b, 1, 2, 0); + return Vector3(i - j); + } + + blah :: proc(a: Vector3) -> f32 { + return a.x + a.y + a.z; + } + + x := cross(a, b); + fmt.println(x); + fmt.println(blah(x)); + } +} + + main :: proc() { - when true { + when false { general_stuff(); default_struct_values(); union_type(); parametric_polymorphism(); threading_example(); + array_programming(); } } diff --git a/src/check_decl.cpp b/src/check_decl.cpp index 72c8dcd0d..b7bd91183 100644 --- a/src/check_decl.cpp +++ b/src/check_decl.cpp @@ -786,6 +786,7 @@ void check_proc_body(Checker *c, Token token, DeclInfo *decl, Type *type, AstNod continue; } bool is_immutable = e->Variable.is_immutable; + bool is_value = (e->flags & EntityFlag_Value) != 0; String name = e->token.string; Type *t = base_type(type_deref(e->type)); if (t->kind == Type_Struct) { @@ -799,6 +800,8 @@ void check_proc_body(Checker *c, Token token, DeclInfo *decl, Type *type, AstNod if (f->kind == Entity_Variable) { Entity *uvar = make_entity_using_variable(c->allocator, e, f->token, f->type); uvar->Variable.is_immutable = is_immutable; + if (is_value) uvar->flags |= EntityFlag_Value; + Entity *prev = scope_insert_entity(c->context.scope, uvar); if (prev != nullptr) { error(e->token, "Namespace collision while 'using' '%.*s' of: %.*s", LIT(name), LIT(prev->token.string)); diff --git a/src/check_expr.cpp b/src/check_expr.cpp index cf1005055..eaa54306c 100644 --- a/src/check_expr.cpp +++ b/src/check_expr.cpp @@ -56,7 +56,7 @@ void check_expr_or_type (Checker *c, Operand *operand, AstNode * ExprKind check_expr_base (Checker *c, Operand *operand, AstNode *expression, Type *type_hint); void check_expr_with_type_hint (Checker *c, Operand *o, AstNode *e, Type *t); Type * check_type (Checker *c, AstNode *expression, Type *named_type = nullptr); -Type * make_optional_ok_type(gbAllocator a, Type *value); +Type * make_optional_ok_type (gbAllocator a, Type *value); void check_type_decl (Checker *c, Entity *e, AstNode *type_expr, Type *def, bool alias); Entity * check_selector (Checker *c, Operand *operand, AstNode *node, Type *type_hint); Entity * check_ident (Checker *c, Operand *o, AstNode *n, Type *named_type, Type *type_hint, bool allow_import_name); @@ -2862,7 +2862,7 @@ bool check_builtin_procedure(Checker *c, Operand *operand, AstNode *call, i32 id mode = Addressing_Constant; value = exact_value_i64(at->Array.count); type = t_untyped_integer; - } else if (is_type_slice(op_type)) { + } else if (is_type_slice(op_type) && id == BuiltinProc_len) { mode = Addressing_Value; } else if (is_type_dynamic_array(op_type)) { mode = Addressing_Value; diff --git a/src/entity.cpp b/src/entity.cpp index 00993d407..940288957 100644 --- a/src/entity.cpp +++ b/src/entity.cpp @@ -200,11 +200,13 @@ Entity *make_entity_type_name(gbAllocator a, Scope *scope, Token token, Type *ty return entity; } -Entity *make_entity_param(gbAllocator a, Scope *scope, Token token, Type *type, bool is_using, bool is_immutable) { +Entity *make_entity_param(gbAllocator a, Scope *scope, Token token, Type *type, bool is_using, bool is_value) { + bool is_immutable = false; Entity *entity = make_entity_variable(a, scope, token, type, is_immutable); entity->flags |= EntityFlag_Used; - if (is_using) entity->flags |= EntityFlag_Using; entity->flags |= EntityFlag_Param; + if (is_using) entity->flags |= EntityFlag_Using; + if (is_value) entity->flags |= EntityFlag_Value; return entity; }