bh_arr(InterfaceParam) params;
bh_arr(InterfaceConstraint) exprs;
+ Scope *scope;
+
b32 is_intrinsic: 1;
};
}
assert(constraint->interface->entity && constraint->interface->entity->scope);
+ assert(constraint->interface->scope);
+ assert(constraint->interface->scope->parent == constraint->interface->entity->scope);
- constraint->scope = scope_create(context.ast_alloc, constraint->interface->entity->scope, constraint->token->pos);
+ constraint->scope = scope_create(context.ast_alloc, constraint->interface->scope, constraint->token->pos);
if (bh_arr_length(constraint->type_args) != bh_arr_length(constraint->interface->params)) {
ERROR_(constraint->token->pos, "Wrong number of arguments given to interface. Expected %d, got %d.",
bh_arr_new(global_heap_allocator, interface->exprs, 2);
+ type_create_scope(parser, &interface->scope, interface->token);
+ parser->current_scope = interface->scope;
+
expect_token(parser, '{');
while (!consume_token_if_next(parser, '}')) {
if (parser->hit_unexpected_token) return interface;
+ if (next_tokens_are(parser, 3, Token_Type_Symbol, ':', ':')) {
+ OnyxToken* binding_name = expect_token(parser, Token_Type_Symbol);
+ consume_token(parser);
+
+ AstBinding* binding = parse_top_level_binding(parser, binding_name);
+ if (binding) ENTITY_SUBMIT(binding);
+
+ consume_token_if_next(parser, ';');
+ continue;
+ }
+
InterfaceConstraint ic = {0};
if (parse_possible_directive(parser, "not")) {
ic.invert_condition = 1;
expect_token(parser, ';');
}
+ parser->current_scope = parser->current_scope->parent;
return interface;
}
expr->kind == Ast_Kind_Enum_Type ||
expr->kind == Ast_Kind_Type_Raw_Alias ||
expr->kind == Ast_Kind_Union_Type ||
- expr->kind == Ast_Kind_Poly_Union_Type) {
-
+ expr->kind == Ast_Kind_Poly_Union_Type ||
+ expr->kind == Ast_Kind_Interface) {
force_a_lookup = 1;
}
AstDistinctType* dtype = (AstDistinctType *) node;
return symbol_raw_resolve(dtype->scope, symbol);
}
+
+ case Ast_Kind_Interface: {
+ AstInterface* inter = (AstInterface *) node;
+ return symbol_raw_resolve(inter->scope, symbol);
+ }
}
return NULL;
AstDistinctType* dtype = (AstDistinctType *) node;
return &dtype->scope;
}
+
+ case Ast_Kind_Interface: {
+ AstInterface* inter = (AstInterface *) node;
+ return &inter->scope;
+ }
}
return NULL;
--- /dev/null
+Woof! Message 1
+Woof! Another message!
+Woof! Such cool message!
+WOOF! YELL THIS.
+Meow! Message 1
+Meow! Another message!
+Meow! Such cool message!
+MEOW! Yell this.
--- /dev/null
+use core {*}
+
+Speak :: interface (t: $T) {
+ { speak(t, str.{}) } -> void;
+ { yell(t, str.{}) } -> void;
+
+ speak :: #match {}
+}
+
+#inject Speak {
+ yell :: #match {}
+}
+
+Dog :: struct {_: i32}
+
+#overload
+Speak.speak :: (d: Dog, msg: str) {
+ printf("Woof! {}\n", msg);
+}
+
+#overload
+Speak.yell :: (d: Dog, msg: str) {
+ printf("WOOF! {}\n", string.temp_copy(msg) |> string.to_uppercase());
+}
+
+Cat :: struct {_: i32}
+
+#overload
+Speak.speak :: (d: Cat, msg: str) {
+ printf("Meow! {}\n", msg);
+}
+
+#overload
+Speak.yell :: (d: Cat, msg: str) {
+ printf("MEOW! {}\n", msg);
+}
+
+
+speak_things :: (thing: $T/Speak) {
+ Speak.speak(thing, "Message 1");
+ Speak.speak(thing, "Another message!");
+ Speak.speak(thing, "Such cool message!");
+
+ Speak.yell(thing, "Yell this.");
+}
+
+
+main :: () {
+ dog := Dog.{};
+ cat := Cat.{};
+
+ speak_things(dog);
+ speak_things(cat);
+}
\ No newline at end of file