NODE(DirectiveAddOverload) \
NODE(DirectiveOperator) \
NODE(DirectiveExport) \
+ NODE(DirectiveDefined) \
\
NODE(Return) \
NODE(Jump) \
Ast_Kind_Directive_Add_Overload,
Ast_Kind_Directive_Operator,
Ast_Kind_Directive_Export,
+ Ast_Kind_Directive_Defined,
Ast_Kind_Call_Site,
Ast_Kind_Note,
AstTyped* export;
};
+struct AstDirectiveDefined {
+ AstTyped_base;
+ AstTyped *expr;
+
+ b32 is_defined: 1;
+};
+
struct AstNote {
AstNode_base;
};
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);
"ADD OVERLOAD",
"OPERATOR OVERLOAD",
"EXPORT",
+ "DEFINED",
+ "CALL SITE",
"NOTE",
return "<anonymous procedure>";
}
+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);
*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;
}
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);
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;
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);
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;
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;
--- /dev/null
+true
+false
+true
--- /dev/null
+#load "core/std"
+
+use package core
+
+main :: (args: [] cstr) {
+ println(#defined(stdio));
+ println(#defined(foobar));
+ println(#defined(array.Untyped_Array.foo));
+}