map :: proc (arr: ^[..] $T, data: $R, f: proc (T, R) -> T) {
for ^it: *arr do *it = f(*it, data);
}
+
+#private_file
+greatest_impl :: (arr: ^$T, count: i32) -> (i32, T) {
+ greatest_idx := 0;
+ greatest := arr[0];
+
+ for i: 1 .. count {
+ if arr[i] > greatest {
+ greatest_idx = i;
+ greatest = arr[i];
+ }
+ }
+
+ return greatest_idx, greatest;
+}
+
+// This pattern should be expanded on to make all kinds of folding functions.
+greatest :: proc {
+ (arr: [..] $T) -> (i32, T) { return greatest_impl(arr.data, arr.count); },
+ (arr: [] $T) -> (i32, T) { return greatest_impl(arr.data, arr.count); },
+ (arr: [$N] $T) -> (i32, T) { return greatest_impl(cast(^T) arr, N); },
+}
Ast_Flag_Private_File = BH_BIT(6),
// Global flags
- Ast_Flag_Global_Stack_Top = BH_BIT(7), // These can go away for something better,
- Ast_Flag_Global_Stack_Base = BH_BIT(8), // like just checking the pointers since they will be unique.
+ Ast_Flag_Global_Stack_Top = BH_BIT(7),
// Function flags
+ Ast_Flag_Already_Checked = BH_BIT(8),
Ast_Flag_Intrinsic = BH_BIT(10),
Ast_Flag_Function_Used = BH_BIT(11),
--- /dev/null
+version(1);
+project_name = "Onyx";
+
+patterns = {
+"*.c",
+"*.cpp",
+"*.h",
+"*.onyx",
+"*.js",
+"*.bat",
+"*.sh",
+"*.4coder",
+"*.txt",
+};
+blacklist_patterns = {
+".*",
+};
+load_paths_custom = {
+ {"."},
+};
+load_paths = {
+ { load_paths_custom, .os = "win" },
+ { load_paths_custom, .os = "linux"},
+ { load_paths_custom, .os = "mac" },
+};
+
+build_debug_win32 = "build.bat";
+build_release_win32 = "build.bat 1";
+build_debug_linux = "./build.sh debug";
+build_release_linux = "./build.sh";
+
+command_list = {
+ { .name = "Build Debug",
+ .out = "*compilation*", .footer_panel = true, .save_dirty_files = true,
+ .cmd = { {build_debug_win32, .os ="win" },
+ {build_debug_linux, .os ="linux"}, }, },
+
+ { .name = "Build Release",
+ .out = "*compilation*", .footer_panel = true, .save_dirty_files = true,
+ .cmd = { {build_release_win32, .os ="win" },
+ {build_release_linux, .os ="linux" }, }, },
+};
+
+fkey_command[1] = "Build Debug";
+fkey_command[2] = "Build Release";
bh_file file;
bh_file_error err = bh_file_open(&file, filename);
if (err != BH_FILE_ERROR_NONE) {
- // bh_printf_err("Failed to open file %s\n", filename);
onyx_report_error((OnyxFilePos) { 0 }, "Failed to open file %s\n", filename);
return ONYX_COMPILER_PROGRESS_FAILED_READ;
}
bh_file_contents fc = bh_file_read_contents(context.token_alloc, &file);
bh_file_close(&file);
- // POTENTIAL BUG: If there are too many files and too many collisions in the table,
- // there is a chance that the inner arrays of the table will be repositioned. That
- // would completely break the pointer taken here, which would break all references
- // to file contents anywhere else in the program.
- //
- // A good solution would be to not use a table and just use a array of char* and
- // ensure that the filename is not in that list.
- // - brendanfh 2020/09/03
-
-
- // NOTE: Need to reget the value out of the table so token references work
bh_arr_push(context.loaded_files, fc);
if (context.options->verbose_output == 2) {
// 9. Check types of formal and actual params against each other, handling varargs
CHECK(expression, &call->callee);
- AstFunction* callee = (AstFunction *) call->callee;
-
check_arguments(&call->args);
- if (callee->kind == Ast_Kind_Overloaded_Function) {
- call->callee = match_overloaded_function(&call->args, ((AstOverloadedFunction *) callee)->overloads);
-
+ if (call->callee->kind == Ast_Kind_Overloaded_Function) {
+ call->callee = match_overloaded_function(&call->args, ((AstOverloadedFunction *) call->callee)->overloads);
if (call->callee == NULL) {
report_unable_to_match_overload(call);
return Check_Error;
}
-
- callee = (AstFunction *) call->callee;
}
- if (callee->kind == Ast_Kind_Polymorphic_Proc) {
+ if (call->callee->kind == Ast_Kind_Polymorphic_Proc) {
call->callee = (AstTyped *) polymorphic_proc_lookup((AstPolyProc *) call->callee, PPLM_By_Arguments, &call->args, call->token);
-
if (call->callee == NULL) return Check_Error;
- callee = (AstFunction *) call->callee;
arguments_remove_baked(&call->args);
}
+ AstFunction* callee = (AstFunction *) call->callee;
+
// NOTE: Build callee's type
fill_in_type((AstTyped *) callee);
if (callee->type == NULL) {
case Ast_Kind_Polymorphic_Proc: break;
case Ast_Kind_Package: break;
case Ast_Kind_Error: break;
+
+ // NOTE: The only way to have an Intrinsic_Call node is to have gone through the
+ // checking of a call node at least once.
+ case Ast_Kind_Intrinsic_Call: break;
default:
retval = Check_Error;
}
CheckStatus check_function(AstFunction* func) {
+ if (func->flags & Ast_Flag_Already_Checked) return Check_Success;
+
expected_return_type = func->type->Function.return_type;
if (func->body) {
CheckStatus status = check_block(func->body);
return status;
}
+
+ func->flags |= Ast_Flag_Already_Checked;
return Check_Success;
}
b32 success = 1;
fori (idx, 0, bh_arr_length(args->values)) {
if (args->values[idx] == NULL) args->values[idx] = (AstTyped *) lookup_default_value_by_idx(provider, idx);
- if (args->values[idx] == NULL) success = 0;
+ if (args->values[idx] == NULL) {
+ *err_msg = bh_aprintf(global_scratch_allocator, "No value given for %d%s argument.", idx + 1, bh_num_suffix(idx + 1));
+ success = 0;
+ }
}
return success;
EMIT_FUNC(memory_reservation_location, AstMemRes* memres);
EMIT_FUNC(location_return_offset, AstTyped* expr, u64* offset_return);
EMIT_FUNC(location, AstTyped* expr);
-EMIT_FUNC(compound_load, Type* type, u64 offset);
+EMIT_FUNC(compound_load, Type* type, u64 offset);
EMIT_FUNC(struct_lval, AstTyped* lval);
EMIT_FUNC(struct_literal, AstStructLiteral* sl);
EMIT_FUNC(compound_store, Type* type, u64 offset, b32 location_first);