mirror of
https://github.com/Ed94/Odin.git
synced 2026-08-06 15:48:51 +00:00
*_of as keyords; Allow constant aliasing for user/built-in procedures, import names, and library names
This commit is contained in:
+6
-4
@@ -1,6 +1,5 @@
|
|||||||
import (
|
import (
|
||||||
"fmt.odin";
|
"fmt.odin";
|
||||||
/*
|
|
||||||
"atomics.odin";
|
"atomics.odin";
|
||||||
"bits.odin";
|
"bits.odin";
|
||||||
"decimal.odin";
|
"decimal.odin";
|
||||||
@@ -16,6 +15,7 @@ import (
|
|||||||
"types.odin";
|
"types.odin";
|
||||||
"utf8.odin";
|
"utf8.odin";
|
||||||
"utf16.odin";
|
"utf16.odin";
|
||||||
|
/*
|
||||||
*/
|
*/
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -370,9 +370,11 @@ main :: proc() {
|
|||||||
foo :: proc(x: type, y: f32) do fmt.println("#2", type_info(x), y);
|
foo :: proc(x: type, y: f32) do fmt.println("#2", type_info(x), y);
|
||||||
foo :: proc(x: type) do fmt.println("#3", type_info(x));
|
foo :: proc(x: type) do fmt.println("#3", type_info(x));
|
||||||
|
|
||||||
foo(y = 3785.1546, x = 123);
|
f :: foo;
|
||||||
foo(x = int, y = 897.513);
|
|
||||||
foo(x = f32);
|
f(y = 3785.1546, x = 123);
|
||||||
|
f(x = int, y = 897.513);
|
||||||
|
f(x = f32);
|
||||||
/*
|
/*
|
||||||
general_stuff();
|
general_stuff();
|
||||||
foreign_blocks();
|
foreign_blocks();
|
||||||
|
|||||||
+14
-2
@@ -504,8 +504,20 @@ __mem_compare :: proc(a, b: ^u8, n: int) -> int #cc_contextless {
|
|||||||
}
|
}
|
||||||
|
|
||||||
foreign __llvm_core {
|
foreign __llvm_core {
|
||||||
__sqrt_f32 :: proc(x: f32) -> f32 #link_name "llvm.sqrt.f32" ---;
|
__sqrt_f32 :: proc(x: f32) -> f32 #link_name "llvm.sqrt.f32" ---;
|
||||||
__sqrt_f64 :: proc(x: f64) -> f64 #link_name "llvm.sqrt.f64" ---;
|
__sqrt_f64 :: proc(x: f64) -> f64 #link_name "llvm.sqrt.f64" ---;
|
||||||
|
|
||||||
|
__sin_f32 :: proc(θ: f32) -> f32 #link_name "llvm.sin.f32" ---;
|
||||||
|
__sin_f64 :: proc(θ: f64) -> f64 #link_name "llvm.sin.f64" ---;
|
||||||
|
|
||||||
|
__cos_f32 :: proc(θ: f32) -> f32 #link_name "llvm.cos.f32" ---;
|
||||||
|
__cos_f64 :: proc(θ: f64) -> f64 #link_name "llvm.cos.f64" ---;
|
||||||
|
|
||||||
|
__pow_f32 :: proc(x, power: f32) -> f32 #link_name "llvm.pow.f32" ---;
|
||||||
|
__pow_f64 :: proc(x, power: f64) -> f64 #link_name "llvm.pow.f64" ---;
|
||||||
|
|
||||||
|
fmuladd32 :: proc(a, b, c: f32) -> f32 #link_name "llvm.fmuladd.f32" ---;
|
||||||
|
fmuladd64 :: proc(a, b, c: f64) -> f64 #link_name "llvm.fmuladd.f64" ---;
|
||||||
}
|
}
|
||||||
__abs_complex64 :: proc(x: complex64) -> f32 #inline #cc_contextless {
|
__abs_complex64 :: proc(x: complex64) -> f32 #inline #cc_contextless {
|
||||||
r, i := real(x), imag(x);
|
r, i := real(x), imag(x);
|
||||||
|
|||||||
+67
-12
@@ -191,25 +191,80 @@ void check_const_decl(Checker *c, Entity *e, AstNode *type_expr, AstNode *init,
|
|||||||
}
|
}
|
||||||
|
|
||||||
Operand operand = {};
|
Operand operand = {};
|
||||||
if (init != NULL) {
|
|
||||||
check_expr_or_type(c, &operand, init);
|
|
||||||
}
|
|
||||||
#if 1
|
|
||||||
if (operand.mode == Addressing_Type) {
|
|
||||||
e->kind = Entity_TypeName;
|
|
||||||
|
|
||||||
DeclInfo *d = c->context.decl;
|
if (init != NULL) {
|
||||||
d->type_expr = d->init_expr;
|
Entity *entity = NULL;
|
||||||
check_type_decl(c, e, d->type_expr, named_type);
|
if (init->kind == AstNode_Ident) {
|
||||||
return;
|
entity = check_ident(c, &operand, init, NULL, e->type, true);
|
||||||
|
} else if (init->kind == AstNode_SelectorExpr) {
|
||||||
|
entity = check_selector(c, &operand, init, e->type);
|
||||||
|
} else {
|
||||||
|
check_expr_or_type(c, &operand, init, e->type);
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (operand.mode) {
|
||||||
|
case Addressing_Type: {
|
||||||
|
e->kind = Entity_TypeName;
|
||||||
|
|
||||||
|
DeclInfo *d = c->context.decl;
|
||||||
|
d->type_expr = d->init_expr;
|
||||||
|
check_type_decl(c, e, d->type_expr, named_type);
|
||||||
|
return;
|
||||||
|
} break;
|
||||||
|
|
||||||
|
case Addressing_Builtin:
|
||||||
|
if (e->type != NULL) {
|
||||||
|
error(type_expr, "A constant alias of a built-in procedure may not have a type initializer");
|
||||||
|
}
|
||||||
|
e->kind = Entity_Builtin;
|
||||||
|
e->Builtin.id = operand.builtin_id;
|
||||||
|
e->type = t_invalid;
|
||||||
|
return;
|
||||||
|
|
||||||
|
case Addressing_Overload:
|
||||||
|
e->kind = Entity_Alias;
|
||||||
|
e->Alias.base = operand.overload_entities[0];
|
||||||
|
e->type = t_invalid;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (entity != NULL) {
|
||||||
|
switch (entity->kind) {
|
||||||
|
case Entity_Procedure:
|
||||||
|
e->kind = Entity_Alias;
|
||||||
|
e->type = entity->type;
|
||||||
|
e->Alias.base = entity;
|
||||||
|
return;
|
||||||
|
case Entity_ImportName:
|
||||||
|
e->kind = Entity_ImportName;
|
||||||
|
e->type = entity->type;
|
||||||
|
e->ImportName.path = entity->ImportName.path;
|
||||||
|
e->ImportName.name = entity->ImportName.path;
|
||||||
|
e->ImportName.scope = entity->ImportName.scope;
|
||||||
|
e->ImportName.used = false;
|
||||||
|
return;
|
||||||
|
case Entity_LibraryName:
|
||||||
|
e->kind = Entity_LibraryName;
|
||||||
|
e->type = entity->type;
|
||||||
|
e->LibraryName.path = entity->LibraryName.path;
|
||||||
|
e->LibraryName.name = entity->LibraryName.path;
|
||||||
|
e->LibraryName.used = false;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (init != NULL) {
|
||||||
|
check_expr_or_type(c, &operand, init, e->type);
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
check_init_constant(c, e, &operand);
|
check_init_constant(c, e, &operand);
|
||||||
|
|
||||||
if (operand.mode == Addressing_Invalid ||
|
if (operand.mode == Addressing_Invalid ||
|
||||||
base_type(operand.type) == t_invalid) {
|
base_type(operand.type) == t_invalid) {
|
||||||
error(e->token, "Invalid declaration type");
|
gbString str = expr_to_string(init);
|
||||||
|
error(e->token, "Invalid declaration type `%s`", str);
|
||||||
|
gb_string_free(str);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+44
-8
@@ -33,7 +33,7 @@ typedef CALL_ARGUMENT_CHECKER(CallArgumentCheckerType);
|
|||||||
|
|
||||||
void check_expr (Checker *c, Operand *operand, AstNode *expression);
|
void check_expr (Checker *c, Operand *operand, AstNode *expression);
|
||||||
void check_multi_expr (Checker *c, Operand *operand, AstNode *expression);
|
void check_multi_expr (Checker *c, Operand *operand, AstNode *expression);
|
||||||
void check_expr_or_type (Checker *c, Operand *operand, AstNode *expression);
|
void check_expr_or_type (Checker *c, Operand *operand, AstNode *expression, Type *type_hint = NULL);
|
||||||
ExprKind check_expr_base (Checker *c, Operand *operand, AstNode *expression, Type *type_hint);
|
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);
|
void check_expr_with_type_hint (Checker *c, Operand *o, AstNode *e, Type *t);
|
||||||
Type * check_type (Checker *c, AstNode *expression, Type *named_type = NULL);
|
Type * check_type (Checker *c, AstNode *expression, Type *named_type = NULL);
|
||||||
@@ -1260,7 +1260,7 @@ Type *check_get_params(Checker *c, Scope *scope, AstNode *_params, bool *is_vari
|
|||||||
success = false;
|
success = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (type_expr->kind == AstNode_HelperType) {
|
if (type_expr->kind == AstNode_TypeType) {
|
||||||
is_type_param = true;
|
is_type_param = true;
|
||||||
if (operands != NULL) {
|
if (operands != NULL) {
|
||||||
detemine_type_from_operand = true;
|
detemine_type_from_operand = true;
|
||||||
@@ -1283,7 +1283,7 @@ Type *check_get_params(Checker *c, Scope *scope, AstNode *_params, bool *is_vari
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (default_value != NULL) {
|
if (default_value != NULL) {
|
||||||
if (type_expr->kind == AstNode_HelperType) {
|
if (type_expr->kind == AstNode_TypeType) {
|
||||||
error(default_value, "A type parameter may not have a default value");
|
error(default_value, "A type parameter may not have a default value");
|
||||||
} else {
|
} else {
|
||||||
Operand o = {};
|
Operand o = {};
|
||||||
@@ -1817,7 +1817,16 @@ Entity *check_ident(Checker *c, Operand *o, AstNode *n, Type *named_type, Type *
|
|||||||
|
|
||||||
bool is_overloaded = false;
|
bool is_overloaded = false;
|
||||||
isize overload_count = 0;
|
isize overload_count = 0;
|
||||||
HashKey key = hash_string(name);
|
|
||||||
|
bool is_alias = false;
|
||||||
|
while (e->kind == Entity_Alias) {
|
||||||
|
GB_ASSERT(e->Alias.base != NULL);
|
||||||
|
e = e->Alias.base;
|
||||||
|
is_alias = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
HashKey key = hash_string(e->token.string);
|
||||||
|
|
||||||
|
|
||||||
if (e->kind == Entity_Procedure) {
|
if (e->kind == Entity_Procedure) {
|
||||||
// NOTE(bill): Overloads are only allowed with the same scope
|
// NOTE(bill): Overloads are only allowed with the same scope
|
||||||
@@ -2135,6 +2144,10 @@ bool check_type_internal(Checker *c, AstNode *e, Type **type, Type *named_type)
|
|||||||
}
|
}
|
||||||
case_end;
|
case_end;
|
||||||
|
|
||||||
|
case_ast_node(ht, HelperType, e);
|
||||||
|
return check_type_internal(c, ht->type, type, named_type);
|
||||||
|
case_end;
|
||||||
|
|
||||||
case_ast_node(pt, PolyType, e);
|
case_ast_node(pt, PolyType, e);
|
||||||
AstNode *ident = pt->type;
|
AstNode *ident = pt->type;
|
||||||
if (ident->kind != AstNode_Ident) {
|
if (ident->kind != AstNode_Ident) {
|
||||||
@@ -6047,6 +6060,24 @@ ExprKind check_expr_base_internal(Checker *c, Operand *o, AstNode *node, Type *t
|
|||||||
o->mode = Addressing_Value;
|
o->mode = Addressing_Value;
|
||||||
o->type = t_context;
|
o->type = t_context;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case Token_size_of:
|
||||||
|
o->mode = Addressing_Builtin;
|
||||||
|
o->builtin_id = BuiltinProc_size_of;
|
||||||
|
break;
|
||||||
|
case Token_align_of:
|
||||||
|
o->mode = Addressing_Builtin;
|
||||||
|
o->builtin_id = BuiltinProc_align_of;
|
||||||
|
break;
|
||||||
|
case Token_offset_of:
|
||||||
|
o->mode = Addressing_Builtin;
|
||||||
|
o->builtin_id = BuiltinProc_offset_of;
|
||||||
|
break;
|
||||||
|
case Token_type_of:
|
||||||
|
o->mode = Addressing_Builtin;
|
||||||
|
o->builtin_id = BuiltinProc_type_of;
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
error(node, "Illegal implicit name `%.*s`", LIT(i->string));
|
error(node, "Illegal implicit name `%.*s`", LIT(i->string));
|
||||||
return kind;
|
return kind;
|
||||||
@@ -6916,7 +6947,7 @@ ExprKind check_expr_base_internal(Checker *c, Operand *o, AstNode *node, Type *t
|
|||||||
}
|
}
|
||||||
case_end;
|
case_end;
|
||||||
|
|
||||||
case AstNode_HelperType:
|
case AstNode_TypeType:
|
||||||
case AstNode_ProcType:
|
case AstNode_ProcType:
|
||||||
case AstNode_PointerType:
|
case AstNode_PointerType:
|
||||||
case AstNode_ArrayType:
|
case AstNode_ArrayType:
|
||||||
@@ -7001,8 +7032,8 @@ void check_expr(Checker *c, Operand *o, AstNode *e) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void check_expr_or_type(Checker *c, Operand *o, AstNode *e) {
|
void check_expr_or_type(Checker *c, Operand *o, AstNode *e, Type *type_hint) {
|
||||||
check_expr_base(c, o, e, NULL);
|
check_expr_base(c, o, e, type_hint);
|
||||||
check_not_tuple(c, o);
|
check_not_tuple(c, o);
|
||||||
error_operand_no_value(o);
|
error_operand_no_value(o);
|
||||||
}
|
}
|
||||||
@@ -7148,6 +7179,11 @@ gbString write_expr_to_string(gbString str, AstNode *node) {
|
|||||||
str = write_expr_to_string(str, fv->value);
|
str = write_expr_to_string(str, fv->value);
|
||||||
case_end;
|
case_end;
|
||||||
|
|
||||||
|
case_ast_node(ht, HelperType, node);
|
||||||
|
str = gb_string_appendc(str, "#type ");
|
||||||
|
str = write_expr_to_string(str, ht->type);
|
||||||
|
case_end;
|
||||||
|
|
||||||
case_ast_node(pt, PointerType, node);
|
case_ast_node(pt, PointerType, node);
|
||||||
str = gb_string_appendc(str, "^");
|
str = gb_string_appendc(str, "^");
|
||||||
str = write_expr_to_string(str, pt->type);
|
str = write_expr_to_string(str, pt->type);
|
||||||
@@ -7271,7 +7307,7 @@ gbString write_expr_to_string(gbString str, AstNode *node) {
|
|||||||
str = gb_string_appendc(str, ")");
|
str = gb_string_appendc(str, ")");
|
||||||
case_end;
|
case_end;
|
||||||
|
|
||||||
case_ast_node(ht, HelperType, node);
|
case_ast_node(ht, TypeType, node);
|
||||||
str = gb_string_appendc(str, "type");
|
str = gb_string_appendc(str, "type");
|
||||||
case_end;
|
case_end;
|
||||||
|
|
||||||
|
|||||||
@@ -61,6 +61,12 @@ enum BuiltinProcId {
|
|||||||
BuiltinProc_abs,
|
BuiltinProc_abs,
|
||||||
BuiltinProc_clamp,
|
BuiltinProc_clamp,
|
||||||
|
|
||||||
|
/* BuiltinProc_sqrt,
|
||||||
|
BuiltinProc_sin,
|
||||||
|
BuiltinProc_cos,
|
||||||
|
BuiltinProc_tan,
|
||||||
|
BuiltinProc_pow, */
|
||||||
|
|
||||||
BuiltinProc_transmute,
|
BuiltinProc_transmute,
|
||||||
|
|
||||||
BuiltinProc_DIRECTIVE, // NOTE(bill): This is used for specialized hash-prefixed procedures
|
BuiltinProc_DIRECTIVE, // NOTE(bill): This is used for specialized hash-prefixed procedures
|
||||||
@@ -107,6 +113,14 @@ gb_global BuiltinProc builtin_procs[BuiltinProc_COUNT] = {
|
|||||||
{STR_LIT("abs"), 1, false, Expr_Expr},
|
{STR_LIT("abs"), 1, false, Expr_Expr},
|
||||||
{STR_LIT("clamp"), 3, false, Expr_Expr},
|
{STR_LIT("clamp"), 3, false, Expr_Expr},
|
||||||
|
|
||||||
|
/*
|
||||||
|
{STR_LIT("__sqrt"), 1, false, Expr_Expr},
|
||||||
|
{STR_LIT("__sin"), 1, false, Expr_Expr},
|
||||||
|
{STR_LIT("__cos"), 1, false, Expr_Expr},
|
||||||
|
{STR_LIT("__tan"), 1, false, Expr_Expr},
|
||||||
|
{STR_LIT("__pow"), 2, false, Expr_Expr},
|
||||||
|
*/
|
||||||
|
|
||||||
{STR_LIT("transmute"), 2, false, Expr_Expr},
|
{STR_LIT("transmute"), 2, false, Expr_Expr},
|
||||||
|
|
||||||
{STR_LIT(""), 0, true, Expr_Expr}, // DIRECTIVE
|
{STR_LIT(""), 0, true, Expr_Expr}, // DIRECTIVE
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ struct DeclInfo;
|
|||||||
ENTITY_KIND(TypeName) \
|
ENTITY_KIND(TypeName) \
|
||||||
ENTITY_KIND(Procedure) \
|
ENTITY_KIND(Procedure) \
|
||||||
ENTITY_KIND(Builtin) \
|
ENTITY_KIND(Builtin) \
|
||||||
|
ENTITY_KIND(Alias) \
|
||||||
ENTITY_KIND(ImportName) \
|
ENTITY_KIND(ImportName) \
|
||||||
ENTITY_KIND(LibraryName) \
|
ENTITY_KIND(LibraryName) \
|
||||||
ENTITY_KIND(Nil) \
|
ENTITY_KIND(Nil) \
|
||||||
@@ -108,6 +109,9 @@ struct Entity {
|
|||||||
struct {
|
struct {
|
||||||
i32 id;
|
i32 id;
|
||||||
} Builtin;
|
} Builtin;
|
||||||
|
struct {
|
||||||
|
Entity *base;
|
||||||
|
} Alias;
|
||||||
struct {
|
struct {
|
||||||
String path;
|
String path;
|
||||||
String name;
|
String name;
|
||||||
@@ -232,6 +236,12 @@ Entity *make_entity_builtin(gbAllocator a, Scope *scope, Token token, Type *type
|
|||||||
return entity;
|
return entity;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Entity *make_entity_alias(gbAllocator a, Scope *scope, Token token, Type *type, Entity *base) {
|
||||||
|
Entity *entity = alloc_entity(a, Entity_Alias, scope, token, type);
|
||||||
|
entity->Alias.base = base;
|
||||||
|
return entity;
|
||||||
|
}
|
||||||
|
|
||||||
Entity *make_entity_import_name(gbAllocator a, Scope *scope, Token token, Type *type,
|
Entity *make_entity_import_name(gbAllocator a, Scope *scope, Token token, Type *type,
|
||||||
String path, String name, Scope *import_scope) {
|
String path, String name, Scope *import_scope) {
|
||||||
Entity *entity = alloc_entity(a, Entity_ImportName, scope, token, type);
|
Entity *entity = alloc_entity(a, Entity_ImportName, scope, token, type);
|
||||||
|
|||||||
@@ -5639,6 +5639,13 @@ void ir_build_constant_value_decl(irProcedure *proc, AstNodeValueDecl *vd) {
|
|||||||
GB_ASSERT(ident->kind == AstNode_Ident);
|
GB_ASSERT(ident->kind == AstNode_Ident);
|
||||||
Entity *e = entity_of_ident(proc->module->info, ident);
|
Entity *e = entity_of_ident(proc->module->info, ident);
|
||||||
GB_ASSERT(e != NULL);
|
GB_ASSERT(e != NULL);
|
||||||
|
switch (e->kind) {
|
||||||
|
case Entity_TypeName:
|
||||||
|
case Entity_Procedure:
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
bool polymorphic = is_type_polymorphic(e->type);
|
bool polymorphic = is_type_polymorphic(e->type);
|
||||||
|
|
||||||
|
|||||||
+66
-23
@@ -375,9 +375,13 @@ AST_NODE_KIND(_DeclEnd, "", i32) \
|
|||||||
AstNode *list; \
|
AstNode *list; \
|
||||||
}) \
|
}) \
|
||||||
AST_NODE_KIND(_TypeBegin, "", i32) \
|
AST_NODE_KIND(_TypeBegin, "", i32) \
|
||||||
AST_NODE_KIND(HelperType, "type", struct { \
|
AST_NODE_KIND(TypeType, "type", struct { \
|
||||||
Token token; \
|
Token token; \
|
||||||
}) \
|
}) \
|
||||||
|
AST_NODE_KIND(HelperType, "helper type", struct { \
|
||||||
|
Token token; \
|
||||||
|
AstNode *type; \
|
||||||
|
}) \
|
||||||
AST_NODE_KIND(PolyType, "polymorphic type", struct { \
|
AST_NODE_KIND(PolyType, "polymorphic type", struct { \
|
||||||
Token token; \
|
Token token; \
|
||||||
AstNode *type; \
|
AstNode *type; \
|
||||||
@@ -585,6 +589,7 @@ Token ast_node_token(AstNode *node) {
|
|||||||
case AstNode_UnionField:
|
case AstNode_UnionField:
|
||||||
return ast_node_token(node->UnionField.name);
|
return ast_node_token(node->UnionField.name);
|
||||||
|
|
||||||
|
case AstNode_TypeType: return node->TypeType.token;
|
||||||
case AstNode_HelperType: return node->HelperType.token;
|
case AstNode_HelperType: return node->HelperType.token;
|
||||||
case AstNode_PolyType: return node->PolyType.token;
|
case AstNode_PolyType: return node->PolyType.token;
|
||||||
case AstNode_ProcType: return node->ProcType.token;
|
case AstNode_ProcType: return node->ProcType.token;
|
||||||
@@ -829,7 +834,10 @@ AstNode *clone_ast_node(gbAllocator a, AstNode *node) {
|
|||||||
n->UnionField.list = clone_ast_node(a, n->UnionField.list);
|
n->UnionField.list = clone_ast_node(a, n->UnionField.list);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case AstNode_TypeType:
|
||||||
|
break;
|
||||||
case AstNode_HelperType:
|
case AstNode_HelperType:
|
||||||
|
n->HelperType.type = clone_ast_node(a, n->HelperType.type);
|
||||||
break;
|
break;
|
||||||
case AstNode_ProcType:
|
case AstNode_ProcType:
|
||||||
n->ProcType.params = clone_ast_node(a, n->ProcType.params);
|
n->ProcType.params = clone_ast_node(a, n->ProcType.params);
|
||||||
@@ -1367,12 +1375,20 @@ AstNode *ast_union_field(AstFile *f, AstNode *name, AstNode *list) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
AstNode *ast_helper_type(AstFile *f, Token token) {
|
AstNode *ast_type_type(AstFile *f, Token token) {
|
||||||
AstNode *result = make_ast_node(f, AstNode_HelperType);
|
AstNode *result = make_ast_node(f, AstNode_TypeType);
|
||||||
result->HelperType.token = token;
|
result->TypeType.token = token;
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
AstNode *ast_helper_type(AstFile *f, Token token, AstNode *type) {
|
||||||
|
AstNode *result = make_ast_node(f, AstNode_HelperType);
|
||||||
|
result->HelperType.token = token;
|
||||||
|
result->HelperType.type = type;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
AstNode *ast_poly_type(AstFile *f, Token token, AstNode *type) {
|
AstNode *ast_poly_type(AstFile *f, Token token, AstNode *type) {
|
||||||
AstNode *result = make_ast_node(f, AstNode_PolyType);
|
AstNode *result = make_ast_node(f, AstNode_PolyType);
|
||||||
result->PolyType.token = token;
|
result->PolyType.token = token;
|
||||||
@@ -2187,6 +2203,14 @@ AstNode *parse_operand(AstFile *f, bool lhs) {
|
|||||||
next_token(f);
|
next_token(f);
|
||||||
return operand;
|
return operand;
|
||||||
|
|
||||||
|
case Token_size_of:
|
||||||
|
case Token_align_of:
|
||||||
|
case Token_offset_of: {
|
||||||
|
operand = ast_implicit(f, f->curr_token); next_token(f);
|
||||||
|
return parse_call_expr(f, operand);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
case Token_String: {
|
case Token_String: {
|
||||||
Token token = f->curr_token;
|
Token token = f->curr_token;
|
||||||
next_token(f);
|
next_token(f);
|
||||||
@@ -2228,6 +2252,9 @@ AstNode *parse_operand(AstFile *f, bool lhs) {
|
|||||||
|
|
||||||
case Token_Hash: {
|
case Token_Hash: {
|
||||||
Token token = expect_token(f, Token_Hash);
|
Token token = expect_token(f, Token_Hash);
|
||||||
|
if (allow_token(f, Token_type)) {
|
||||||
|
return ast_helper_type(f, token, parse_type(f));
|
||||||
|
}
|
||||||
Token name = expect_token(f, Token_Ident);
|
Token name = expect_token(f, Token_Ident);
|
||||||
if (name.string == "run") {
|
if (name.string == "run") {
|
||||||
AstNode *expr = parse_expr(f, false);
|
AstNode *expr = parse_expr(f, false);
|
||||||
@@ -3162,7 +3189,7 @@ AstNode *parse_proc_type(AstFile *f, Token proc_token, String *link_name_) {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (f->type != NULL &&
|
if (f->type != NULL &&
|
||||||
f->type->kind == AstNode_HelperType) {
|
f->type->kind == AstNode_TypeType) {
|
||||||
is_generic = true;
|
is_generic = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -3186,7 +3213,7 @@ AstNode *parse_var_type(AstFile *f, bool allow_ellipsis, bool allow_type_token)
|
|||||||
AstNode *type = NULL;
|
AstNode *type = NULL;
|
||||||
if (allow_type_token &&
|
if (allow_type_token &&
|
||||||
f->curr_token.kind == Token_type) {
|
f->curr_token.kind == Token_type) {
|
||||||
type = ast_helper_type(f, expect_token(f, Token_type));
|
type = ast_type_type(f, expect_token(f, Token_type));
|
||||||
} else {
|
} else {
|
||||||
type = parse_type_attempt(f);
|
type = parse_type_attempt(f);
|
||||||
}
|
}
|
||||||
@@ -3473,8 +3500,6 @@ AstNode *parse_record_fields(AstFile *f, isize *field_count_, u32 flags, String
|
|||||||
}
|
}
|
||||||
|
|
||||||
AstNode *parse_type_or_ident(AstFile *f) {
|
AstNode *parse_type_or_ident(AstFile *f) {
|
||||||
AstNode *type = NULL;
|
|
||||||
|
|
||||||
switch (f->curr_token.kind) {
|
switch (f->curr_token.kind) {
|
||||||
case Token_Dollar: {
|
case Token_Dollar: {
|
||||||
Token token = expect_token(f, Token_Dollar);
|
Token token = expect_token(f, Token_Dollar);
|
||||||
@@ -3482,8 +3507,19 @@ AstNode *parse_type_or_ident(AstFile *f) {
|
|||||||
return ast_poly_type(f, token, type);
|
return ast_poly_type(f, token, type);
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case Token_Ident:
|
case Token_type_of: {
|
||||||
{
|
AstNode *i = ast_implicit(f, expect_token(f, Token_type_of));
|
||||||
|
AstNode *type = parse_call_expr(f, i);
|
||||||
|
while (f->curr_token.kind == Token_Period) {
|
||||||
|
Token token = f->curr_token;
|
||||||
|
next_token(f);
|
||||||
|
AstNode *sel = parse_ident(f);
|
||||||
|
type = ast_selector_expr(f, token, type, sel);
|
||||||
|
}
|
||||||
|
return type;
|
||||||
|
} break;
|
||||||
|
|
||||||
|
case Token_Ident: {
|
||||||
AstNode *e = parse_ident(f);
|
AstNode *e = parse_ident(f);
|
||||||
while (f->curr_token.kind == Token_Period) {
|
while (f->curr_token.kind == Token_Period) {
|
||||||
Token token = f->curr_token;
|
Token token = f->curr_token;
|
||||||
@@ -3496,21 +3532,28 @@ AstNode *parse_type_or_ident(AstFile *f) {
|
|||||||
// HACK NOTE(bill): For type_of_val(expr) et al.
|
// HACK NOTE(bill): For type_of_val(expr) et al.
|
||||||
// e = parse_call_expr(f, e);
|
// e = parse_call_expr(f, e);
|
||||||
// }
|
// }
|
||||||
type = e;
|
return e;
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case Token_Pointer: {
|
case Token_Pointer: {
|
||||||
Token token = expect_token(f, Token_Pointer);
|
Token token = expect_token(f, Token_Pointer);
|
||||||
AstNode *elem = parse_type(f);
|
AstNode *elem = parse_type(f);
|
||||||
type = ast_pointer_type(f, token, elem);
|
return ast_pointer_type(f, token, elem);
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case Token_atomic: {
|
case Token_atomic: {
|
||||||
Token token = expect_token(f, Token_atomic);
|
Token token = expect_token(f, Token_atomic);
|
||||||
AstNode *elem = parse_type(f);
|
AstNode *elem = parse_type(f);
|
||||||
type = ast_atomic_type(f, token, elem);
|
return ast_atomic_type(f, token, elem);
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
|
case Token_Hash: {
|
||||||
|
Token hash_token = expect_token(f, Token_Hash);
|
||||||
|
Token type_token = expect_token(f, Token_type);
|
||||||
|
AstNode *type = parse_type(f);
|
||||||
|
return ast_helper_type(f, hash_token, type);
|
||||||
|
}
|
||||||
|
|
||||||
case Token_OpenBracket: {
|
case Token_OpenBracket: {
|
||||||
Token token = expect_token(f, Token_OpenBracket);
|
Token token = expect_token(f, Token_OpenBracket);
|
||||||
AstNode *count_expr = NULL;
|
AstNode *count_expr = NULL;
|
||||||
@@ -3541,7 +3584,7 @@ AstNode *parse_type_or_ident(AstFile *f) {
|
|||||||
if (is_vector) {
|
if (is_vector) {
|
||||||
return ast_vector_type(f, token, count_expr, parse_type(f));
|
return ast_vector_type(f, token, count_expr, parse_type(f));
|
||||||
}
|
}
|
||||||
type = ast_array_type(f, token, count_expr, parse_type(f));
|
return ast_array_type(f, token, count_expr, parse_type(f));
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case Token_map: {
|
case Token_map: {
|
||||||
@@ -3559,7 +3602,7 @@ AstNode *parse_type_or_ident(AstFile *f) {
|
|||||||
Token close = expect_token(f, Token_CloseBracket);
|
Token close = expect_token(f, Token_CloseBracket);
|
||||||
value = parse_type(f);
|
value = parse_type(f);
|
||||||
|
|
||||||
type = ast_map_type(f, token, count, key, value);
|
return ast_map_type(f, token, count, key, value);
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case Token_struct: {
|
case Token_struct: {
|
||||||
@@ -3610,7 +3653,7 @@ AstNode *parse_type_or_ident(AstFile *f) {
|
|||||||
decls = fields->FieldList.list;
|
decls = fields->FieldList.list;
|
||||||
}
|
}
|
||||||
|
|
||||||
type = ast_struct_type(f, token, decls, decl_count, is_packed, is_ordered, align);
|
return ast_struct_type(f, token, decls, decl_count, is_packed, is_ordered, align);
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case Token_union: {
|
case Token_union: {
|
||||||
@@ -3664,7 +3707,7 @@ AstNode *parse_type_or_ident(AstFile *f) {
|
|||||||
Token close = expect_token(f, Token_CloseBrace);
|
Token close = expect_token(f, Token_CloseBrace);
|
||||||
|
|
||||||
|
|
||||||
type = ast_union_type(f, token, decls, total_decl_name_count, variants);
|
return ast_union_type(f, token, decls, total_decl_name_count, variants);
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case Token_raw_union: {
|
case Token_raw_union: {
|
||||||
@@ -3680,7 +3723,7 @@ AstNode *parse_type_or_ident(AstFile *f) {
|
|||||||
decls = fields->FieldList.list;
|
decls = fields->FieldList.list;
|
||||||
}
|
}
|
||||||
|
|
||||||
type = ast_raw_union_type(f, token, decls, decl_count);
|
return ast_raw_union_type(f, token, decls, decl_count);
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case Token_enum: {
|
case Token_enum: {
|
||||||
@@ -3694,7 +3737,7 @@ AstNode *parse_type_or_ident(AstFile *f) {
|
|||||||
Array<AstNode *> values = parse_element_list(f);
|
Array<AstNode *> values = parse_element_list(f);
|
||||||
Token close = expect_token(f, Token_CloseBrace);
|
Token close = expect_token(f, Token_CloseBrace);
|
||||||
|
|
||||||
type = ast_enum_type(f, token, base_type, values);
|
return ast_enum_type(f, token, base_type, values);
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case Token_bit_field: {
|
case Token_bit_field: {
|
||||||
@@ -3739,7 +3782,7 @@ AstNode *parse_type_or_ident(AstFile *f) {
|
|||||||
|
|
||||||
close = expect_token(f, Token_CloseBrace);
|
close = expect_token(f, Token_CloseBrace);
|
||||||
|
|
||||||
type = ast_bit_field_type(f, token, fields, align);
|
return ast_bit_field_type(f, token, fields, align);
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case Token_proc: {
|
case Token_proc: {
|
||||||
@@ -3748,18 +3791,18 @@ AstNode *parse_type_or_ident(AstFile *f) {
|
|||||||
if (pt->ProcType.tags != 0) {
|
if (pt->ProcType.tags != 0) {
|
||||||
syntax_error(token, "A procedure type cannot have tags");
|
syntax_error(token, "A procedure type cannot have tags");
|
||||||
}
|
}
|
||||||
type = pt;
|
return pt;
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case Token_OpenParen: {
|
case Token_OpenParen: {
|
||||||
Token open = expect_token(f, Token_OpenParen);
|
Token open = expect_token(f, Token_OpenParen);
|
||||||
AstNode *type = parse_type(f);
|
AstNode *type = parse_type(f);
|
||||||
Token close = expect_token(f, Token_CloseParen);
|
Token close = expect_token(f, Token_CloseParen);
|
||||||
type = ast_paren_expr(f, type, open, close);
|
return ast_paren_expr(f, type, open, close);
|
||||||
} break;
|
} break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return type;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -118,6 +118,10 @@ TOKEN_KIND(Token__KeywordBegin, "_KeywordBegin"), \
|
|||||||
TOKEN_KIND(Token_context, "context"), \
|
TOKEN_KIND(Token_context, "context"), \
|
||||||
TOKEN_KIND(Token_push_context, "push_context"), \
|
TOKEN_KIND(Token_push_context, "push_context"), \
|
||||||
TOKEN_KIND(Token_push_allocator, "push_allocator"), \
|
TOKEN_KIND(Token_push_allocator, "push_allocator"), \
|
||||||
|
TOKEN_KIND(Token_size_of, "size_of"), \
|
||||||
|
TOKEN_KIND(Token_align_of, "align_of"), \
|
||||||
|
TOKEN_KIND(Token_offset_of, "offset_of"), \
|
||||||
|
TOKEN_KIND(Token_type_of, "type_of"), \
|
||||||
TOKEN_KIND(Token_asm, "asm"), \
|
TOKEN_KIND(Token_asm, "asm"), \
|
||||||
TOKEN_KIND(Token_yield, "yield"), \
|
TOKEN_KIND(Token_yield, "yield"), \
|
||||||
TOKEN_KIND(Token_await, "await"), \
|
TOKEN_KIND(Token_await, "await"), \
|
||||||
|
|||||||
Reference in New Issue
Block a user