Remove scalar*vector; swizzle; broadcast

This commit is contained in:
gingerBill
2016-08-17 18:36:37 +01:00
parent c4fe2ace05
commit 6f9d11b381
10 changed files with 284 additions and 877 deletions
+5
View File
@@ -123,6 +123,7 @@ enum BuiltinProcId {
BuiltinProc_cap,
BuiltinProc_copy,
BuiltinProc_append,
BuiltinProc_swizzle,
BuiltinProc_print,
BuiltinProc_println,
@@ -149,8 +150,12 @@ gb_global BuiltinProc builtin_procs[BuiltinProc_Count] = {
{STR_LIT("cap"), 1, false, Expression_Expression},
{STR_LIT("copy"), 2, false, Expression_Expression},
{STR_LIT("append"), 2, false, Expression_Expression},
{STR_LIT("swizzle"), 1, true, Expression_Expression},
{STR_LIT("print"), 1, true, Expression_Statement},
{STR_LIT("println"), 1, true, Expression_Statement},
};
struct CheckerContext {
+65 -6
View File
@@ -409,10 +409,7 @@ Type *check_type(Checker *c, AstNode *e, Type *named_type) {
case_ast_node(pt, ProcType, e);
type = alloc_type(c->allocator, Type_Proc);
set_base_type(named_type, type);
CheckerContext context = c->context;
c->context.scope = make_scope(c->context.scope, c->allocator);
check_procedure_type(c, type, e);
c->context = context;
goto end;
case_end;
@@ -979,7 +976,10 @@ void check_binary_expr(Checker *c, Operand *x, AstNode *node) {
return;
}
if (token_is_shift(be->op)) {
Token op = be->op;
if (token_is_shift(op)) {
check_shift(c, x, y, node);
return;
}
@@ -992,7 +992,6 @@ void check_binary_expr(Checker *c, Operand *x, AstNode *node) {
return;
}
Token op = be->op;
if (token_is_comparison(op)) {
check_comparison(c, x, y, op);
return;
@@ -1616,6 +1615,54 @@ b32 check_builtin_procedure(Checker *c, Operand *operand, AstNode *call, i32 id)
operand->mode = Addressing_Value;
} break;
case BuiltinProc_swizzle: {
// swizzle :: proc(v: {N}T, T...) -> {M}T
Type *vector_type = get_base_type(operand->type);
if (!is_type_vector(vector_type)) {
gbString type_str = type_to_string(operand->type);
defer (gb_string_free(type_str));
error(&c->error_collector, ast_node_token(call),
"You can only `swizzle` a vector, got `%s`",
type_str);
return false;
}
isize max_count = vector_type->vector.count;
isize arg_count = 0;
for (AstNode *arg = ce->arg_list->next; arg != NULL; arg = arg->next) {
Operand op = {};
check_expr(c, &op, arg);
if (op.mode == Addressing_Invalid)
return false;
Type *arg_type = get_base_type(op.type);
if (!is_type_integer(arg_type) || op.mode != Addressing_Constant) {
error(&c->error_collector, ast_node_token(op.expr), "Indices to `swizzle` must be constant integers");
return false;
}
if (op.value.value_integer < 0) {
error(&c->error_collector, ast_node_token(op.expr), "Negative `swizzle` index");
return false;
}
if (max_count <= op.value.value_integer) {
error(&c->error_collector, ast_node_token(op.expr), "`swizzle` index exceeds vector length");
return false;
}
arg_count++;
}
if (arg_count > max_count) {
error(&c->error_collector, ast_node_token(call), "Too many `swizzle` indices, %td > %td", arg_count, max_count);
return false;
}
Type *elem_type = vector_type->vector.elem;
operand->type = make_type_vector(c->allocator, elem_type, arg_count);
operand->mode = Addressing_Value;
}
case BuiltinProc_print:
case BuiltinProc_println: {
for (AstNode *arg = ce->arg_list; arg != NULL; arg = arg->next) {
@@ -1958,7 +2005,12 @@ ExpressionKind check__expr_base(Checker *c, Operand *o, AstNode *node, Type *typ
if (t->kind == Type_Array &&
t->array.count >= 0 &&
index >= t->array.count) {
error(&c->error_collector, ast_node_token(elem), "Index %lld is out of bounds (>= %lld)", index, t->array.count);
error(&c->error_collector, ast_node_token(elem), "Index %lld is out of bounds (>= %lld) for array literal", index, t->array.count);
}
if (t->kind == Type_Vector &&
t->vector.count >= 0 &&
index >= t->vector.count) {
error(&c->error_collector, ast_node_token(elem), "Index %lld is out of bounds (>= %lld) for vector literal", index, t->vector.count);
}
Operand o = {};
@@ -1968,6 +2020,13 @@ ExpressionKind check__expr_base(Checker *c, Operand *o, AstNode *node, Type *typ
if (max < index)
max = index;
if (t->kind == Type_Vector) {
if (t->vector.count > 1 && gb_is_between(index, 2, t->vector.count-1)) {
error(&c->error_collector, ast_node_token(cl->elem_list),
"Expected either 1 (broadcast) or %td elements in vector literal, got %td", t->vector.count, index);
}
}
if (t->kind == Type_Array && ellipsis_array) {
t->array.count = max;
}
-15
View File
@@ -369,18 +369,6 @@ void check_type_decl(Checker *c, Entity *e, AstNode *type_expr, Type *named_type
set_base_type(named, get_base_type(get_base_type(named)));
}
void check_alias_decl(Checker *c, Entity *e, AstNode *type_expr, Type *alias_type) {
GB_ASSERT(e->type == NULL);
Type *named = make_type_alias(c->allocator, e->token.string, NULL, e);
named->alias.alias_name = e;
set_base_type(alias_type, named);
e->type = named;
check_type(c, type_expr, named);
set_base_type(named, get_base_type(get_base_type(named)));
}
void check_proc_body(Checker *c, Token token, DeclInfo *decl, Type *type, AstNode *body) {
GB_ASSERT(body->kind == AstNode_BlockStmt);
@@ -496,9 +484,6 @@ void check_entity_decl(Checker *c, Entity *e, DeclInfo *d, Type *named_type) {
case Entity_TypeName:
check_type_decl(c, e, d->type_expr, named_type);
break;
case Entity_AliasName:
check_alias_decl(c, e, d->type_expr, named_type);
break;
case Entity_Procedure:
check_proc_decl(c, e, d, true);
break;
+2 -36
View File
@@ -64,7 +64,6 @@ struct BasicType {
TYPE_KIND(Structure), \
TYPE_KIND(Pointer), \
TYPE_KIND(Named), \
TYPE_KIND(Alias), \
TYPE_KIND(Tuple), \
TYPE_KIND(Proc), \
TYPE_KIND(Count),
@@ -110,11 +109,6 @@ struct Type {
Type * base;
Entity *type_name; // Entity_TypeName
} named;
struct {
String name;
Type * base;
Entity *alias_name; // Entity_AliasName
} alias;
struct {
Entity **variables; // Entity_Variable
isize variable_count;
@@ -130,12 +124,8 @@ struct Type {
};
Type *get_base_type(Type *t) {
while (t->kind == Type_Named || t->kind == Type_Alias) {
if (t->kind == Type_Named) {
t = t->named.base;
} else {
t = t->alias.base;
}
while (t->kind == Type_Named) {
t = t->named.base;
}
return t;
}
@@ -143,8 +133,6 @@ Type *get_base_type(Type *t) {
void set_base_type(Type *t, Type *base) {
if (t && t->kind == Type_Named) {
t->named.base = base;
} else if (t && t->kind == Type_Alias) {
t->alias.base = base;
}
}
@@ -201,14 +189,6 @@ Type *make_type_named(gbAllocator a, String name, Type *base, Entity *type_name)
return t;
}
Type *make_type_alias(gbAllocator a, String name, Type *base, Entity *alias_name) {
Type *t = alloc_type(a, Type_Alias);
t->alias.name = name;
t->alias.base = base;
t->alias.alias_name = alias_name;
return t;
}
Type *make_type_tuple(gbAllocator a) {
Type *t = alloc_type(a, Type_Tuple);
return t;
@@ -465,16 +445,11 @@ b32 are_types_identical(Type *x, Type *y) {
return are_types_identical(x->pointer.elem, y->pointer.elem);
break;
case Type_Alias:
return are_types_identical(get_base_type(x), y);
case Type_Named:
if (y->kind == Type_Named)
return x->named.base == y->named.base;
break;
case Type_Tuple:
if (y->kind == Type_Tuple) {
if (x->tuple.variable_count == y->tuple.variable_count) {
@@ -737,15 +712,6 @@ gbString write_type_to_string(gbString str, Type *type) {
}
break;
case Type_Alias:
if (type->alias.alias_name != NULL) {
str = gb_string_append_length(str, type->alias.name.text, type->alias.name.len);
} else {
// NOTE(bill): Just in case
str = gb_string_appendc(str, "<alias type>");
}
break;
case Type_Tuple:
if (type->tuple.variable_count > 0) {
for (isize i = 0; i < type->tuple.variable_count; i++) {