fi
}
+if command -v wasmer >/dev/null; then
+ printf "Using $(wasmer --version)\n"
+else
+ printf "Using $(node --verison)\n"
+fi
+
failed=0
for test_file in $(find tests/ -name '*.onyx'); do
filename=$(basename -- "$test_file")
print_check "$name"
- if ! ./bin/onyx -r js --use-post-mvp-features "$test_file" -o "./tests/$name.wasm" >/dev/null; then
- printf "\n❌ Failed to compile $name.onyx.\n"
- failed=1
- continue
- fi
-
- if ! ./bin/onyx-js "./tests/$name.wasm" > ./tmpoutput; then
- printf "\n❌ Failed to run $name.onyx.\n"
- failed=1
- continue
+ if command -v wasmer >/dev/null; then
+ if ! ./bin/onyx --use-post-mvp-features "$test_file" -o "./tests/$name.wasm" >/dev/null; then
+ printf "\n❌ Failed to compile $name.onyx.\n"
+ failed=1
+ continue
+ fi
+
+ if ! wasmer "./tests/$name.wasm" > ./tmpoutput; then
+ printf "\n❌ Failed to run $name.onyx.\n"
+ failed=1
+ continue
+ fi
+ else
+ if ! ./bin/onyx -r js --use-post-mvp-features "$test_file" -o "./tests/$name.wasm" >/dev/null; then
+ printf "\n❌ Failed to compile $name.onyx.\n"
+ failed=1
+ continue
+ fi
+
+ if ! ./bin/onyx-js "./tests/$name.wasm" > ./tmpoutput; then
+ printf "\n❌ Failed to run $name.onyx.\n"
+ failed=1
+ continue
+ fi
fi
if ! diff ./tmpoutput "$dirname/$name" >/dev/null; then
count: i32;
}
-vararg_get :: proc {
+vararg_get :: #match {
(va: vararg, ret: ^$T) -> bool {
if va.count <= 0 do return false;
*ret = *cast(^T) va.data;
}
// Uses '==' to compare for equality.
-contains :: proc {
+contains :: #match {
(arr: ^[..] $T, x: T) -> bool {
for it: *arr do if it == x do return true;
return false;
}
// Uses '+' to sum.
-sum :: proc {
+sum :: #match {
(arr: ^[..] $T, start: T = 0) -> T {
sum := start;
for it: *arr do sum += it;
}
}
-product :: proc {
+product :: #match {
(arr: ^[..] $T, start: T = 1) -> T {
sum := start;
for it: *arr do sum *= it;
** Simple insertion sort
** cmp should return >0 if left > right
*/
-sort :: proc {
+sort :: #match {
(arr: ^[..] $T, cmp: (T, T) -> i32) {
for i: 1 .. arr.count {
x := arr.data[i];
}
}
-fold :: proc {
+fold :: #match {
(arr: ^[..] $T, init: $R, f: (T, R) -> R) -> R {
val := init;
for it: *arr do val = f(it, val);
}
}
-map :: proc {
+map :: #match {
(arr: ^[..] $T, f: (^T) -> void) do for ^it: *arr do f(it);,
(arr: ^[..] $T, f: (T) -> T) do for ^it: *arr do *it = f(*it);,
(arr: ^[..] $T, data: $R, f: (^T, R) -> void) do for ^it: *arr do f(it, data);,
return null;
}
-count_where :: proc {
+count_where :: #match {
(arr: ^[..] $T, predicate: (T) -> bool) -> u32 {
count: u32 = 0;
for ^it: *arr do if predicate(*it) do count += 1;
#private_file cmp_greater :: (x: $T, y: T) -> bool do return x > y;
#private_file cmp_less :: (x: $T, y: T) -> bool do return x < y;
-greatest :: proc {
+greatest :: #match {
(arr: [..] $T) -> (i32, T) { return fold_idx_elem(arr.data, arr.count, cmp_greater); },
(arr: [] $T) -> (i32, T) { return fold_idx_elem(arr.data, arr.count, cmp_greater); },
(arr: [$N] $T) -> (i32, T) { return fold_idx_elem(cast(^T) arr, N, cmp_greater); },
}
-least :: proc {
+least :: #match {
(arr: [..] $T) -> (i32, T) { return fold_idx_elem(arr.data, arr.count, cmp_less); },
(arr: [] $T) -> (i32, T) { return fold_idx_elem(arr.data, arr.count, cmp_less); },
(arr: [$N] $T) -> (i32, T) { return fold_idx_elem(cast(^T) arr, N, cmp_less); },
return val;
}
-map :: proc {
- (list: ^List($T), f: (^T) -> void) {
- }
-}
+// map :: #match {
+// (list: ^List($T), f: (^T) -> void) {
+// }
+// }
get_iterator :: (list: ^List($T)) -> Iterator(T) {
iterator_next :: ($T: type_expr, data: rawptr) -> (T, bool) {
package core.hash
-to_u32 :: proc {
+to_u32 :: #match {
(key: rawptr) -> u32 { return 0xcbf29ce7 ^ cast(u32) key; },
(key: i32) -> u32 { return 0xcbf29ce7 ^ cast(u32) key; },
(key: i64) -> u32 { return cast(u32) (cast(u64) 0xcbf29ce7 ^ cast(u64) key); },
return data[0 .. size];
}
-get_contents :: proc {
+get_contents :: #match {
get_contents_from_file,
(path: str) -> str {
write_str(writer, conv.str_format_va(format, buffer[0 .. 2048], va));
}
-write :: proc {
+write :: #match {
write_str, write_cstr,
write_i32, write_f32,
write_i64, write_f64,
// which if it is an integer, will be 2! This should always return a floating point number!
exp :: (p: $T) -> T do return pow(base = cast(T) E, p = p);
-pow :: proc {
+pow :: #match {
// Fast implementation of power when raising to an integer power.
(base: $T, p: i32) -> T {
if base == 0 do return 0;
// they would be however, the fact that these overloads are intrinsic means they cannot
// be reference from the element section and therefore cannot be passed around or used
// as values.
-max :: proc { wasm.max_f32, wasm.max_f64, max_poly }
+max :: #match { wasm.max_f32, wasm.max_f64, max_poly }
max_poly :: (a: $T, b: T) -> T {
if a >= b do return a;
else do return b;
}
-min :: proc { wasm.min_f32, wasm.min_f64, min_poly }
+min :: #match { wasm.min_f32, wasm.min_f64, min_poly }
min_poly :: (a: $T, b: T) -> T {
if a <= b do return a;
else do return b;
return v;
}
-sqrt :: proc { wasm.sqrt_f32, wasm.sqrt_f64, sqrt_poly }
+sqrt :: #match { wasm.sqrt_f32, wasm.sqrt_f64, sqrt_poly }
sqrt_poly :: (x: $T) -> T {
return ~~ wasm.sqrt_f64(~~ x);
}
-abs :: proc { wasm.abs_f32, wasm.abs_f64, abs_poly }
+abs :: #match { wasm.abs_f32, wasm.abs_f64, abs_poly }
abs_poly :: (x: $T) -> T {
if x >= 0 do return x;
else do return -x;
return 0;
}
-copysign :: proc { wasm.copysign_f32, wasm.copysign_f64, copysign_poly }
+copysign :: #match { wasm.copysign_f32, wasm.copysign_f64, copysign_poly }
copysign_poly :: (x: $T, y: T) -> T {
return abs(x) * sign(y);
}
// Floating point rounding
//
-ceil :: proc { wasm.ceil_f32, wasm.ceil_f64 }
-floor :: proc { wasm.floor_f32, wasm.floor_f64 }
-trunc :: proc { wasm.trunc_f32, wasm.trunc_f64 }
-nearest :: proc { wasm.nearest_f32, wasm.nearest_f64 }
+ceil :: #match { wasm.ceil_f32, wasm.ceil_f64 }
+floor :: #match { wasm.floor_f32, wasm.floor_f64 }
+trunc :: #match { wasm.trunc_f32, wasm.trunc_f64 }
+nearest :: #match { wasm.nearest_f32, wasm.nearest_f64 }
// Integer operations
//
-clz :: proc { wasm.clz_i32, wasm.clz_i64 }
-ctz :: proc { wasm.ctz_i32, wasm.ctz_i64 }
-popcnt :: proc { wasm.popcnt_i32, wasm.popcnt_i64 }
-rotate_left :: proc { wasm.rotl_i32, wasm.rotl_i64 }
-rotate_right :: proc { wasm.rotr_i32, wasm.rotr_i64 }
+clz :: #match { wasm.clz_i32, wasm.clz_i64 }
+ctz :: #match { wasm.ctz_i32, wasm.ctz_i64 }
+popcnt :: #match { wasm.popcnt_i32, wasm.popcnt_i64 }
+rotate_left :: #match { wasm.rotl_i32, wasm.rotl_i64 }
+rotate_right :: #match { wasm.rotr_i32, wasm.rotr_i64 }
};
}
-align :: proc {
+align :: #match {
(size: ^u64, align: u64) {
if *size % align != 0 {
*size += align - (*size % align);
auto_flush_stdio := true
-print :: proc {
+print :: #match {
(x: str) {
io.write(^print_writer, x);
if x[x.count - 1] == #char "\n" && auto_flush_stdio do __flush_stdio();
}
// This works on both slices and arrays
-print_array :: proc {
+print_array :: #match {
(arr: [$N] $T, sep := " ") {
for i: 0 .. N {
print(arr[i]);
free :: (s: str, allocator := context.allocator) do raw_free(allocator, s.data);
-length :: proc {
+length :: #match {
(s: str) -> u32 {
return s.count;
},
},
}
-concat :: proc {
+concat :: #match {
(s1: str, s2: str, allocator := context.allocator) -> str {
len1 := length(s1);
len2 := length(s2);
return strarr[0 .. delim_count + 1];
}
-contains :: proc {
+contains :: #match {
(s: str, c: u8) -> bool {
for ch: s do if ch == c do return true;
return false;
}
-strip_leading_whitespace :: proc {
+strip_leading_whitespace :: #match {
(s: ^str) {
while true do switch s.data[0] {
case #char " ", #char "\t", #char "\n", #char "\r" {
},
}
-strip_trailing_whitespace :: proc {
+strip_trailing_whitespace :: #match {
(s: ^str) {
while true do switch s.data[s.count - 1] {
case #char " ", #char "\t", #char "\n", #char "\r" {
},
}
-trim_start :: proc {
+trim_start :: #match {
(s: ^str, char: u8) {
while s.data[0] == char {
s.data += 1;
}
}
-trim_end :: proc {
+trim_end :: #match {
(s: ^str, char: u8) {
while s.data[s.count - 1] == char {
s.count -= 1;
}
}
-advance :: proc {
+advance :: #match {
(s: ^str, chars := 1) {
chars = math.min(chars, s.count);
data : [..] u8;
}
-make :: proc (initial_cap := 4, alloc := context.allocator) -> Builder {
+make :: (initial_cap := 4, alloc := context.allocator) -> Builder {
builder : Builder;
array.init(^builder.data, initial_cap, allocator = alloc);
return builder;
}
-clear :: proc (use sb: ^Builder) -> ^Builder {
+clear :: (use sb: ^Builder) -> ^Builder {
data.count = 0;
return sb;
}
-add_str :: proc (use sb: ^Builder, s: str) -> ^Builder {
+add_str :: (use sb: ^Builder, s: str) -> ^Builder {
len_total := data.count + s.count;
if data.capacity < len_total {
return sb;
}
-add_cstr :: proc (use sb: ^Builder, cstring: cstr) -> ^Builder {
+add_cstr :: (use sb: ^Builder, cstring: cstr) -> ^Builder {
s := string.from_cstr(cstring);
return add_str(sb, s);
}
-add_i64 :: proc (use sb: ^Builder, n: i64, base: u64 = 10) -> ^Builder {
+add_i64 :: (use sb: ^Builder, n: i64, base: u64 = 10) -> ^Builder {
buf : [256] u8;
s := conv.i64_to_str(n, base, buf[0 .. 256]);
return add_str(sb, s);
}
-add_f64 :: proc (use sb: ^Builder, f: f64) -> ^Builder {
+add_f64 :: (use sb: ^Builder, f: f64) -> ^Builder {
buf : [256] u8;
s := conv.f64_to_str(f, buf[0 .. 256]);
return add_str(sb, s);
}
-add_bool :: proc (use sb: ^Builder, b: bool) -> ^Builder {
+add_bool :: (use sb: ^Builder, b: bool) -> ^Builder {
if b do return add_str(sb, "true");
else do return add_str(sb, "false");
return sb;
}
-append :: proc {
+append :: #match {
add_str,
add_cstr,
add_i64,
add_bool,
}
-to_str :: proc (use sb: ^Builder) -> str {
+to_str :: (use sb: ^Builder) -> str {
return str.{ data.data, data.count };
}
original_str : str;
}
-make :: proc (s: str) -> String_Reader {
+make :: (s: str) -> String_Reader {
reader : String_Reader;
init(^reader, s);
return reader;
}
-init :: proc (use reader: ^String_Reader, orig_str: str) {
+init :: (use reader: ^String_Reader, orig_str: str) {
original_str = orig_str;
data = original_str.data;
count = original_str.count;
}
-reset :: proc (use reader: ^String_Reader) {
+reset :: (use reader: ^String_Reader) {
data = original_str.data;
count = original_str.count;
}
-empty :: proc (use reader: ^String_Reader) -> bool do return count == 0;
+empty :: (use reader: ^String_Reader) -> bool do return count == 0;
-read_u32 :: proc (use reader: ^String_Reader) -> u32 {
+read_u32 :: (use reader: ^String_Reader) -> u32 {
n: u32 = 0;
skip_whitespace(reader);
return n;
}
-read_u64 :: proc (use reader: ^String_Reader) -> u64 {
+read_u64 :: (use reader: ^String_Reader) -> u64 {
n: u64 = 0;
skip_whitespace(reader);
return n;
}
-read_byte :: proc (use reader: ^String_Reader) -> u8 {
+read_byte :: (use reader: ^String_Reader) -> u8 {
if count == 0 do return #char "\0";
defer {
return data[0];
}
-read_bytes :: proc (use reader: ^String_Reader, byte_count := 1) -> str {
+read_bytes :: (use reader: ^String_Reader, byte_count := 1) -> str {
bc := byte_count;
if count < bc do bc = count;
return str.{ data, bc };
}
-read_line :: proc (use reader: ^String_Reader) -> str {
+read_line :: (use reader: ^String_Reader) -> str {
out : str;
out.data = data;
out.count = 0;
return out;
}
-read_until :: proc (use reader: ^String_Reader, skip: u32, uptos: ..u8) -> str {
+read_until :: (use reader: ^String_Reader, skip: u32, uptos: ..u8) -> str {
if count == 0 do return str.{ null, 0 };
out : str;
}
// Reads a continuous string of alphabetic chars along with underscores '_'
-read_word :: proc (use reader: ^String_Reader) -> str {
+read_word :: (use reader: ^String_Reader) -> str {
if count == 0 do return str.{ null, 0 };
out := str.{ data, 0 };
return out;
}
-advance_line :: proc (use reader: ^String_Reader) {
+advance_line :: (use reader: ^String_Reader) {
if count == 0 do return;
adv := 0;
}
-skip_whitespace :: proc (use reader: ^String_Reader) {
+skip_whitespace :: (use reader: ^String_Reader) {
while count > 0 do switch data[0] {
case #char " ", #char "\t", #char "\n", #char "\r" {
data += 1;
}
}
-skip_bytes :: proc (use reader: ^String_Reader, byte_count := 1) {
+skip_bytes :: (use reader: ^String_Reader, byte_count := 1) {
bc := byte_count;
if count < bc do bc = count;
-starts_with :: proc (use reader: ^String_Reader, s: str) -> bool {
+starts_with :: (use reader: ^String_Reader, s: str) -> bool {
if count < s.count do return false;
while i := 0; i < s.count {
if data[i] != s[i] do return false;
return ~~output_time;
}
-sleep :: proc {
+sleep :: #match {
(seconds: u64) { sleep(nanoseconds=seconds * 1000000000); },
(milliseconds: u64) { sleep(nanoseconds=milliseconds * 1000000); },
void onyx_errors_init(bh_arr(bh_file_contents)* files);
void onyx_report_error(OnyxFilePos pos, char * format, ...);
+void onyx_report_warning(OnyxFilePos pos, char* format, ...);
void onyx_errors_print();
b32 onyx_has_errors();
void onyx_clear_errors();
# strings in YAML. When using single quoted strings, only single quotes
# need to be escaped: this is done by using two single quotes next to each
# other.
- - match: '\b(package|struct|proc|use|global|enum|if|elseif|else|for|while|do|break|continue|fallthrough|return|as|cast|sizeof|alignof|defer|switch|case)\b'
+ - match: '\b(package|struct|use|global|enum|if|elseif|else|for|while|do|break|continue|fallthrough|return|as|cast|sizeof|alignof|defer|switch|case)\b'
scope: keyword.control.onyx
- match: '\b(bool|void|i8|u8|i16|u16|i32|u32|i64|u64|f32|f64|rawptr|str|cstr|range|type_expr)\b'
- match: '\$[a-zA-Z0-9_]+'
scope: constant.other.onyx
- - match: '([a-zA-Z_][a-zA-Z0-9_]*)\s*::\s*(proc)'
+ - match: '([a-zA-Z_][a-zA-Z0-9_]*)\s*::\s*(#match)'
captures:
1: entity.name.function
- 2: keyword.control.onyx
+ 2: keyword.other.onyx
- match: '([a-zA-Z_][a-zA-Z0-9_]*)\s*::\s*\('
captures:
vertex_count = 0;
}
- push_vertex :: proc {
+ push_vertex :: #match {
// If a color is not provided, the previous color is used.
(use ir: ^Immediate_Renderer, position: Vector2) {
push_vertex(ir, position, color = verticies[vertex_count - 1].color);
Immediate_Renderer.free(^immediate_renderer);
}
-vertex :: proc {
+vertex :: #match {
(position: Vector2) { immediate_renderer->push_vertex(position); },
(position: Vector2, color: Color4) { immediate_renderer->push_vertex(position, color); },
}
return v_arr.array_[idx];
}
-free :: proc {
+free :: #match {
(v: ^Value, allocator: Allocator) do switch v.type {
case .String {
v_str := cast(^Value_String) v;
}
#private_file
-adjust_slider_value :: proc {
+adjust_slider_value :: #match {
@Incomplete // the step parameter is ignored.
// Integers need to be
(value: ^i32, x: f32, width: f32, min_value: i32, max_value: i32) {
// UI Flow
Flow :: struct {
- split_vertical :: proc {
+ split_vertical :: #match {
(r: Rectangle, left_percent: f32, padding := 0.0f) -> (left: Rectangle, right: Rectangle) {
return split_vertical(r, left_width=left_percent * Rectangle.width(r), padding=padding);
},
}
- split_horizontal :: proc {
+ split_horizontal :: #match {
(r: Rectangle, top_percent: f32, padding := 0.0f) -> (top: Rectangle, bottom: Rectangle) {
return split_horizontal(r, top_height=top_percent * Rectangle.height(r), padding=padding);
},
gl.bindTexture(gl.TEXTURE_2D, -1);
}
-draw_rect :: proc {
+draw_rect :: #match {
(use r: Rectangle, color := gfx.Color4.{1,1,1}) {
gfx.set_texture();
return a.x == b.x && a.y == b.y;
}
-#add_overload io.write, vector2_write
+#add_match io.write, vector2_write
vector2_write :: (writer: ^io.Writer, v: Vector2($T)) {
io.write(writer, "Vector2(");
io.write(writer, v.x);
blitFramebuffer :: (sx0: GLint, sy0: GLint, sx1: GLint, sy1: GLint, dx0: GLint, dy0: GLint, dx1: GLint, dy1: GLint, mask: GLbitfield, filter: GLenum) -> void #foreign "gl" "blitFramebuffer" ---
bufferDataWithData :: (target: GLenum, buffer: [] void, usage: GLenum) -> void #foreign "gl" "bufferDataWithData" ---
bufferDataNoData :: (target: GLenum, size: GLsizei, usage: GLenum) -> void #foreign "gl" "bufferDataNoData" ---
-bufferData :: proc { bufferDataWithData, bufferDataNoData }
+bufferData :: #match { bufferDataWithData, bufferDataNoData }
bufferSubData :: (target: GLenum, offset: GLsizei, data: [] void) -> void #foreign "gl" "bufferSubData" ---
canvasSize :: (width: GLsizei, height: GLsizei) -> void #foreign "gl" "canvasSize" ---
checkFrameBufferStatus :: (target: GLenum) -> GLenum #foreign "gl" "checkFrameBufferStatus" ---
bh_arr_new(global_heap_allocator, errors.errors, 4);
}
-void onyx_report_error(OnyxFilePos pos, char * format, ...) {
-
- va_list vargs;
- va_start(vargs, format);
- char* msg = bh_bprintf_va(format, vargs);
- va_end(vargs);
-
- OnyxError err = {
- .pos = pos,
- .text = bh_strdup(errors.msg_alloc, msg),
- };
-
- bh_arr_push(errors.errors, err);
-}
-
static void print_detailed_message(OnyxError* err, bh_file_contents* fc) {
bh_printf("(%s:%l,%l) %s\n", err->pos.filename, err->pos.line, err->pos.column, err->text);
void onyx_clear_errors() {
bh_printf("ERRORS WERE CLEARED!!!\n");
bh_arr_set_length(errors.errors, 0);
-}
\ No newline at end of file
+}
+
+void onyx_report_error(OnyxFilePos pos, char * format, ...) {
+
+ va_list vargs;
+ va_start(vargs, format);
+ char* msg = bh_bprintf_va(format, vargs);
+ va_end(vargs);
+
+ OnyxError err = {
+ .pos = pos,
+ .text = bh_strdup(errors.msg_alloc, msg),
+ };
+
+ bh_arr_push(errors.errors, err);
+}
+
+void onyx_report_warning(OnyxFilePos pos, char* format, ...) {
+ va_list vargs;
+ va_start(vargs, format);
+ char* msg = bh_bprintf_va(format, vargs);
+ va_end(vargs);
+
+ OnyxError err = {
+ .pos = pos,
+ .text = msg,
+ };
+
+ bh_file_contents file_contents = { 0 };
+ bh_arr_each(bh_file_contents, fc, *errors.file_contents) {
+ if (!strcmp(fc->filename, pos.filename)) {
+ file_contents = *fc;
+ break;
+ }
+ }
+
+ print_detailed_message(&err, &file_contents);
+}
case Token_Type_Keyword_Proc: {
OnyxToken* proc_token = expect_token(parser, Token_Type_Keyword_Proc);
+ onyx_report_warning(proc_token->pos, "Warning: 'proc' is a deprecated keyword.");
retval = (AstTyped *) parse_function_definition(parser, proc_token);
break;
}
case Token_Type_Keyword_Proc: {
OnyxToken* proc_token = expect_token(parser, Token_Type_Keyword_Proc);
+ onyx_report_warning(proc_token->pos, "Warning: 'proc' is a deprecated keyword.");
*next_insertion = parse_function_type(parser, proc_token);
next_insertion = NULL;
break;
return;
}
-static AstFunction* parse_function_definition(OnyxParser* parser, OnyxToken* token) {
- if (consume_token_if_next(parser, '{')) {
- AstOverloadedFunction* ofunc = make_node(AstOverloadedFunction, Ast_Kind_Overloaded_Function);
- ofunc->token = token;
- ofunc->flags |= Ast_Flag_Comptime;
+static AstOverloadedFunction* parse_overloaded_function(OnyxParser* parser, OnyxToken* token) {
+ expect_token(parser, '{');
- bh_arr_new(global_heap_allocator, ofunc->overloads, 4);
+ AstOverloadedFunction* ofunc = make_node(AstOverloadedFunction, Ast_Kind_Overloaded_Function);
+ ofunc->token = token;
+ ofunc->flags |= Ast_Flag_Comptime;
- while (!consume_token_if_next(parser, '}')) {
- if (parser->hit_unexpected_token) return (AstFunction *) ofunc;
+ bh_arr_new(global_heap_allocator, ofunc->overloads, 4);
+
+ while (!consume_token_if_next(parser, '}')) {
+ if (parser->hit_unexpected_token) return ofunc;
- AstTyped* o_node = parse_expression(parser, 0);
+ AstTyped* o_node = parse_expression(parser, 0);
- bh_arr_push(ofunc->overloads, o_node);
+ bh_arr_push(ofunc->overloads, o_node);
- if (parser->curr->type != '}')
- expect_token(parser, ',');
- }
-
- ENTITY_SUBMIT(ofunc);
- return (AstFunction *) ofunc;
+ if (parser->curr->type != '}')
+ expect_token(parser, ',');
+ }
+
+ ENTITY_SUBMIT(ofunc);
+ return ofunc;
+}
+
+static AstFunction* parse_function_definition(OnyxParser* parser, OnyxToken* token) {
+ // :TemporaryForProcRemoval
+ if (parser->curr->type == '{') {
+ return (AstFunction *) parse_overloaded_function(parser, token);
}
AstFunction* func_def = make_node(AstFunction, Ast_Kind_Function);
static b32 parse_possible_function_definition(OnyxParser* parser, AstTyped** ret) {
if (parser->curr->type == Token_Type_Keyword_Proc) {
OnyxToken* proc_token = expect_token(parser, Token_Type_Keyword_Proc);
+ onyx_report_warning(proc_token->pos, "Warning: 'proc' is a deprecated keyword.");
AstFunction* func_node = parse_function_definition(parser, proc_token);
*ret = (AstTyped *) func_node;
return 1;
static AstTyped* parse_top_level_expression(OnyxParser* parser) {
if (parser->curr->type == Token_Type_Keyword_Proc) {
OnyxToken* proc_token = expect_token(parser, Token_Type_Keyword_Proc);
+ onyx_report_warning(proc_token->pos, "Warning: 'proc' is a deprecated keyword.");
AstFunction* func_node = parse_function_definition(parser, proc_token);
return (AstTyped *) func_node;
alias->to = parse_type(parser);
return (AstTyped *) alias;
}
+
+ if (parse_possible_directive(parser, "match")) {
+ // :LinearTokenDependent
+ OnyxToken* directive_token = parser->curr - 2;
+ AstOverloadedFunction* ofunc = parse_overloaded_function(parser, directive_token);
+ return (AstTyped *) ofunc;
+ }
return parse_expression(parser, 1);
}
return;
}
- case Token_Type_Keyword_Proc:
- parse_top_level_expression(parser);
- return;
+ // case Token_Type_Keyword_Proc:
+ // onyx_report_warning(parser->curr->pos, "Warning: 'proc' is a deprecated keyword.");
+ // parse_top_level_expression(parser);
+ // return;
case Token_Type_Symbol: {
OnyxToken* symbol = expect_token(parser, Token_Type_Symbol);
ENTITY_SUBMIT(operator);
return;
}
- else if (parse_possible_directive(parser, "add_overload")) {
+ else if (parse_possible_directive(parser, "add_overload") || parse_possible_directive(parser, "add_match")) {
AstDirectiveAddOverload *add_overload = make_node(AstDirectiveAddOverload, Ast_Kind_Directive_Add_Overload);
add_overload->token = dir_token;
add_overload->overloaded_function = (AstNode *) parse_expression(parser, 0);
next := false;
}
-#add_overload hash.to_u32, (c: CubePos) -> u32 {
+#add_match hash.to_u32, (c: CubePos) -> u32 {
return 17 * c.x + 13 * c.y + 11 * c.z + 19 * c.w;
}
y: i32 = 0;
}
-#add_overload hash.to_u32, (v: Vec2) -> u32 {
+#add_match hash.to_u32, (v: Vec2) -> u32 {
return v.x * 11 + v.y * 17;
}
Vec2 :: struct { x: i32; y: i32; }
// Overload print() to print Vec2's.
-#add_overload io.write, (use writer: ^io.Writer, use v: Vec2) {
+#add_match io.write, (use writer: ^io.Writer, use v: Vec2) {
io.write_format(writer, "Vec2(%i, %i)", x, y);
}
println("\n\n=========================");
- poly_overloaded :: proc {
+ poly_overloaded :: #match {
(y: [$N] $T) { print("MATCHED Y: "); print_array(y); },
(x: $T) { print("MATCHED X: "); println(x); },
(z: $T) { print("MATCHED Z: "); println(z); },
println(test_overload("World!", "Hello!"));
}
-test_overload :: proc {
+test_overload :: #match {
(x: $T, y: T) -> T { return x; },
(x: $T, y: $R) -> R { return y; },
}
use package core
-overloaded :: proc {
+overloaded :: #match {
(x: str, y: i32) do println("Called str, i32"); ,
(x: f32, y: str) do println("Called f32, str"); ,
(x: i32, y: i32) do println("Called i32, i32"); ,