NODE(DirectiveOperator) \
NODE(DirectiveExport) \
NODE(DirectiveDefined) \
+ NODE(DirectiveTag) \
\
NODE(Return) \
NODE(Jump) \
Ast_Kind_Directive_Operator,
Ast_Kind_Directive_Export,
Ast_Kind_Directive_Defined,
+ Ast_Kind_Directive_Tag,
Ast_Kind_Call_Site,
Ast_Kind_Code_Block,
b32 is_defined: 1;
};
+struct AstDirectiveTag {
+ AstNode_base;
+
+ AstTyped* expr;
+ AstTyped* tag;
+};
+
struct AstNote {
AstNode_base;
};
"OPERATOR OVERLOAD",
"EXPORT",
"DEFINED",
+ "TAG",
"CALL SITE",
"CODE BLOCK",
YIELD(directive->token->pos, "Waiting for export type to be known.");
}
+ if (directive->kind == Ast_Kind_Directive_Tag) {
+ AstDirectiveTag *tag = (AstDirectiveTag *) directive;
+
+ CHECK(expression, &tag->tag);
+
+ switch (tag->expr->kind) {
+ case Ast_Kind_Struct_Type: {
+ AstStructType* st = (AstStructType *) tag->expr;
+
+ if (st->meta_tags == NULL) bh_arr_new(global_heap_allocator, st->meta_tags, 1);
+ bh_arr_push(st->meta_tags, tag->tag);
+
+ return Check_Complete;
+ }
+
+ case Ast_Kind_Field_Access: {
+ AstFieldAccess* fa = (AstFieldAccess *) tag->expr;
+
+ if (fa->expr->kind == Ast_Kind_Struct_Type) {
+ AstStructType* st = (AstStructType *) fa->expr;
+ Type* s_type = type_build_from_ast(context.ast_alloc, (AstType *) st);
+
+ bh_arr_each(AstStructMember *, smem, st->members) {
+ if (token_equals((*smem)->token, fa->token)) {
+ bh_arr(AstTyped *) tags = (*smem)->meta_tags;
+
+ if (tags == NULL) bh_arr_new(global_heap_allocator, tags, 1);
+ bh_arr_push(tags, tag->tag);
+
+ (*smem)->meta_tags = tags;
+
+ bh_arr_each(StructMember *, smem_type, s_type->Struct.memarr) {
+ if (token_text_equals((*smem)->token, (*smem_type)->name)) {
+ (*smem_type)->meta_tags = tags;
+ break;
+ }
+ }
+
+ return Check_Complete;
+ }
+ }
+
+ onyx_report_error(fa->token->pos, "'%b' is not a member of '%s'.",
+ fa->token->text, fa->token->length,
+ st->name);
+ return Check_Error;
+ }
+ }
+
+ default: {
+ onyx_report_error(tag->token->pos, "Cannot tag this.");
+ return Check_Error;
+ }
+ }
+ }
+
return Check_Success;
}
case Ast_Kind_Directive_Export:
case Ast_Kind_Directive_Add_Overload:
+ case Ast_Kind_Directive_Tag:
case Ast_Kind_Directive_Operator: {
ent.type = Entity_Type_Process_Directive;
ent.expr = (AstTyped *) node;
} else {
bh_arr(AstTyped *) meta_tags=NULL;
- while (parse_possible_directive(parser, "tag")) {
- expect_token(parser, '(');
+ while (parser->curr->type == '[') {
+ expect_token(parser, '[');
AstTyped* expr = parse_expression(parser, 0);
if (meta_tags == NULL) bh_arr_new(global_heap_allocator, meta_tags, 1);
bh_arr_push(meta_tags, expr);
- expect_token(parser, ')');
+ expect_token(parser, ']');
}
bh_arr_clear(member_list_temp);
ENTITY_SUBMIT(export);
return;
}
+ else if (parse_possible_directive(parser, "tag")) {
+ AstDirectiveTag *tag = make_node(AstDirectiveTag, Ast_Kind_Directive_Tag);
+ tag->token = dir_token;
+
+ tag->expr = parse_expression(parser, 0);
+ expect_token(parser, ',');
+ tag->tag = parse_expression(parser, 0);
+
+ ENTITY_SUBMIT(tag);
+ return;
+ }
else {
OnyxToken* directive_token = expect_token(parser, '#');
OnyxToken* symbol_token = expect_token(parser, Token_Type_Symbol);
break;
}
+
+ case Ast_Kind_Directive_Tag: {
+ AstDirectiveTag *tag = (AstDirectiveTag *) directive;
+ SYMRES(expression, &tag->tag);
+ SYMRES(expression, &tag->expr);
+ break;
+ }
}
return Symres_Success;