diff --git a/core/math.odin b/core/math.odin index 7ff245651..dc8b26b3b 100644 --- a/core/math.odin +++ b/core/math.odin @@ -319,15 +319,14 @@ look_at :: proc(eye, centre, up: Vec3) -> Mat4 { s := norm(cross(f, up)); u := cross(s, f); - m: Mat4; - - m[0] = [4]f32{+s.x, +s.y, +s.z, 0}; - m[1] = [4]f32{+u.x, +u.y, +u.z, 0}; - m[2] = [4]f32{-f.x, -f.y, -f.z, 0}; - m[3] = [4]f32{dot(s, eye), dot(u, eye), dot(f, eye), 1}; - - return m; + return Mat4{ + {+s.x, +u.x, -f.x, 0}, + {+s.y, +u.y, -f.y, 0}, + {+s.z, +u.z, -f.z, 0}, + {-dot(s, eye), -dot(u, eye), dot(f, eye), 1}, + }; } + perspective :: proc(fovy, aspect, near, far: f32) -> Mat4 { m: Mat4; tan_half_fovy := tan(0.5 * fovy); diff --git a/src/check_expr.c b/src/check_expr.c index db31c25ec..dc98b1bc7 100644 --- a/src/check_expr.c +++ b/src/check_expr.c @@ -3345,10 +3345,15 @@ bool check_builtin_procedure(Checker *c, Operand *operand, AstNode *call, i32 id } } + bool vari_expand = (ce->ellipsis.pos.line != 0); + if (vari_expand && id != BuiltinProc_append) { + error(ce->ellipsis, "Invalid use of `..` with built-in procedure `append`"); + return false; + } + switch (id) { case BuiltinProc_new: - // case BuiltinProc_new_slice: case BuiltinProc_make: case BuiltinProc_size_of: case BuiltinProc_align_of: @@ -4083,50 +4088,34 @@ bool check_builtin_procedure(Checker *c, Operand *operand, AstNode *call, i32 id check_expr(c, &z, ce->args.e[2]); if (z.mode == Addressing_Invalid) return false; check_expr(c, &w, ce->args.e[3]); if (w.mode == Addressing_Invalid) return false; - convert_to_typed(c, &x, y.type, 0); if (x.mode == Addressing_Invalid) return false; - convert_to_typed(c, &x, z.type, 0); if (x.mode == Addressing_Invalid) return false; - convert_to_typed(c, &x, w.type, 0); if (x.mode == Addressing_Invalid) return false; - - convert_to_typed(c, &y, z.type, 0); if (y.mode == Addressing_Invalid) return false; - convert_to_typed(c, &y, w.type, 0); if (y.mode == Addressing_Invalid) return false; - convert_to_typed(c, &y, x.type, 0); if (y.mode == Addressing_Invalid) return false; - - convert_to_typed(c, &z, y.type, 0); if (z.mode == Addressing_Invalid) return false; - convert_to_typed(c, &z, w.type, 0); if (z.mode == Addressing_Invalid) return false; - convert_to_typed(c, &z, x.type, 0); if (z.mode == Addressing_Invalid) return false; - - convert_to_typed(c, &w, x.type, 0); if (w.mode == Addressing_Invalid) return false; - convert_to_typed(c, &w, y.type, 0); if (w.mode == Addressing_Invalid) return false; - convert_to_typed(c, &w, z.type, 0); if (w.mode == Addressing_Invalid) return false; +#define _QUAT_CTT(x, y, z, w) do { \ + convert_to_typed(c, &(x), (y).type, 0); if ((x).mode == Addressing_Invalid) return false; \ + convert_to_typed(c, &(x), (z).type, 0); if ((x).mode == Addressing_Invalid) return false; \ + convert_to_typed(c, &(x), (w).type, 0); if ((x).mode == Addressing_Invalid) return false; \ + } while (0) + _QUAT_CTT(x, y, z, w); + _QUAT_CTT(y, z, w, x); + _QUAT_CTT(z, w, x, y); + _QUAT_CTT(w, x, y, z); +#undef _QUAT_CTT if (x.mode == Addressing_Constant && y.mode == Addressing_Constant && z.mode == Addressing_Constant && w.mode == Addressing_Constant) { - if (is_type_numeric(x.type) && - exact_value_imag(x.value).value_float == 0 && - exact_value_jmag(x.value).value_float == 0 && - exact_value_kmag(x.value).value_float == 0) { - x.type = t_untyped_float; - } - if (is_type_numeric(y.type) && - exact_value_imag(y.value).value_float == 0 && - exact_value_jmag(y.value).value_float == 0 && - exact_value_kmag(y.value).value_float == 0) { - y.type = t_untyped_float; - } - if (is_type_numeric(z.type) && - exact_value_imag(z.value).value_float == 0 && - exact_value_jmag(z.value).value_float == 0 && - exact_value_kmag(z.value).value_float == 0) { - z.type = t_untyped_float; - } - if (is_type_numeric(w.type) && - exact_value_imag(w.value).value_float == 0 && - exact_value_jmag(w.value).value_float == 0 && - exact_value_kmag(w.value).value_float == 0) { - w.type = t_untyped_float; - } +#define _QUAT_EXACT_VAL(x) do { \ + if (is_type_numeric((x).type) && \ + exact_value_imag((x).value).value_float == 0 && \ + exact_value_jmag((x).value).value_float == 0 && \ + exact_value_kmag((x).value).value_float == 0) { \ + (x).type = t_untyped_float; \ + } \ + } while (0) + _QUAT_EXACT_VAL(x); + _QUAT_EXACT_VAL(y); + _QUAT_EXACT_VAL(z); + _QUAT_EXACT_VAL(w); +#undef _QUAT_EXACT_VAL } if (!are_types_identical(x.type, y.type)) { diff --git a/src/check_stmt.c b/src/check_stmt.c index 2d25e88a9..619431907 100644 --- a/src/check_stmt.c +++ b/src/check_stmt.c @@ -918,6 +918,14 @@ void check_stmt_internal(Checker *c, AstNode *node, u32 flags) { } } + if (x.mode != Addressing_Constant) { + x.value = (ExactValue){0}; + } + if (y.mode != Addressing_Constant) { + y.value = (ExactValue){0}; + } + + add_type_and_value(&c->info, ie->left, x.mode, x.type, x.value); add_type_and_value(&c->info, ie->right, y.mode, y.type, y.value); val = type; diff --git a/src/ir.c b/src/ir.c index 54d193b2f..ab1321bb4 100644 --- a/src/ir.c +++ b/src/ir.c @@ -673,8 +673,11 @@ bool ir_is_instr_terminating(irInstr *i) { void ir_add_edge(irBlock *from, irBlock *to) { - array_add(&from->succs, to); - array_add(&to->preds, from); + GB_ASSERT(from->instrs.count > 0); + if (!ir_is_instr_terminating(ir_get_last_instr(from))) { + array_add(&from->succs, to); + array_add(&to->preds, from); + } } void ir_set_instr_parent(irValue *instr, irBlock *parent) { @@ -1812,14 +1815,15 @@ irValue *ir_emit_unary_arith(irProcedure *proc, TokenKind op, irValue *x, Type * return ir_emit(proc, ir_instr_unary_op(proc, op, x, type)); } + + irValue *ir_emit_arith(irProcedure *proc, TokenKind op, irValue *left, irValue *right, Type *type) { Type *t_left = ir_type(left); Type *t_right = ir_type(right); - if (is_type_vector(t_left)) { + if (is_type_vector(t_left) || is_type_vector(t_right)) { ir_emit_comment(proc, str_lit("vector.arith.begin")); // IMPORTANT TODO(bill): This is very wasteful with regards to stack memory - Type *tl = base_type(t_left); left = ir_emit_conv(proc, left, type); right = ir_emit_conv(proc, right, type); irValue *lhs = ir_address_from_load_or_generate_local(proc, left); @@ -1828,7 +1832,8 @@ irValue *ir_emit_arith(irProcedure *proc, TokenKind op, irValue *left, irValue * Type *elem_type = base_type(type)->Vector.elem; irValue *res = ir_add_local_generated(proc, type); - for (i32 i = 0; i < tl->Vector.count; i++) { + i64 count = base_type(type)->Vector.count; + for (i32 i = 0; i < count; i++) { irValue *x = ir_emit_load(proc, ir_emit_array_epi(proc, lhs, i)); irValue *y = ir_emit_load(proc, ir_emit_array_epi(proc, rhs, i)); irValue *z = ir_emit_arith(proc, op, x, y, elem_type); @@ -5640,7 +5645,6 @@ void ir_build_range_string(irProcedure *proc, irValue *expr, Type *val_type, done = ir_new_block(proc, NULL, "for.string.done"); irValue *offset = ir_emit_load(proc, offset_); - irValue *cond = ir_emit_comp(proc, Token_Lt, offset, count); ir_emit_if(proc, cond, body, done); ir_start_block(proc, body); @@ -5696,7 +5700,6 @@ void ir_build_range_interval(irProcedure *proc, AstNodeBinaryExpr *node, Type *v body = ir_new_block(proc, NULL, "for.interval.body"); done = ir_new_block(proc, NULL, "for.interval.done"); - upper = ir_build_expr(proc, node->right); TokenKind op = Token_Lt; switch (node->op.kind) { @@ -5704,6 +5707,9 @@ void ir_build_range_interval(irProcedure *proc, AstNodeBinaryExpr *node, Type *v case Token_HalfClosed: op = Token_Lt; break; default: GB_PANIC("Invalid interval operator"); break; } + + upper = ir_build_expr(proc, node->right); + irValue *cond = ir_emit_comp(proc, op, ir_emit_load(proc, value), upper); ir_emit_if(proc, cond, body, done); ir_start_block(proc, body); @@ -6222,7 +6228,6 @@ void ir_build_stmt_internal(irProcedure *proc, AstNode *node) { GB_PANIC("TODO(bill): enum core type %s", type_to_string(core_elem)); } } - } else { Type *expr_type = type_of_expr(proc->module->info, rs->expr); Type *et = base_type(type_deref(expr_type)); diff --git a/src/ir_print.c b/src/ir_print.c index 237d50773..3d7b2e9d6 100644 --- a/src/ir_print.c +++ b/src/ir_print.c @@ -1060,7 +1060,7 @@ void ir_print_instr(irFileBuffer *f, irModule *m, irValue *value) { irInstrBinaryOp *bo = &value->Instr.BinaryOp; Type *type = base_type(ir_type(bo->left)); Type *elem_type = type; - GB_ASSERT(!is_type_vector(elem_type)); + GB_ASSERT_MSG(!is_type_vector(elem_type), type_to_string(elem_type)); ir_fprintf(f, "%%%d = ", value->index);