Field access now works, somehow! It was easier then I thought,

probably introduced a bunch of bugs though
This commit is contained in:
Krzosa Karol
2022-09-30 19:58:47 +02:00
parent 32fbacff6d
commit 6cd0596fd5
4 changed files with 84 additions and 84 deletions

View File

@@ -1,6 +1,6 @@
# The Core Language # 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. 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.

View File

@@ -971,13 +971,14 @@ try_propagating_resolved_type_to_untyped_literals(Ast *ast, Ast_Type *type, Ast_
} }
} }
// @todo: Remove compound context
function Ast_Type * function Ast_Type *
resolve_typespec(Ast_Expr *ast, Resolve_Flag flags, Ast_Type *compound_context = 0){ resolve_typespec(Ast_Expr *ast, Resolve_Flag flags, Ast_Type *compound_context = 0){
if(!ast && is_flag_set(flags, AST_CAN_BE_NULL)) if(!ast && is_flag_set(flags, AST_CAN_BE_NULL))
return 0; return 0;
Scratch scratch; 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)) if(is_flag_set(flags, RESOLVE_TYPESPEC_COMPLETE))
type_complete(resolved.type_val); type_complete(resolved.type_val);
if(resolved.type != type_type) 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; return resolved.type_val;
} }
// @todo: Remove compound context
function Operand function Operand
resolve_and_require_bool(const char *error, Ast_Expr *expr, Resolve_Flag flags, Ast_Type *compound_context = 0){ resolve_and_require_bool(const char *error, Ast_Expr *expr, Resolve_Flag flags, Ast_Type *compound_context = 0){
if(!expr){ if(!expr){
@@ -994,7 +996,7 @@ resolve_and_require_bool(const char *error, Ast_Expr *expr, Resolve_Flag flags,
} }
Scratch scratch; Scratch scratch;
Operand op = resolve_expr(expr, flags, compound_context); Operand op = resolve_expr(expr, flags, compound_context, 0);
if(!is_bool(op.type)){ if(!is_bool(op.type)){
compiler_error(expr->pos, "Expected type [Bool] got instead type %Q :: %s", typestring(op.type), error); 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; return op;
} }
// @todo: Remove compound context
function Operand function Operand
require_const_int(Ast_Expr *expr, Resolve_Flag flags, Ast_Type *compound_context = 0){ 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) if(expr == 0 && flags)
return op; return op;
@@ -1036,10 +1039,10 @@ resolve_stmt(Ast *ast, Ast_Type *ret){
Operand op; Operand op;
if(is_tuple(ret)){ if(is_tuple(ret)){
Ast_Type *sub_type = ret->agg.members[it.i].type; 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{ 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); 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); resolve_expr(node->init, AST_CAN_BE_NULL, 0, 0);
Operand op = resolve_expr(node->cond, AST_CAN_BE_NULL); Operand op = resolve_expr(node->cond, AST_CAN_BE_NULL, 0, 0);
if(node->cond){ if(node->cond){
if((!node->init && !node->iter) && (is_array(op.type) || is_slice(op.type))){ if((!node->init && !node->iter) && (is_array(op.type) || is_slice(op.type))){
node->is_array_traversal = true; 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); For(node->scope->stmts) resolve_stmt(it, ret);
BREAK(); BREAK();
} }
@@ -1138,7 +1141,7 @@ resolve_stmt(Ast *ast, Ast_Type *ret){
} }
CASE(SWITCH, Switch){ 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)) 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)); 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); try_propagating_resolved_type_to_untyped_literals(node->value, base.type);
For(node->cases){ For(node->cases){
For_Named(it->labels, label){ 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"); 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); 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); 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){ 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)) if(!is_tuple(expr_op.type))
compiler_error(node->pos, "Expected expression to be of type [Tuple]"); compiler_error(node->pos, "Expected expression to be of type [Tuple]");
if(expr_op.type->agg.members.len != node->vars.len) if(expr_op.type->agg.members.len != node->vars.len)
@@ -1183,7 +1186,7 @@ resolve_stmt(Ast *ast, Ast_Type *ret){
default:{ default:{
if(is_flag_set(ast->flags, AST_EXPR)){ if(is_flag_set(ast->flags, AST_EXPR)){
assert(is_flag_set(ast->flags, AST_STMT)); 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; else invalid_codepath;
} }
@@ -1213,7 +1216,7 @@ resolve_lambda_type(Ast_Lambda *lambda){
else { else {
Ast_Type *type = resolve_typespec(it->typespec, AST_CANT_BE_NULL); 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); make_sure_value_is_compatible_with_type(it->pos, &default_value, type, EXPR_CAN_BE_NULL);
it->type = type; it->type = type;
@@ -1245,7 +1248,7 @@ try_resolving_lambda_scope(Operand *op, Ast_Lambda *lambda, Ast_Type *lambda_typ
function Operand function Operand
resolve_cast(Ast_Binary *node){ 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 *type = resolve_typespec(node->right, AST_CANT_BE_NULL);
Ast_Type *original_type = expr.type; Ast_Type *original_type = expr.type;
node->before_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; 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); make_sure_value_is_compatible_with_type(it->pos, &item, item_type, TYPE_AND_EXPR_REQUIRED);
it->resolved_type = item_type; it->resolved_type = item_type;
try_propagating_resolved_type_to_untyped_literals(it->item, it->resolved_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); 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); make_sure_value_is_compatible_with_type(it->pos, &item, item_type, TYPE_AND_EXPR_REQUIRED);
it->resolved_type = item_type; 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; 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 * function Ast_Expr *
unpack_ast_call_expr_for_builtin(Ast_Call *call){ unpack_ast_call_expr_for_builtin(Ast_Call *call){
if(call->exprs.len != 1) { if(call->exprs.len != 1) {
@@ -1459,7 +1419,7 @@ expr_atom_is_equal_intern(Ast_Expr *expr, Intern_String intern){
} }
function Operand 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 {}; if(!ast && is_flag_set(flags, AST_CAN_BE_NULL)) return {};
assert(is_flag_set(ast->flags, AST_EXPR)); assert(is_flag_set(ast->flags, AST_EXPR));
assert(ast->parent_scope->kind == AST_SCOPE || ast->parent_scope->kind == AST_FILE); 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){ switch(ast->kind){
CASE(IDENT, Atom){ 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; node->resolved_type = node->resolved_decl->type;
Operand result = operand(node->resolved_decl); 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 // Typespec array [32]int
CASE(ARRAY, Array){ 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); 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"); if(type.type != type_type) compiler_error(node->pos, "Prefix array operator is only allowed on types");
type_complete(type.type_val); type_complete(type.type_val);
@@ -1517,8 +1480,8 @@ resolve_expr(Ast_Expr *ast, Resolve_Flag flags, Ast_Type *compound_context){
} }
CASE(INDEX, Index){ CASE(INDEX, Index){
Operand left = resolve_expr(node->expr, 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); Operand index = resolve_expr(node->index, AST_CANT_BE_NULL, 0, 0);
if(!is_int(index.type)) 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)); 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){ CASE(BINARY, Binary){
if(token_is_assign(node->op)){ if(token_is_assign(node->op)){
assert(is_flag_set(node->flags, AST_STMT)); 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"); 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); 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)); 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); return resolve_cast(node);
} }
else if(node->op == TK_Dot){ else if(node->op == TK_Dot){
Operand op = resolve_field_access(node, 0); Operand left = resolve_expr(node->left, AST_CANT_BE_NULL, 0, field_access_scope);
node->resolved_type = op.type; Ast_Scope *scope = 0;
if(op.is_const){ Ast_Decl *decl = left.resolved_decl;
rewrite_into_const(node, Ast_Binary, op.value); 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{ else{
Operand left = resolve_expr(node->left, 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); Operand right = resolve_expr(node->right, AST_CANT_BE_NULL, 0, field_access_scope);
B32 is_const = left.is_const && right.is_const; B32 is_const = left.is_const && right.is_const;
B32 proceed_to_default_operator_handler = true; 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){ 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(node->op == TK_Pointer){
if(value.type->kind == TYPE_POINTER){ if(value.type->kind == TYPE_POINTER){
node->resolved_type = value.type->base; 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){ 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; Ast_Type *type = op.type;
if(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)){ if(expr_atom_is_equal_intern(node->name, intern_sizeof)){
Ast_Expr *expr = unpack_ast_call_expr_for_builtin(node); 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; node->kind = AST_SIZE_OF;
if(!name.is_const){ if(!name.is_const){
compiler_error(node->pos, "SizeOf requires a constant value"); 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)){ else if(expr_atom_is_equal_intern(node->name, intern_len)){
Ast_Expr *expr = unpack_ast_call_expr_for_builtin(node); 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->kind = AST_LENGTH_OF;
node->resolved_type = type_s64; node->resolved_type = type_s64;
if(is_array(name.type)){ 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)){ else if(expr_atom_is_equal_intern(node->name, intern_alignof)){
Ast_Expr *expr = unpack_ast_call_expr_for_builtin(node); 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; node->kind = AST_ALIGN_OF;
if(!name.is_const) { if(!name.is_const) {
compiler_error(node->pos, "AlignOf requires a constant value"); 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 { 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){ if(name.type->kind != TYPE_LAMBDA){
compiler_error(node->pos, "Calling %Q which is not a [Lambda]", typestring(name.type)); 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){ if(item){
set_flag(item->call_flags, CALL_INCLUDED); 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)){ 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); make_sure_value_is_compatible_with_type(item->pos, &expr, lambda_arg->type->base, TYPE_AND_EXPR_REQUIRED);
item->resolved_type = expr.type; item->resolved_type = expr.type;
@@ -1930,7 +1921,7 @@ resolve_decl(Ast_Decl *ast){
CASE(CONST, Decl){ CASE(CONST, Decl){
// @warning: if in the future we add type here then pass it to resolve expr for // @warning: if in the future we add type here then pass it to resolve expr for
// compound // 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){ if(!op.is_const){
compiler_error(node->pos, "Assigning a value that is not constant to a constant declaration"); 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){ CASE(VAR, Decl){
Ast_Type *type = node->type; Ast_Type *type = node->type;
if(!type) type = resolve_typespec(node->typespec, AST_CAN_BE_NULL | RESOLVE_TYPESPEC_COMPLETE); 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); 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); make_sure_value_is_compatible_with_type(node->pos, &op, type, EXPR_CAN_BE_NULL|TYPE_CAN_BE_NULL);

View File

@@ -37,7 +37,7 @@ enum{
SEARCH_ONLY_CURRENT_SCOPE = bit_flag(1), 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 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 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); function String gen_string_simple_decl(Allocator *a, Ast_Type *ast, String name = {}, Ast_Scope *scope = 0, bool scope_names = true);

View File

@@ -0,0 +1,9 @@
main :: (): int
a := 10
b := 20
values := []Any{a, b}
c := values[0].data
return 0