Parsing operator overloads
This commit is contained in:
@@ -64,6 +64,7 @@ enum{
|
||||
AST_GLOBAL = bit_flag(10),
|
||||
AST_FLAG = bit_flag(11),
|
||||
AST_VAR_IS_CONST = bit_flag(12),
|
||||
AST_OPERATOR_OVERLOAD = bit_flag(13),
|
||||
};
|
||||
|
||||
struct Ast{
|
||||
|
||||
@@ -36,11 +36,35 @@ lex_init(Allocator *token_string_arena, Allocator *map_allocator, Lexer *l){
|
||||
intern_sizeof = l->intern("SizeOf"_s);
|
||||
intern_lengthof = l->intern("Length"_s);
|
||||
intern_alignof = l->intern("AlignOf"_s);
|
||||
intern_foreign = intern_string(&l->interns, "foreign"_s);
|
||||
intern_strict = intern_string(&l->interns, "strict"_s);
|
||||
intern_void = intern_string(&l->interns, "void"_s);
|
||||
intern_flag = intern_string(&l->interns, "flag"_s);
|
||||
intern_it = intern_string(&l->interns, "it"_s);
|
||||
intern_foreign = l->intern("foreign"_s);
|
||||
intern_strict = l->intern("strict"_s);
|
||||
intern_void = l->intern("void"_s);
|
||||
intern_flag = l->intern("flag"_s);
|
||||
intern_it = l->intern("it"_s);
|
||||
|
||||
op_add = l->intern("+"_s);
|
||||
op_mul = l->intern("*"_s);
|
||||
op_div = l->intern("/"_s);
|
||||
op_sub = l->intern("-"_s);
|
||||
op_and = l->intern("&&"_s);
|
||||
op_bitand = l->intern("&"_s);
|
||||
op_or = l->intern("||"_s);
|
||||
op_bitor = l->intern("|"_s);
|
||||
op_xor = l->intern("^"_s);
|
||||
op_equals = l->intern("=="_s);
|
||||
op_not_equals = l->intern("!="_s);
|
||||
op_lesser_then_or_equal = l->intern("<="_s);
|
||||
op_greater_then_or_equal = l->intern(">="_s);
|
||||
op_lesser_then = l->intern("<"_s);
|
||||
op_greater_then = l->intern(">"_s);
|
||||
op_left_shift = l->intern("<<"_s);
|
||||
op_right_shift = l->intern(">>"_s);
|
||||
op_not = l->intern("!"_s);
|
||||
op_neg = l->intern("~"_s);
|
||||
op_decrement = l->intern("--"_s);
|
||||
op_increment = l->intern("++"_s);
|
||||
l->first_op = op_add;
|
||||
l->last_op = op_increment;
|
||||
}
|
||||
|
||||
function void
|
||||
|
||||
@@ -142,6 +142,9 @@ struct Lexer{
|
||||
S64 token_iter;
|
||||
U32 token_debug_ids;
|
||||
|
||||
Intern_String first_op;
|
||||
Intern_String last_op ;
|
||||
|
||||
Intern_String intern(String string){
|
||||
return intern_string(&interns, string);
|
||||
}
|
||||
|
||||
@@ -4,6 +4,8 @@ thread_local B32 emit_line_directives;
|
||||
Allocator *bigint_allocator;
|
||||
global S64 bigint_allocation_count;
|
||||
|
||||
global Token token_null = {SAME_SCOPE};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Interns / keywords
|
||||
//-----------------------------------------------------------------------------
|
||||
@@ -32,6 +34,28 @@ Intern_String intern_it;
|
||||
Intern_String intern_strict;
|
||||
Intern_String intern_flag;
|
||||
|
||||
Intern_String op_add;
|
||||
Intern_String op_mul;
|
||||
Intern_String op_div;
|
||||
Intern_String op_sub;
|
||||
Intern_String op_and;
|
||||
Intern_String op_bitand;
|
||||
Intern_String op_or;
|
||||
Intern_String op_bitor;
|
||||
Intern_String op_xor;
|
||||
Intern_String op_equals;
|
||||
Intern_String op_not_equals;
|
||||
Intern_String op_lesser_then_or_equal;
|
||||
Intern_String op_greater_then_or_equal;
|
||||
Intern_String op_lesser_then;
|
||||
Intern_String op_greater_then;
|
||||
Intern_String op_left_shift;
|
||||
Intern_String op_right_shift;
|
||||
Intern_String op_not;
|
||||
Intern_String op_neg;
|
||||
Intern_String op_decrement;
|
||||
Intern_String op_increment;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Type globals
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
@@ -2,7 +2,6 @@ force_inline B32 token_is_assign(Token_Kind token){return token >= TK_FirstAssig
|
||||
force_inline B32 token_is_assign(Token *token){return token_is_assign(token->kind);}
|
||||
force_inline B32 token_is_compare(Token_Kind token){return token >= TK_FirstCompare && token <= TK_LastCompare;}
|
||||
force_inline B32 token_is_compare(Token *token){return token_is_compare(token->kind);}
|
||||
global Token token_null = {SAME_SCOPE};
|
||||
|
||||
function U8
|
||||
lexc(Lex_Stream *s){
|
||||
@@ -73,6 +72,12 @@ lex_is_keyword(Intern_Table *lexer, Intern_String keyword){
|
||||
return result;
|
||||
}
|
||||
|
||||
function B32
|
||||
is_valid_operator_overload(Lexer *lexer, Intern_String op){
|
||||
B32 result = op.str >= lexer->first_op.str && op.str <= lexer->last_op.str;
|
||||
return result;
|
||||
}
|
||||
|
||||
function void
|
||||
token_error(Token *t, String error_val){
|
||||
t->kind = TK_Error;
|
||||
|
||||
@@ -834,12 +834,29 @@ parse_decl(B32 is_global){
|
||||
if(expr->kind == AST_LAMBDA_EXPR){
|
||||
auto a = (Ast_Lambda *)expr;
|
||||
if(a->scope || is_flag_set(flags, AST_FOREIGN)){
|
||||
result->kind = AST_LAMBDA;
|
||||
if(is_flag_set(flags, AST_FOREIGN))
|
||||
set_flag(expr->flags, flags);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if(token_match(TK_StringLit, TK_DoubleColon)){
|
||||
Ast_Lambda *expr = (Ast_Lambda *)parse_expr();
|
||||
if(expr->kind != AST_LAMBDA_EXPR){
|
||||
compiler_error(tname, "Operator overload is required to be a lambda function");
|
||||
}
|
||||
if(!expr->scope){
|
||||
compiler_error(tname, "Operator overload doesn't have body");
|
||||
}
|
||||
|
||||
if(!is_valid_operator_overload(pctx, tname->intern_val)){
|
||||
compiler_error(tname, "This operator cannot be overloaded");
|
||||
}
|
||||
|
||||
result = ast_const(tname, tname->intern_val, expr);
|
||||
result->kind = AST_LAMBDA;
|
||||
}
|
||||
}
|
||||
}
|
||||
result->flags = set_flag(result->flags, AST_OPERATOR_OVERLOAD);
|
||||
}
|
||||
else if(token_match(TK_Identifier, TK_Colon)){
|
||||
Ast_Expr *typespec = parse_expr();
|
||||
|
||||
@@ -737,8 +737,7 @@ make_sure_value_is_compatible_with_type(Token *pos, Operand *expr, Ast_Type *typ
|
||||
}
|
||||
|
||||
#define rewrite_into_const(ast,T,s) _rewrite_into_const(ast,sizeof(T),s)
|
||||
function void
|
||||
_rewrite_into_const(Ast *node, U64 ast_size, Value value){
|
||||
function void _rewrite_into_const(Ast *node, U64 ast_size, Value value){
|
||||
auto ast = (Ast_Atom *)node;
|
||||
assert(ast_size >= sizeof(Ast_Atom));
|
||||
set_flag(ast->flags, AST_ATOM);
|
||||
|
||||
@@ -6,7 +6,8 @@ Vec2I :: struct;; x: S64; y: S64
|
||||
Vec2 :: struct;; x: F32; y: F32
|
||||
Vec3 :: struct;; x: F32; y: F32; z: F32
|
||||
|
||||
|
||||
"+" :: (a: Vec3, b: Vec3): Vec3
|
||||
return Vec3_Add(a,b)
|
||||
|
||||
Vec3_Cross :: (a: Vec3, b: Vec3): Vec3
|
||||
result := Vec3{
|
||||
|
||||
Reference in New Issue
Block a user