A simple, yet powerful language for WebAssembly.
-[Try Online](https://onyxlang.io/playground) |
-[Read the Wiki](https://github.com/brendanfh/onyx/wiki)
+[Try Online](https://onyxlang.io/playground/) |
+[Read the Wiki](https://github.com/onyx-lang/onyx/wiki)
// This is u64 because padding will make it that anyway.
// Consider: would there be any practical benefit to having the precedence setting
// be a compile-time known value? as opposed to a hardcoded value?
- u64 precedence;
+ u64 order;
AstTyped* option;
};
AstNode *overloaded_function;
// See note in OverloadOption. This could be refactored into an OverloadOption?
- u64 precedence;
+ u64 order;
AstTyped *overload;
};
BinaryOp operator;
- u64 precedence;
+ u64 order;
AstTyped *overload;
};
OnyxToken *group;
} OverloadReturnTypeCheck;
-void add_overload_option(bh_arr(OverloadOption)* poverloads, u64 precedence, AstTyped* overload);
+void add_overload_option(bh_arr(OverloadOption)* poverloads, u64 order, AstTyped* overload);
AstTyped* find_matching_overload_by_arguments(bh_arr(OverloadOption) overloads, Arguments* args);
AstTyped* find_matching_overload_by_type(bh_arr(OverloadOption) overloads, Type* type);
void report_unable_to_match_overload(AstCall* call, bh_arr(OverloadOption) overloads);
expect_token(parser, '{');
- u64 precedence = 0;
+ u64 order = 0;
while (!consume_token_if_next(parser, '}')) {
if (parser->hit_unexpected_token) return ofunc;
- if (parse_possible_directive(parser, "precedence")) {
+ if (parse_possible_directive(parser, "order")) {
AstNumLit* pre = parse_int_literal(parser);
if (parser->hit_unexpected_token) return ofunc;
- precedence = bh_max(pre->value.l, 0);
+ order = bh_max(pre->value.l, 0);
}
AstTyped* option = parse_expression(parser, 0);
- add_overload_option(&ofunc->overloads, precedence++, option);
+ add_overload_option(&ofunc->overloads, order++, option);
if (parser->curr->type != '}')
expect_token(parser, ',');
}
operator_determined:
- if (parse_possible_directive(parser, "precedence")) {
+ if (parse_possible_directive(parser, "order")) {
AstNumLit* pre = parse_int_literal(parser);
if (parser->hit_unexpected_token) return;
- operator->precedence = bh_max(pre->value.l, 0);
+ operator->order = bh_max(pre->value.l, 0);
} else {
- operator->precedence = parser->overload_count++;
+ operator->order = parser->overload_count++;
}
operator->overload = parse_expression(parser, 0);
AstDirectiveAddOverload *add_overload = make_node(AstDirectiveAddOverload, Ast_Kind_Directive_Add_Overload);
add_overload->token = dir_token;
- if (parse_possible_directive(parser, "precedence")) {
+ if (parse_possible_directive(parser, "order")) {
AstNumLit* pre = parse_int_literal(parser);
if (parser->hit_unexpected_token) return;
- add_overload->precedence = bh_max(pre->value.l, 0);
+ add_overload->order = bh_max(pre->value.l, 0);
} else {
- add_overload->precedence = parser->overload_count++;
+ add_overload->order = parser->overload_count++;
}
parser->parse_calls = 0;
}
SYMRES(expression, (AstTyped **) &add_overload->overload);
- add_overload_option(&ofunc->overloads, add_overload->precedence, add_overload->overload);
+ add_overload_option(&ofunc->overloads, add_overload->order, add_overload->overload);
break;
}
return Symres_Error;
}
- add_overload_option(&operator_overloads[operator->operator], operator->precedence, operator->overload);
+ add_overload_option(&operator_overloads[operator->operator], operator->order, operator->overload);
break;
}
// * Resolving an overload from a TypeFunction (so an overloaded procedure can be passed as a parameter)
//
-void add_overload_option(bh_arr(OverloadOption)* poverloads, u64 precedence, AstTyped* overload) {
+void add_overload_option(bh_arr(OverloadOption)* poverloads, u64 order, AstTyped* overload) {
bh_arr(OverloadOption) overloads = *poverloads;
i32 index = -1;
fori (i, 0, bh_arr_length(overloads)) {
- if (overloads[i].precedence > precedence) {
+ if (overloads[i].order > order) {
index = i;
break;
}
if (index < 0) {
bh_arr_push(overloads, ((OverloadOption) {
- .precedence = precedence,
- .option = overload,
+ .order = order,
+ .option = overload,
}));
} else {
bh_arr_insertn(overloads, index, 1);
- overloads[index].precedence = precedence;
- overloads[index].option = overload;
+ overloads[index].order = order;
+ overloads[index].option = overload;
}
*poverloads = overloads;
//
// This is the fallback option for make. It simply allocates a zero-intialized
// element of type T.
- #precedence 1000 (_: ^$T, allocator := context.allocator) -> ^T {
+ #order 1000 (_: ^$T, allocator := context.allocator) -> ^T {
memory :: package core.memory
res := cast(^T) raw_alloc(allocator, sizeof T);
}
delete :: #match {
- #precedence 1000 macro (x: ^$T, allocator := context.allocator) {
+ #order 1000 macro (x: ^$T, allocator := context.allocator) {
if x != null do raw_free(allocator, x);
}
}
// type has the necessary methods.
//
-#overload #precedence 10000
+#overload #order 10000
as_iter :: (x: ^$T/ImplicitIterator) => {
x->iter_open();
return generator_no_copy(x, T.iter_next, T.iter_close);
}
-#overload #precedence 10000
+#overload #order 10000
as_iter :: macro (x: $T/HasAsIter) => x->as_iter();
#local
(key: type_expr) -> u32 { return to_u32(cast(u32) key); },
(key: bool) -> u32 { return 1 if key else 0; },
- #precedence 10000
+ #order 10000
macro (key: $T/HasHashMethod) => key->hash()
}
write_format,
- // Catch all for any type. Has a high precedence so you can easily override it.
- #precedence 1000 macro (w: ^Writer, a: $T) {
+ // Catch all for any type. Has a high order so you can easily override it.
+ #order 1000 macro (w: ^Writer, a: $T) {
write_format :: write_format
write_format(w, "{}", a);
}
}
#if #defined(runtime.vars.Onyx_Enable_Operator_Methods) {
- #operator == #precedence 10000 macro (t: $T, r: $R) -> #auto where __HasEqMethod(T, R) do return T.__eq(t, r);
- #operator != #precedence 10000 macro (t: $T, r: $R) -> #auto where __HasNeMethod(T, R) do return T.__ne(t, r);
- #operator < #precedence 10000 macro (t: $T, r: $R) -> #auto where __HasLtMethod(T, R) do return T.__lt(t, r);
- #operator <= #precedence 10000 macro (t: $T, r: $R) -> #auto where __HasLeMethod(T, R) do return T.__le(t, r);
- #operator > #precedence 10000 macro (t: $T, r: $R) -> #auto where __HasGtMethod(T, R) do return T.__gt(t, r);
- #operator >= #precedence 10000 macro (t: $T, r: $R) -> #auto where __HasGeMethod(T, R) do return T.__ge(t, r);
- #operator + #precedence 10000 macro (t: $T, r: $R) -> #auto where __HasAddMethod(T, R) do return T.__add(t, r);
- #operator - #precedence 10000 macro (t: $T, r: $R) -> #auto where __HasMinusMethod(T, R) do return T.__minus(t, r);
- #operator * #precedence 10000 macro (t: $T, r: $R) -> #auto where __HasMulMethod(T, R) do return T.__mul(t, r);
- #operator / #precedence 10000 macro (t: $T, r: $R) -> #auto where __HasDivMethod(T, R) do return T.__div(t, r);
- #operator % #precedence 10000 macro (t: $T, r: $R) -> #auto where __HasModMethod(T, R) do return T.__mod(t, r);
- #operator & #precedence 10000 macro (t: $T, r: $R) -> #auto where __HasAndMethod(T, R) do return T.__and(t, r);
- #operator | #precedence 10000 macro (t: $T, r: $R) -> #auto where __HasOrMethod(T, R) do return T.__or(t, r);
- #operator << #precedence 10000 macro (t: $T, r: $R) -> #auto where __HasShlMethod(T, R) do return T.__shl(t, r);
- #operator >> #precedence 10000 macro (t: $T, r: $R) -> #auto where __HasShrMethod(T, R) do return T.__shr(t, r);
- #operator >>> #precedence 10000 macro (t: $T, r: $R) -> #auto where __HasSarMethod(T, R) do return T.__sar(t, r);
- #operator ^ #precedence 10000 macro (t: $T, r: $R) -> #auto where __HasXorMethod(T, R) do return T.__xor(t, r);
- #operator && #precedence 10000 macro (t: $T, r: $R) -> #auto where __HasBandMethod(T, R) do return T.__band(t, r);
- #operator || #precedence 10000 macro (t: $T, r: $R) -> #auto where __HasBorMethod(T, R) do return T.__bor(t, r);
- #operator [] #precedence 10000 macro (t: $T, r: $R) -> #auto where __HasSubMethod(T, R) do return T.__sub(t, r);
+ #operator == #order 10000 macro (t: $T, r: $R) -> #auto where __HasEqMethod(T, R) do return T.__eq(t, r);
+ #operator != #order 10000 macro (t: $T, r: $R) -> #auto where __HasNeMethod(T, R) do return T.__ne(t, r);
+ #operator < #order 10000 macro (t: $T, r: $R) -> #auto where __HasLtMethod(T, R) do return T.__lt(t, r);
+ #operator <= #order 10000 macro (t: $T, r: $R) -> #auto where __HasLeMethod(T, R) do return T.__le(t, r);
+ #operator > #order 10000 macro (t: $T, r: $R) -> #auto where __HasGtMethod(T, R) do return T.__gt(t, r);
+ #operator >= #order 10000 macro (t: $T, r: $R) -> #auto where __HasGeMethod(T, R) do return T.__ge(t, r);
+ #operator + #order 10000 macro (t: $T, r: $R) -> #auto where __HasAddMethod(T, R) do return T.__add(t, r);
+ #operator - #order 10000 macro (t: $T, r: $R) -> #auto where __HasMinusMethod(T, R) do return T.__minus(t, r);
+ #operator * #order 10000 macro (t: $T, r: $R) -> #auto where __HasMulMethod(T, R) do return T.__mul(t, r);
+ #operator / #order 10000 macro (t: $T, r: $R) -> #auto where __HasDivMethod(T, R) do return T.__div(t, r);
+ #operator % #order 10000 macro (t: $T, r: $R) -> #auto where __HasModMethod(T, R) do return T.__mod(t, r);
+ #operator & #order 10000 macro (t: $T, r: $R) -> #auto where __HasAndMethod(T, R) do return T.__and(t, r);
+ #operator | #order 10000 macro (t: $T, r: $R) -> #auto where __HasOrMethod(T, R) do return T.__or(t, r);
+ #operator << #order 10000 macro (t: $T, r: $R) -> #auto where __HasShlMethod(T, R) do return T.__shl(t, r);
+ #operator >> #order 10000 macro (t: $T, r: $R) -> #auto where __HasShrMethod(T, R) do return T.__shr(t, r);
+ #operator >>> #order 10000 macro (t: $T, r: $R) -> #auto where __HasSarMethod(T, R) do return T.__sar(t, r);
+ #operator ^ #order 10000 macro (t: $T, r: $R) -> #auto where __HasXorMethod(T, R) do return T.__xor(t, r);
+ #operator && #order 10000 macro (t: $T, r: $R) -> #auto where __HasBandMethod(T, R) do return T.__band(t, r);
+ #operator || #order 10000 macro (t: $T, r: $R) -> #auto where __HasBorMethod(T, R) do return T.__bor(t, r);
+ #operator [] #order 10000 macro (t: $T, r: $R) -> #auto where __HasSubMethod(T, R) do return T.__sub(t, r);
}
{ T.as_str(t) } -> str;
}
-#overload #precedence 10000
+#overload #order 10000
as_str :: macro (t: $T/HasAsStrMethod) -> str {
return T.as_str(t);
}
person_set << .{ "Joe", 38 };
// "Joe" will only be printed once.
- for person: set.iterator(^person_set) {
+ for person: set.as_iter(^person_set) {
println(person);
}
}
// type knowledge at runtime. To rectify this, let's add a new case that makes
// this work for any type:
-#match print_type #precedence 10 (x: $T) {
+#match #order 10 print_type (x: $T) {
printf("Fallback case: called with a {} ({})\n", T, x);
}
-// There are a couple things going on here. The #match directive takes two "parameters": the overloaded procedure to add a match option to, and the option itself. The other
-// thing to notice is the "#precedence 10" specification. Onyx tries to match the arguments you provided
+// There are a couple things going on here. The #match directive takes two "parameters": the overloaded
+// procedure to add a match option to, and the option itself. The other
+// thing to notice is the "#order 10" specification. Onyx tries to match the arguments you provided
// with each of the options. The first one that matches perfectly, is the one that is used. The order in
-// which it does this process is important, and that is why you can control it with the #precedence
-// directive. The #precedence directive is allowed in two places: right before the option in the original
+// which it does this process is important, and that is why you can control it with the #order
+// directive. The #order directive is allowed in two places: right before the option in the original
// #match directive, or in front of the option in an #match directive, as seen above. Currently,
// the options are sorted in ascending order according to the precedence. I feel like this is backwards,
// so that may change in the future. Either way, setting the precedence allows you to place the options
use package core
overloaded :: #match {
- #precedence 10 (x: i32) { println("Option X"); },
- #precedence 5 (y: i32) { println("Option Y"); },
- #precedence 4 (z: i32) { println("Option Z"); },
+ #order 10 (x: i32) { println("Option X"); },
+ #order 5 (y: i32) { println("Option Y"); },
+ #order 4 (z: i32) { println("Option Z"); },
}
main :: (args: [] cstr) {
overloaded(z=10);
}
-#match #precedence 3 overloaded (q: i32) { println("Option Q"); }
-#match #precedence 2 overloaded (r: i32) { println("Option R"); }
-#match #precedence 1 overloaded (m: i32) { println("Option M"); }
+#match #order 3 overloaded (q: i32) { println("Option Q"); }
+#match #order 2 overloaded (r: i32) { println("Option R"); }
+#match #order 1 overloaded (m: i32) { println("Option M"); }