From: Brendan Hansen Date: Sat, 3 Jul 2021 19:50:40 +0000 (-0500) Subject: added #defined() X-Git-Url: https://git.brendanfh.com/?a=commitdiff_plain;h=5bf4ac91290497af456d8e7f9a4990255cce3114;p=onyx.git added #defined() --- diff --git a/bin/onyx b/bin/onyx index 077a57cb..f41b8354 100755 Binary files a/bin/onyx and b/bin/onyx differ diff --git a/include/onyxastnodes.h b/include/onyxastnodes.h index e6fbfed6..0b0d0067 100644 --- a/include/onyxastnodes.h +++ b/include/onyxastnodes.h @@ -34,6 +34,7 @@ NODE(DirectiveAddOverload) \ NODE(DirectiveOperator) \ NODE(DirectiveExport) \ + NODE(DirectiveDefined) \ \ NODE(Return) \ NODE(Jump) \ @@ -180,6 +181,7 @@ typedef enum AstKind { Ast_Kind_Directive_Add_Overload, Ast_Kind_Directive_Operator, Ast_Kind_Directive_Export, + Ast_Kind_Directive_Defined, Ast_Kind_Call_Site, Ast_Kind_Note, @@ -968,6 +970,13 @@ struct AstDirectiveExport { AstTyped* export; }; +struct AstDirectiveDefined { + AstTyped_base; + AstTyped *expr; + + b32 is_defined: 1; +}; + struct AstNote { AstNode_base; }; @@ -1245,6 +1254,7 @@ i64 get_expression_integer_value(AstTyped* node); b32 cast_is_legal(Type* from_, Type* to_, char** err_msg); char* get_function_name(AstFunction* func); +AstNumLit* make_bool_literal(bh_allocator, b32 b); AstNumLit* make_int_literal(bh_allocator a, i64 value); AstNumLit* make_float_literal(bh_allocator a, f64 value); AstRangeLiteral* make_range_literal(bh_allocator a, AstTyped* low, AstTyped* high); diff --git a/src/onyxastnodes.c b/src/onyxastnodes.c index d7d9831c..0571e989 100644 --- a/src/onyxastnodes.c +++ b/src/onyxastnodes.c @@ -83,6 +83,8 @@ static const char* ast_node_names[] = { "ADD OVERLOAD", "OPERATOR OVERLOAD", "EXPORT", + "DEFINED", + "CALL SITE", "NOTE", @@ -719,7 +721,14 @@ char* get_function_name(AstFunction* func) { return ""; } +AstNumLit* make_bool_literal(bh_allocator a, b32 b) { + AstNumLit* bl = onyx_ast_node_new(a, sizeof(AstNumLit), Ast_Kind_NumLit); + bl->flags |= Ast_Flag_Comptime; + bl->type_node = (AstType *) &basic_type_bool; + bl->value.i = b ? 1 : 0; + return bl; +} AstNumLit* make_int_literal(bh_allocator a, i64 i) { AstNumLit* num = onyx_ast_node_new(a, sizeof(AstNumLit), Ast_Kind_NumLit); diff --git a/src/onyxchecker.c b/src/onyxchecker.c index d5ee2837..b7c13d2f 100644 --- a/src/onyxchecker.c +++ b/src/onyxchecker.c @@ -1610,6 +1610,11 @@ CheckStatus check_expression(AstTyped** pexpr) { *pexpr = (AstTyped *) ((AstDirectiveSolidify *) expr)->resolved_proc; break; + case Ast_Kind_Directive_Defined: + *pexpr = (AstTyped *) make_bool_literal(context.ast_alloc, ((AstDirectiveDefined *) expr)->is_defined); + fill_in_type(*pexpr); + break; + case Ast_Kind_Compound: CHECK(compound, (AstCompound *) expr); break; diff --git a/src/onyxparser.c b/src/onyxparser.c index b5c7d61f..e80c64b4 100644 --- a/src/onyxparser.c +++ b/src/onyxparser.c @@ -560,6 +560,7 @@ static AstTyped* parse_factor(OnyxParser* parser) { } else if (parse_possible_directive(parser, "solidify")) { AstDirectiveSolidify* solid = make_node(AstDirectiveSolidify, Ast_Kind_Directive_Solidify); + // :LinearTokenDependent solid->token = parser->curr - 1; solid->poly_proc = (AstPolyProc *) parse_factor(parser); @@ -591,6 +592,19 @@ static AstTyped* parse_factor(OnyxParser* parser) { retval = (AstTyped *) solid; break; } + else if (parse_possible_directive(parser, "defined")) { + AstDirectiveDefined* defined = make_node(AstDirectiveDefined, Ast_Kind_Directive_Defined); + // :LinearTokenDependent + defined->token = parser->curr - 1; + defined->type_node = (AstType *) &basic_type_bool; + + expect_token(parser, '('); + defined->expr = parse_expression(parser, 0); + expect_token(parser, ')'); + + retval = (AstTyped *) defined; + break; + } onyx_report_error(parser->curr->pos, "Invalid directive in expression."); return NULL; diff --git a/src/onyxsymres.c b/src/onyxsymres.c index eb091113..0c416376 100644 --- a/src/onyxsymres.c +++ b/src/onyxsymres.c @@ -43,6 +43,7 @@ static SymresStatus symres_for(AstFor* fornode); static SymresStatus symres_switch(AstSwitch* switchnode); static SymresStatus symres_use(AstUse* use); static SymresStatus symres_directive_solidify(AstDirectiveSolidify** psolid); +static SymresStatus symres_directive_defined(AstDirectiveDefined** pdefined); static SymresStatus symres_statement_chain(AstNode** walker); static SymresStatus symres_statement(AstNode** stmt, b32 *remove); static SymresStatus symres_block(AstBlock* block); @@ -449,6 +450,10 @@ static SymresStatus symres_expression(AstTyped** expr) { SYMRES(directive_solidify, (AstDirectiveSolidify **) expr); break; + case Ast_Kind_Directive_Defined: + SYMRES(directive_defined, (AstDirectiveDefined **) expr); + break; + case Ast_Kind_Compound: SYMRES(compound, (AstCompound *) *expr); break; @@ -709,6 +714,31 @@ static SymresStatus symres_directive_solidify(AstDirectiveSolidify** psolid) { return Symres_Success; } +static SymresStatus symres_directive_defined(AstDirectiveDefined** pdefined) { + AstDirectiveDefined* defined = *pdefined; + + b32 old_report_unresolved_symbols = report_unresolved_symbols; + report_unresolved_symbols = 0; + + SymresStatus ss = symres_expression(&defined->expr); + if (old_report_unresolved_symbols && ss != Symres_Success) { + // The symbol definitely was not found and there is no chance that it could be found. + defined->is_defined = 0; + + } else { + if (ss == Symres_Success) { + defined->is_defined = 1; + + } else { + report_unresolved_symbols = old_report_unresolved_symbols; + return Symres_Yield_Macro; + } + } + + report_unresolved_symbols = old_report_unresolved_symbols; + return Symres_Success; +} + static SymresStatus symres_statement(AstNode** stmt, b32 *remove) { if (remove) *remove = 0; diff --git a/tests/defined_test b/tests/defined_test new file mode 100644 index 00000000..87f8d93a --- /dev/null +++ b/tests/defined_test @@ -0,0 +1,3 @@ +true +false +true diff --git a/tests/defined_test.onyx b/tests/defined_test.onyx new file mode 100644 index 00000000..3cc44f55 --- /dev/null +++ b/tests/defined_test.onyx @@ -0,0 +1,9 @@ +#load "core/std" + +use package core + +main :: (args: [] cstr) { + println(#defined(stdio)); + println(#defined(foobar)); + println(#defined(array.Untyped_Array.foo)); +}