length_of align_of size_of are no longer operators but function calls
This commit is contained in:
@@ -362,9 +362,10 @@ gen_expr(Ast_Expr *ast, Ast_Type *type_of_var){
|
|||||||
BREAK();
|
BREAK();
|
||||||
}
|
}
|
||||||
|
|
||||||
CASE(LENGTH_OF, Builtin){
|
CASE(LENGTH_OF, Call){
|
||||||
gen_expr(node->expr);
|
Ast_Expr *expr = unpack_ast_call_expr_for_builtin(node);
|
||||||
if(is_pointer(node->expr->resolved_type))
|
gen_expr(expr);
|
||||||
|
if(is_pointer(expr->resolved_type))
|
||||||
gen("->len");
|
gen("->len");
|
||||||
else gen(".len");
|
else gen(".len");
|
||||||
BREAK();
|
BREAK();
|
||||||
|
|||||||
@@ -169,11 +169,11 @@ Intern_String keyword_switch;
|
|||||||
Intern_String keyword_break;
|
Intern_String keyword_break;
|
||||||
Intern_String keyword_elif;
|
Intern_String keyword_elif;
|
||||||
Intern_String keyword_assert;
|
Intern_String keyword_assert;
|
||||||
Intern_String keyword_sizeof;
|
|
||||||
Intern_String keyword_alignof;
|
|
||||||
Intern_String keyword_lengthof;
|
|
||||||
Intern_String keyword_enum;
|
Intern_String keyword_enum;
|
||||||
|
|
||||||
|
Intern_String intern_sizeof;
|
||||||
|
Intern_String intern_alignof;
|
||||||
|
Intern_String intern_lengthof;
|
||||||
Intern_String intern_void;
|
Intern_String intern_void;
|
||||||
Intern_String intern_foreign;
|
Intern_String intern_foreign;
|
||||||
Intern_String intern_it;
|
Intern_String intern_it;
|
||||||
@@ -226,9 +226,6 @@ lex_init(Allocator *token_string_arena, Allocator *map_allocator, Lexer *l){
|
|||||||
|
|
||||||
keyword_struct= l->intern("struct"_s);
|
keyword_struct= l->intern("struct"_s);
|
||||||
keyword_union = l->intern("union"_s);
|
keyword_union = l->intern("union"_s);
|
||||||
keyword_sizeof = l->intern("size_of"_s);
|
|
||||||
keyword_lengthof = l->intern("length_of"_s);
|
|
||||||
keyword_alignof = l->intern("align_of"_s);
|
|
||||||
keyword_true = l->intern("true"_s);
|
keyword_true = l->intern("true"_s);
|
||||||
keyword_default = l->intern("default"_s);
|
keyword_default = l->intern("default"_s);
|
||||||
keyword_break = l->intern("break"_s);
|
keyword_break = l->intern("break"_s);
|
||||||
@@ -245,6 +242,9 @@ lex_init(Allocator *token_string_arena, Allocator *map_allocator, Lexer *l){
|
|||||||
l->interns.first_keyword = keyword_struct.str;
|
l->interns.first_keyword = keyword_struct.str;
|
||||||
l->interns.last_keyword = keyword_enum.str;
|
l->interns.last_keyword = keyword_enum.str;
|
||||||
|
|
||||||
|
intern_sizeof = l->intern("size_of"_s);
|
||||||
|
intern_lengthof = l->intern("length_of"_s);
|
||||||
|
intern_alignof = l->intern("align_of"_s);
|
||||||
intern_foreign = intern_string(&l->interns, "foreign"_s);
|
intern_foreign = intern_string(&l->interns, "foreign"_s);
|
||||||
intern_strict = intern_string(&l->interns, "strict"_s);
|
intern_strict = intern_string(&l->interns, "strict"_s);
|
||||||
intern_void = intern_string(&l->interns, "void"_s);
|
intern_void = intern_string(&l->interns, "void"_s);
|
||||||
|
|||||||
@@ -566,25 +566,7 @@ parse_expr(S64 min_bp){
|
|||||||
left = ast_bool(token, 1);
|
left = ast_bool(token, 1);
|
||||||
else if(token->intern_val == keyword_false)
|
else if(token->intern_val == keyword_false)
|
||||||
left = ast_bool(token, 0);
|
left = ast_bool(token, 0);
|
||||||
else if(token->intern_val == keyword_sizeof){
|
else compiler_error(token, "Unexpected keyword: [%s]", token->intern_val.str);
|
||||||
token_expect(TK_OpenParen);
|
|
||||||
Ast_Expr *expr = parse_expr();
|
|
||||||
token_expect(TK_CloseParen);
|
|
||||||
left = ast_sizeof(token, expr);
|
|
||||||
}
|
|
||||||
else if(token->intern_val == keyword_alignof){
|
|
||||||
token_expect(TK_OpenParen);
|
|
||||||
Ast_Expr *expr = parse_expr();
|
|
||||||
token_expect(TK_CloseParen);
|
|
||||||
left = ast_alignof(token, expr);
|
|
||||||
}
|
|
||||||
else if(token->intern_val == keyword_lengthof){
|
|
||||||
token_expect(TK_OpenParen);
|
|
||||||
Ast_Expr *expr = parse_expr();
|
|
||||||
token_expect(TK_CloseParen);
|
|
||||||
left = ast_len(token, expr);
|
|
||||||
}
|
|
||||||
else compiler_error(token, "Unexpected keyword: [%s], expected keyword [cast]", token->intern_val.str);
|
|
||||||
}break;
|
}break;
|
||||||
|
|
||||||
case TK_OpenParen: {
|
case TK_OpenParen: {
|
||||||
|
|||||||
@@ -989,6 +989,26 @@ resolve_field_access(Ast_Expr *node, Ast_Scope *context){
|
|||||||
return resolve_field_access(next, ((Ast_Decl *)type->ast)->scope);
|
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) {
|
||||||
|
compiler_error(call->pos, "Expected exactly 1 argument inside a builtin function call got instead %d", (int)call->exprs.len);
|
||||||
|
}
|
||||||
|
return call->exprs[0]->item;
|
||||||
|
}
|
||||||
|
|
||||||
|
function bool
|
||||||
|
expr_atom_is_equal_intern(Ast_Expr *expr, Intern_String intern){
|
||||||
|
assert(expr->kind == AST_IDENT || expr->kind == AST_BINARY);
|
||||||
|
if(expr->kind == AST_IDENT){
|
||||||
|
Ast_Atom *atom = (Ast_Atom *)expr;
|
||||||
|
if(atom->intern_val == intern) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
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){
|
||||||
if(!ast && is_flag_set(flags, AST_CAN_BE_NULL)) return {};
|
if(!ast && is_flag_set(flags, AST_CAN_BE_NULL)) return {};
|
||||||
@@ -1202,28 +1222,26 @@ resolve_expr(Ast_Expr *ast, Resolve_Flag flags, Ast_Type *compound_context){
|
|||||||
BREAK();
|
BREAK();
|
||||||
}
|
}
|
||||||
|
|
||||||
CASE(ALIGN_OF, Builtin){
|
CASE(CALL, Call){
|
||||||
Operand name = resolve_expr(node->expr, inherit_flag(flags, AST_CANT_BE_NULL));
|
if(expr_atom_is_equal_intern(node->name, intern_sizeof)){
|
||||||
if(!name.is_const) compiler_error(node->pos, "align_of requires a constant value");
|
Ast_Expr *expr = unpack_ast_call_expr_for_builtin(node);
|
||||||
Ast_Type *type = name.type == type_type ? name.type_val : name.type;
|
|
||||||
Value v = value_int(type->align);
|
Operand name = resolve_expr(expr, inherit_flag(flags, AST_CANT_BE_NULL));
|
||||||
rewrite_into_const(node, Ast_Builtin, v);
|
if(!name.is_const){
|
||||||
return operand_const_rvalue(v);
|
compiler_error(node->pos, "size_of requires a constant value");
|
||||||
BREAK();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
CASE(SIZE_OF, Builtin){
|
|
||||||
Operand name = resolve_expr(node->expr, inherit_flag(flags, AST_CANT_BE_NULL));
|
|
||||||
if(!name.is_const) compiler_error(node->pos, "size_of requires a constant value");
|
|
||||||
Ast_Type *type = name.type == type_type ? name.type_val : name.type;
|
Ast_Type *type = name.type == type_type ? name.type_val : name.type;
|
||||||
Value v = value_int(type->size);
|
Value v = value_int(type->size);
|
||||||
rewrite_into_const(node, Ast_Builtin, v);
|
rewrite_into_const(node, Ast_Builtin, v);
|
||||||
return operand_const_rvalue(v);
|
return operand_const_rvalue(v);
|
||||||
BREAK();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
CASE(LENGTH_OF, Builtin){
|
else if(expr_atom_is_equal_intern(node->name, intern_lengthof)){
|
||||||
Operand name = resolve_expr(node->expr, inherit_flag(flags, AST_CANT_BE_NULL));
|
Ast_Expr *expr = unpack_ast_call_expr_for_builtin(node);
|
||||||
|
|
||||||
|
Operand name = resolve_expr(expr, inherit_flag(flags, AST_CANT_BE_NULL));
|
||||||
|
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)){
|
||||||
Value value = value_int(name.type->arr.size);
|
Value value = value_int(name.type->arr.size);
|
||||||
@@ -1239,10 +1257,19 @@ resolve_expr(Ast_Expr *ast, Resolve_Flag flags, Ast_Type *compound_context){
|
|||||||
return operand_rvalue(type_s64);
|
return operand_rvalue(type_s64);
|
||||||
}
|
}
|
||||||
else compiler_error(node->pos, "Can't get length of type %Q", typestring(name.type));
|
else compiler_error(node->pos, "Can't get length of type %Q", typestring(name.type));
|
||||||
BREAK();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
CASE(CALL, Call){
|
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));
|
||||||
|
if(!name.is_const) compiler_error(node->pos, "align_of requires a constant value");
|
||||||
|
Ast_Type *type = name.type == type_type ? name.type_val : name.type;
|
||||||
|
Value v = value_int(type->align);
|
||||||
|
rewrite_into_const(node, Ast_Builtin, v);
|
||||||
|
return operand_const_rvalue(v);
|
||||||
|
}
|
||||||
|
|
||||||
|
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));
|
||||||
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));
|
||||||
@@ -1319,10 +1346,12 @@ resolve_expr(Ast_Expr *ast, Resolve_Flag flags, Ast_Type *compound_context){
|
|||||||
else unset_flag(it->call_flags, CALL_INCLUDED);
|
else unset_flag(it->call_flags, CALL_INCLUDED);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
return operand_rvalue(name.type->func.ret);
|
return operand_rvalue(name.type->func.ret);
|
||||||
//
|
//
|
||||||
// CALL End
|
// CALL End
|
||||||
//
|
//
|
||||||
|
}
|
||||||
BREAK();
|
BREAK();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user