Field access now works, somehow! It was easier then I thought,
probably introduced a bunch of bugs though
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
# The Core Language
|
||||
|
||||
A compiled language that assumes C as base reality but it also has lots of ideas taken from Jai, Go like type system, order indepent declarations using Ion algorithm. Syntax currently is whitespace significant. Made to practice language development, **it's not supposed to be used**. It has lot's of ideas from modern programming languages that you would not find in any compiler book. It supports **modules** combined with **ordered independent declarations** and **lazy typechecking**. Also **runtime reflection**, **slices** and other standard features you would find in C.
|
||||
A compiled language that assumes C as base reality but it also has lots of ideas taken from Jai, Go like type system, order indepent declarations using Ion algorithm. Syntax currently is whitespace significant. Made to practice language development. It has lot's of ideas from modern programming languages that you would not find in any compiler book. It supports **modules** combined with **ordered independent declarations** and **lazy typechecking**. Also **runtime reflection**, **slices** and other standard features you would find in C.
|
||||
|
||||
The language is currently **very debuggable**. It can produce readable C code with line directives. This allows you to debug the programs with Visual Studio with full source mapping, exactly like you would debug C programs.
|
||||
|
||||
|
||||
@@ -971,13 +971,14 @@ try_propagating_resolved_type_to_untyped_literals(Ast *ast, Ast_Type *type, Ast_
|
||||
}
|
||||
}
|
||||
|
||||
// @todo: Remove compound context
|
||||
function Ast_Type *
|
||||
resolve_typespec(Ast_Expr *ast, Resolve_Flag flags, Ast_Type *compound_context = 0){
|
||||
if(!ast && is_flag_set(flags, AST_CAN_BE_NULL))
|
||||
return 0;
|
||||
|
||||
Scratch scratch;
|
||||
Operand resolved = resolve_expr(ast, flags | RESOLVE_TYPESPEC, compound_context);
|
||||
Operand resolved = resolve_expr(ast, flags | RESOLVE_TYPESPEC, compound_context, 0);
|
||||
if(is_flag_set(flags, RESOLVE_TYPESPEC_COMPLETE))
|
||||
type_complete(resolved.type_val);
|
||||
if(resolved.type != type_type)
|
||||
@@ -985,6 +986,7 @@ resolve_typespec(Ast_Expr *ast, Resolve_Flag flags, Ast_Type *compound_context =
|
||||
return resolved.type_val;
|
||||
}
|
||||
|
||||
// @todo: Remove compound context
|
||||
function Operand
|
||||
resolve_and_require_bool(const char *error, Ast_Expr *expr, Resolve_Flag flags, Ast_Type *compound_context = 0){
|
||||
if(!expr){
|
||||
@@ -994,7 +996,7 @@ resolve_and_require_bool(const char *error, Ast_Expr *expr, Resolve_Flag flags,
|
||||
}
|
||||
|
||||
Scratch scratch;
|
||||
Operand op = resolve_expr(expr, flags, compound_context);
|
||||
Operand op = resolve_expr(expr, flags, compound_context, 0);
|
||||
if(!is_bool(op.type)){
|
||||
compiler_error(expr->pos, "Expected type [Bool] got instead type %Q :: %s", typestring(op.type), error);
|
||||
}
|
||||
@@ -1002,9 +1004,10 @@ resolve_and_require_bool(const char *error, Ast_Expr *expr, Resolve_Flag flags,
|
||||
return op;
|
||||
}
|
||||
|
||||
// @todo: Remove compound context
|
||||
function Operand
|
||||
require_const_int(Ast_Expr *expr, Resolve_Flag flags, Ast_Type *compound_context = 0){
|
||||
Operand op = resolve_expr(expr, flags, compound_context);
|
||||
Operand op = resolve_expr(expr, flags, compound_context, 0);
|
||||
|
||||
if(expr == 0 && flags)
|
||||
return op;
|
||||
@@ -1036,10 +1039,10 @@ resolve_stmt(Ast *ast, Ast_Type *ret){
|
||||
Operand op;
|
||||
if(is_tuple(ret)){
|
||||
Ast_Type *sub_type = ret->agg.members[it.i].type;
|
||||
op = resolve_expr(*it.item, AST_CAN_BE_NULL, sub_type);
|
||||
op = resolve_expr(*it.item, AST_CAN_BE_NULL, sub_type, 0);
|
||||
}
|
||||
else{
|
||||
op = resolve_expr(*it.item, AST_CAN_BE_NULL, ret);
|
||||
op = resolve_expr(*it.item, AST_CAN_BE_NULL, ret, 0);
|
||||
convert_untyped_to_typed(node->pos, &op.value, ret);
|
||||
}
|
||||
|
||||
@@ -1099,8 +1102,8 @@ resolve_stmt(Ast *ast, Ast_Type *ret){
|
||||
}
|
||||
}
|
||||
|
||||
resolve_expr(node->init, AST_CAN_BE_NULL);
|
||||
Operand op = resolve_expr(node->cond, AST_CAN_BE_NULL);
|
||||
resolve_expr(node->init, AST_CAN_BE_NULL, 0, 0);
|
||||
Operand op = resolve_expr(node->cond, AST_CAN_BE_NULL, 0, 0);
|
||||
if(node->cond){
|
||||
if((!node->init && !node->iter) && (is_array(op.type) || is_slice(op.type))){
|
||||
node->is_array_traversal = true;
|
||||
@@ -1120,7 +1123,7 @@ resolve_stmt(Ast *ast, Ast_Type *ret){
|
||||
}
|
||||
}
|
||||
|
||||
resolve_expr(node->iter, AST_CAN_BE_NULL);
|
||||
resolve_expr(node->iter, AST_CAN_BE_NULL, 0, 0);
|
||||
For(node->scope->stmts) resolve_stmt(it, ret);
|
||||
BREAK();
|
||||
}
|
||||
@@ -1138,7 +1141,7 @@ resolve_stmt(Ast *ast, Ast_Type *ret){
|
||||
}
|
||||
|
||||
CASE(SWITCH, Switch){
|
||||
Operand base = resolve_expr(node->value, AST_CANT_BE_NULL);
|
||||
Operand base = resolve_expr(node->value, AST_CANT_BE_NULL, 0, 0);
|
||||
if(!is_int(base.type) && !is_enum(base.type))
|
||||
compiler_error(node->pos, "You can only switch on integer values(enums included), the type of expression in switch statement is instead %Q", typestring(base.type));
|
||||
|
||||
@@ -1146,7 +1149,7 @@ resolve_stmt(Ast *ast, Ast_Type *ret){
|
||||
try_propagating_resolved_type_to_untyped_literals(node->value, base.type);
|
||||
For(node->cases){
|
||||
For_Named(it->labels, label){
|
||||
Operand op = resolve_expr(label, AST_CANT_BE_NULL);
|
||||
Operand op = resolve_expr(label, AST_CANT_BE_NULL, 0, 0);
|
||||
if(!op.is_const) compiler_error(label->pos, "Switch label required to be constant");
|
||||
make_sure_value_is_compatible_with_type(label->pos, &op, base.type, TYPE_AND_EXPR_REQUIRED);
|
||||
try_propagating_resolved_type_to_untyped_literals(label, base.type);
|
||||
@@ -1163,7 +1166,7 @@ resolve_stmt(Ast *ast, Ast_Type *ret){
|
||||
}
|
||||
|
||||
CASE(VAR_UNPACK, Var_Unpack){
|
||||
Operand expr_op = resolve_expr(node->expr, AST_CANT_BE_NULL);
|
||||
Operand expr_op = resolve_expr(node->expr, AST_CANT_BE_NULL, 0, 0);
|
||||
if(!is_tuple(expr_op.type))
|
||||
compiler_error(node->pos, "Expected expression to be of type [Tuple]");
|
||||
if(expr_op.type->agg.members.len != node->vars.len)
|
||||
@@ -1183,7 +1186,7 @@ resolve_stmt(Ast *ast, Ast_Type *ret){
|
||||
default:{
|
||||
if(is_flag_set(ast->flags, AST_EXPR)){
|
||||
assert(is_flag_set(ast->flags, AST_STMT));
|
||||
resolve_expr((Ast_Expr *)ast, AST_CANT_BE_NULL);
|
||||
resolve_expr((Ast_Expr *)ast, AST_CANT_BE_NULL, 0, 0);
|
||||
}
|
||||
else invalid_codepath;
|
||||
}
|
||||
@@ -1213,7 +1216,7 @@ resolve_lambda_type(Ast_Lambda *lambda){
|
||||
|
||||
else {
|
||||
Ast_Type *type = resolve_typespec(it->typespec, AST_CANT_BE_NULL);
|
||||
Operand default_value = resolve_expr(it->expr, AST_CAN_BE_NULL, type);
|
||||
Operand default_value = resolve_expr(it->expr, AST_CAN_BE_NULL, type, 0);
|
||||
make_sure_value_is_compatible_with_type(it->pos, &default_value, type, EXPR_CAN_BE_NULL);
|
||||
|
||||
it->type = type;
|
||||
@@ -1245,7 +1248,7 @@ try_resolving_lambda_scope(Operand *op, Ast_Lambda *lambda, Ast_Type *lambda_typ
|
||||
|
||||
function Operand
|
||||
resolve_cast(Ast_Binary *node){
|
||||
Operand expr = resolve_expr(node->left, AST_CANT_BE_NULL);
|
||||
Operand expr = resolve_expr(node->left, AST_CANT_BE_NULL, 0, 0);
|
||||
Ast_Type *type = resolve_typespec(node->right, AST_CANT_BE_NULL);
|
||||
Ast_Type *original_type = expr.type;
|
||||
node->before_type = expr.type;
|
||||
@@ -1330,7 +1333,7 @@ resolve_compound_array(Ast_Call *node, Ast_Type *type){
|
||||
it->resolved_index = default_counter;
|
||||
}
|
||||
|
||||
Operand item = resolve_expr(it->item, AST_CANT_BE_NULL, item_type);
|
||||
Operand item = resolve_expr(it->item, AST_CANT_BE_NULL, item_type, 0);
|
||||
make_sure_value_is_compatible_with_type(it->pos, &item, item_type, TYPE_AND_EXPR_REQUIRED);
|
||||
it->resolved_type = item_type;
|
||||
try_propagating_resolved_type_to_untyped_literals(it->item, it->resolved_type);
|
||||
@@ -1385,7 +1388,7 @@ resolve_compound_struct(Ast_Call *node, Ast_Type *type){
|
||||
}
|
||||
|
||||
assert(item_type);
|
||||
Operand item = resolve_expr(it->item, AST_CANT_BE_NULL, item_type);
|
||||
Operand item = resolve_expr(it->item, AST_CANT_BE_NULL, item_type, 0);
|
||||
make_sure_value_is_compatible_with_type(it->pos, &item, item_type, TYPE_AND_EXPR_REQUIRED);
|
||||
|
||||
it->resolved_type = item_type;
|
||||
@@ -1395,49 +1398,6 @@ resolve_compound_struct(Ast_Call *node, Ast_Type *type){
|
||||
For(type->agg.members) it.visited = false;
|
||||
}
|
||||
|
||||
function Operand
|
||||
resolve_field_access(Ast_Expr *node, Ast_Scope *context){
|
||||
Ast_Binary *current = 0;
|
||||
Ast_Expr *next = 0;
|
||||
if(node->kind == AST_BINARY){
|
||||
current = (Ast_Binary *)node;
|
||||
next = current->right;
|
||||
node = current->left;
|
||||
}
|
||||
|
||||
if(node->kind != AST_IDENT)
|
||||
compiler_error(node->pos, "Required to be identifier in field access");
|
||||
|
||||
Ast_Atom *ident = (Ast_Atom *)node;
|
||||
Ast_Scope *scope = context ? context : node->parent_scope;
|
||||
Search_Flag flag = context ? SEARCH_ONLY_CURRENT_SCOPE : 0;
|
||||
Ast_Decl *decl = resolve_name(scope, node->pos, ident->intern_val, flag);
|
||||
ident->resolved_decl = decl;
|
||||
if(decl->kind == AST_FILE_NAMESPACE || decl->kind == AST_MODULE_NAMESPACE){
|
||||
assert(next);
|
||||
return resolve_field_access(next, decl->scope);
|
||||
}
|
||||
|
||||
Ast_Type *type = decl->type;
|
||||
if(type == type_type && decl->type_val && (is_enum(decl->type_val) || is_struct(decl->type_val)))
|
||||
type = decl->type_val;
|
||||
if(current) current->dot_access_step_resolution = type;
|
||||
if(is_pointer(type)) type = type->base;
|
||||
|
||||
type_complete(type);
|
||||
if(next && !is_struct(type) && !is_enum(type)){
|
||||
compiler_error(node->pos, "Dot access");
|
||||
}
|
||||
|
||||
if(!next){
|
||||
Operand op = operand(decl);
|
||||
return op;
|
||||
}
|
||||
|
||||
assert(next);
|
||||
return resolve_field_access(next, ((Ast_Decl *)type->ast)->scope);
|
||||
}
|
||||
|
||||
function Ast_Expr *
|
||||
unpack_ast_call_expr_for_builtin(Ast_Call *call){
|
||||
if(call->exprs.len != 1) {
|
||||
@@ -1459,7 +1419,7 @@ expr_atom_is_equal_intern(Ast_Expr *expr, Intern_String intern){
|
||||
}
|
||||
|
||||
function Operand
|
||||
resolve_expr(Ast_Expr *ast, Resolve_Flag flags, Ast_Type *compound_context){
|
||||
resolve_expr(Ast_Expr *ast, Resolve_Flag flags, Ast_Type *compound_context, Ast_Scope *field_access_scope){
|
||||
if(!ast && is_flag_set(flags, AST_CAN_BE_NULL)) return {};
|
||||
assert(is_flag_set(ast->flags, AST_EXPR));
|
||||
assert(ast->parent_scope->kind == AST_SCOPE || ast->parent_scope->kind == AST_FILE);
|
||||
@@ -1467,7 +1427,10 @@ resolve_expr(Ast_Expr *ast, Resolve_Flag flags, Ast_Type *compound_context){
|
||||
switch(ast->kind){
|
||||
|
||||
CASE(IDENT, Atom){
|
||||
node->resolved_decl = resolve_name(node->parent_scope, node->pos, node->intern_val);
|
||||
Ast_Scope *scope = field_access_scope ? field_access_scope : node->parent_scope;
|
||||
Search_Flag flag = field_access_scope ? SEARCH_ONLY_CURRENT_SCOPE : 0;
|
||||
|
||||
node->resolved_decl = resolve_name(scope, node->pos, node->intern_val, flag);
|
||||
node->resolved_type = node->resolved_decl->type;
|
||||
|
||||
Operand result = operand(node->resolved_decl);
|
||||
@@ -1485,7 +1448,7 @@ resolve_expr(Ast_Expr *ast, Resolve_Flag flags, Ast_Type *compound_context){
|
||||
|
||||
// Typespec array [32]int
|
||||
CASE(ARRAY, Array){
|
||||
Operand type = resolve_expr(node->base, AST_CANT_BE_NULL);
|
||||
Operand type = resolve_expr(node->base, AST_CANT_BE_NULL, 0, 0);
|
||||
Operand expr = require_const_int(node->expr, AST_CAN_BE_NULL);
|
||||
if(type.type != type_type) compiler_error(node->pos, "Prefix array operator is only allowed on types");
|
||||
type_complete(type.type_val);
|
||||
@@ -1517,8 +1480,8 @@ resolve_expr(Ast_Expr *ast, Resolve_Flag flags, Ast_Type *compound_context){
|
||||
}
|
||||
|
||||
CASE(INDEX, Index){
|
||||
Operand left = resolve_expr(node->expr, AST_CANT_BE_NULL);
|
||||
Operand index = resolve_expr(node->index, AST_CANT_BE_NULL);
|
||||
Operand left = resolve_expr(node->expr, AST_CANT_BE_NULL , 0, field_access_scope);
|
||||
Operand index = resolve_expr(node->index, AST_CANT_BE_NULL, 0, 0);
|
||||
if(!is_int(index.type))
|
||||
compiler_error(node->pos, "Trying to index the array with invalid type, expected [Int] got instead %Q", typestring(index.type));
|
||||
|
||||
@@ -1556,9 +1519,9 @@ resolve_expr(Ast_Expr *ast, Resolve_Flag flags, Ast_Type *compound_context){
|
||||
CASE(BINARY, Binary){
|
||||
if(token_is_assign(node->op)){
|
||||
assert(is_flag_set(node->flags, AST_STMT));
|
||||
Operand left = resolve_expr(node->left, AST_CANT_BE_NULL);
|
||||
Operand left = resolve_expr(node->left, AST_CANT_BE_NULL, 0, field_access_scope);
|
||||
if(!left.is_lvalue) compiler_error(node->pos, "Assigning to rvalue");
|
||||
Operand right = resolve_expr(node->right, AST_CANT_BE_NULL);
|
||||
Operand right = resolve_expr(node->right, AST_CANT_BE_NULL, 0, field_access_scope);
|
||||
|
||||
convert_untyped_to_typed(node->pos, &right.value, left.type);
|
||||
if(left.type != right.type) compiler_error(node->pos, "Can't assign value when left is %Q and right is %Q", typestring(left.type), typestring(right.type));
|
||||
@@ -1572,17 +1535,45 @@ resolve_expr(Ast_Expr *ast, Resolve_Flag flags, Ast_Type *compound_context){
|
||||
return resolve_cast(node);
|
||||
}
|
||||
else if(node->op == TK_Dot){
|
||||
Operand op = resolve_field_access(node, 0);
|
||||
node->resolved_type = op.type;
|
||||
Operand left = resolve_expr(node->left, AST_CANT_BE_NULL, 0, field_access_scope);
|
||||
Ast_Scope *scope = 0;
|
||||
|
||||
if(op.is_const){
|
||||
rewrite_into_const(node, Ast_Binary, op.value);
|
||||
Ast_Decl *decl = left.resolved_decl;
|
||||
if(decl && (decl->kind == AST_FILE_NAMESPACE || decl->kind == AST_MODULE_NAMESPACE)){
|
||||
scope = decl->scope;
|
||||
}
|
||||
return op;
|
||||
|
||||
else {
|
||||
// Make sure it's a type but also not a type id
|
||||
Ast_Type *type = left.type;
|
||||
if(type == type_type && left.type_val){
|
||||
if(is_enum(left.type_val) || is_struct(left.type_val)){
|
||||
type = left.type_val;
|
||||
}
|
||||
}
|
||||
|
||||
// We need 2 resolved types, for left and right
|
||||
// Then we can compare if we got a pointer we need to
|
||||
// figure that out to replace '.' with '->' for pointer structs
|
||||
node->dot_access_step_resolution = type;
|
||||
|
||||
if(is_pointer(type)) type = type->base;
|
||||
type_complete(type);
|
||||
|
||||
scope = ((Ast_Decl *)type->ast)->scope;
|
||||
}
|
||||
|
||||
Operand right = resolve_expr(node->right, AST_CANT_BE_NULL, 0, scope);
|
||||
node->resolved_type = right.type;
|
||||
|
||||
if(right.is_const){
|
||||
rewrite_into_const(node, Ast_Binary, right.value);
|
||||
}
|
||||
return right;
|
||||
}
|
||||
else{
|
||||
Operand left = resolve_expr(node->left, AST_CANT_BE_NULL);
|
||||
Operand right = resolve_expr(node->right, AST_CANT_BE_NULL);
|
||||
Operand left = resolve_expr(node->left, AST_CANT_BE_NULL, 0, field_access_scope);
|
||||
Operand right = resolve_expr(node->right, AST_CANT_BE_NULL, 0, field_access_scope);
|
||||
B32 is_const = left.is_const && right.is_const;
|
||||
B32 proceed_to_default_operator_handler = true;
|
||||
|
||||
@@ -1629,7 +1620,7 @@ resolve_expr(Ast_Expr *ast, Resolve_Flag flags, Ast_Type *compound_context){
|
||||
}
|
||||
|
||||
CASE(UNARY, Unary){
|
||||
Operand value = resolve_expr(node->expr, inherit_flag(flags, AST_CANT_BE_NULL));
|
||||
Operand value = resolve_expr(node->expr, inherit_flag(flags, AST_CANT_BE_NULL), 0, field_access_scope);
|
||||
if(node->op == TK_Pointer){
|
||||
if(value.type->kind == TYPE_POINTER){
|
||||
node->resolved_type = value.type->base;
|
||||
@@ -1685,7 +1676,7 @@ resolve_expr(Ast_Expr *ast, Resolve_Flag flags, Ast_Type *compound_context){
|
||||
}
|
||||
|
||||
CASE(COMPOUND, Call){
|
||||
Operand op = resolve_expr(node->typespec, inherit_flag(flags, AST_CAN_BE_NULL));
|
||||
Operand op = resolve_expr(node->typespec, inherit_flag(flags, AST_CAN_BE_NULL), 0, field_access_scope);
|
||||
|
||||
Ast_Type *type = op.type;
|
||||
if(type){
|
||||
@@ -1716,7 +1707,7 @@ resolve_expr(Ast_Expr *ast, Resolve_Flag flags, Ast_Type *compound_context){
|
||||
if(expr_atom_is_equal_intern(node->name, intern_sizeof)){
|
||||
Ast_Expr *expr = unpack_ast_call_expr_for_builtin(node);
|
||||
|
||||
Operand name = resolve_expr(expr, inherit_flag(flags, AST_CANT_BE_NULL));
|
||||
Operand name = resolve_expr(expr, inherit_flag(flags, AST_CANT_BE_NULL), 0, field_access_scope);
|
||||
node->kind = AST_SIZE_OF;
|
||||
if(!name.is_const){
|
||||
compiler_error(node->pos, "SizeOf requires a constant value");
|
||||
@@ -1736,7 +1727,7 @@ resolve_expr(Ast_Expr *ast, Resolve_Flag flags, Ast_Type *compound_context){
|
||||
else if(expr_atom_is_equal_intern(node->name, intern_len)){
|
||||
Ast_Expr *expr = unpack_ast_call_expr_for_builtin(node);
|
||||
|
||||
Operand name = resolve_expr(expr, inherit_flag(flags, AST_CANT_BE_NULL));
|
||||
Operand name = resolve_expr(expr, inherit_flag(flags, AST_CANT_BE_NULL), 0, field_access_scope);
|
||||
node->kind = AST_LENGTH_OF;
|
||||
node->resolved_type = type_s64;
|
||||
if(is_array(name.type)){
|
||||
@@ -1757,7 +1748,7 @@ resolve_expr(Ast_Expr *ast, Resolve_Flag flags, Ast_Type *compound_context){
|
||||
|
||||
else if(expr_atom_is_equal_intern(node->name, intern_alignof)){
|
||||
Ast_Expr *expr = unpack_ast_call_expr_for_builtin(node);
|
||||
Operand name = resolve_expr(expr, inherit_flag(flags, AST_CANT_BE_NULL));
|
||||
Operand name = resolve_expr(expr, inherit_flag(flags, AST_CANT_BE_NULL), 0, field_access_scope);
|
||||
node->kind = AST_ALIGN_OF;
|
||||
if(!name.is_const) {
|
||||
compiler_error(node->pos, "AlignOf requires a constant value");
|
||||
@@ -1775,7 +1766,7 @@ resolve_expr(Ast_Expr *ast, Resolve_Flag flags, Ast_Type *compound_context){
|
||||
}
|
||||
|
||||
else {
|
||||
Operand name = resolve_expr(node->name, inherit_flag(flags, AST_CANT_BE_NULL));
|
||||
Operand name = resolve_expr(node->name, inherit_flag(flags, AST_CANT_BE_NULL), 0, field_access_scope);
|
||||
if(name.type->kind != TYPE_LAMBDA){
|
||||
compiler_error(node->pos, "Calling %Q which is not a [Lambda]", typestring(name.type));
|
||||
}
|
||||
@@ -1823,7 +1814,7 @@ resolve_expr(Ast_Expr *ast, Resolve_Flag flags, Ast_Type *compound_context){
|
||||
|
||||
if(item){
|
||||
set_flag(item->call_flags, CALL_INCLUDED);
|
||||
Operand expr = resolve_expr(item->item, AST_CANT_BE_NULL, lambda_arg->type);
|
||||
Operand expr = resolve_expr(item->item, AST_CANT_BE_NULL, lambda_arg->type, field_access_scope);
|
||||
if(is_flag_set(lambda_arg->flags, AST_ANY_VARGS)){
|
||||
make_sure_value_is_compatible_with_type(item->pos, &expr, lambda_arg->type->base, TYPE_AND_EXPR_REQUIRED);
|
||||
item->resolved_type = expr.type;
|
||||
@@ -1930,7 +1921,7 @@ resolve_decl(Ast_Decl *ast){
|
||||
CASE(CONST, Decl){
|
||||
// @warning: if in the future we add type here then pass it to resolve expr for
|
||||
// compound
|
||||
Operand op = resolve_expr(node->expr, AST_CANT_BE_NULL);
|
||||
Operand op = resolve_expr(node->expr, AST_CANT_BE_NULL, 0, 0);
|
||||
if(!op.is_const){
|
||||
compiler_error(node->pos, "Assigning a value that is not constant to a constant declaration");
|
||||
}
|
||||
@@ -1950,7 +1941,7 @@ resolve_decl(Ast_Decl *ast){
|
||||
CASE(VAR, Decl){
|
||||
Ast_Type *type = node->type;
|
||||
if(!type) type = resolve_typespec(node->typespec, AST_CAN_BE_NULL | RESOLVE_TYPESPEC_COMPLETE);
|
||||
Operand op = resolve_expr(node->expr, AST_CAN_BE_NULL, type);
|
||||
Operand op = resolve_expr(node->expr, AST_CAN_BE_NULL, type, 0);
|
||||
assert(op.type != 0 || type != 0);
|
||||
|
||||
make_sure_value_is_compatible_with_type(node->pos, &op, type, EXPR_CAN_BE_NULL|TYPE_CAN_BE_NULL);
|
||||
|
||||
@@ -37,7 +37,7 @@ enum{
|
||||
SEARCH_ONLY_CURRENT_SCOPE = bit_flag(1),
|
||||
};
|
||||
|
||||
function Operand resolve_expr(Ast_Expr *ast, Resolve_Flag flags, Ast_Type *compound_context = 0);
|
||||
function Operand resolve_expr(Ast_Expr *ast, Resolve_Flag flags, Ast_Type *compound_context, Ast_Scope *field_access_scope);
|
||||
function void resolve_decl(Ast_Decl *ast);
|
||||
function Ast_Decl *resolve_name(Ast_Scope *parent_scope, Token *pos, Intern_String name, Search_Flag search_flags = 0);
|
||||
function String gen_string_simple_decl(Allocator *a, Ast_Type *ast, String name = {}, Ast_Scope *scope = 0, bool scope_names = true);
|
||||
|
||||
9
examples/any_and_variadic_args.core
Normal file
9
examples/any_and_variadic_args.core
Normal file
@@ -0,0 +1,9 @@
|
||||
|
||||
main :: (): int
|
||||
a := 10
|
||||
b := 20
|
||||
values := []Any{a, b}
|
||||
|
||||
c := values[0].data
|
||||
|
||||
return 0
|
||||
Reference in New Issue
Block a user