absolute imports test, normalized all modules

This commit is contained in:
Judah Caruso 2025-07-22 20:39:57 -06:00
parent fd11638b8c
commit 05995a6a06
28 changed files with 301 additions and 132 deletions

22
README
View file

@ -1,16 +1,16 @@
------ --
jc.jai jc
------ --
# Direct installation # Direct installation
cd [jai install dir]/modules cd [jai install dir]/modules
git clone https://git.brut.systems/judah/jc.jai.git jc git clone https://git.brut.systems/judah/jc.git
# Indirect installation # Indirect installation
git clone https://git.brut.systems/judah/jc.jai.git git clone https://git.brut.systems/judah/jc.git
ln -s "/path/to/jc.jai" [jai install dir]/modules/jc # POSIX install ln -s "/path/to/jc" [jai install dir]/modules/jc # POSIX install
mklink /D "C:\path\to\jc.jai" [jai install dir]\jc # Windows install mklink /D "C:\path\to\jc" [jai install dir]\jc # Windows install
#import "jc"; #import "jc";
#import "jc/[module]"; #import "jc/[module]";
@ -36,10 +36,10 @@ Because Jai is still in closed beta (as of May 15, 2025),
updates to the compiler and "standard library" will break updates to the compiler and "standard library" will break
projects of mine; sometimes in a very annoying way. projects of mine; sometimes in a very annoying way.
jc.jai was made to 1) give myself an escape jc was made to 1) give myself an escape hatch/skin-suit to
hatch/skin-suit to cause fewer breaking changes when cause fewer breaking changes when updating the compiler,
updating the compiler, and 2) put all of my non-project and 2) put all of my non-project code in a single place
code in a single place that's easier to manage. that's easier to manage.
While I do use many of the modules shipped with the While I do use many of the modules shipped with the
compiler, my goal is to eventually replace them. compiler, my goal is to eventually replace them.

85
_make_module.jai Normal file
View file

@ -0,0 +1,85 @@
#run {
set_build_options_dc(.{ do_output = false });
args := get_build_options().compile_time_command_line;
usage :: () {
print("creates the template for a module or submodule\n\n");
print("usage: jai _make_module.jai - (module|submodule) [path]\n\n");
print("options:\n");
print("\tpath: a simple module path without an extension (example: 'foo' or 'foo/bar')\n");
}
if args.count < 2 {
usage();
return;
}
kind := trim(args[0]);
if kind.count == 0 {
usage();
return;
}
module_path := trim(args[1]);
if module_path.count == 0 {
usage();
return;
}
if kind == {
case "module";
assert(make_directory_if_it_does_not_exist(module_path), "could not create module directory: '%'", module_path);
entry_file := tprint("%/module.jai", module_path);
assert(write_entire_file(entry_file, tprint(MODULE_STRING, module_path)), "could not create %", entry_file);
case "submodule";
entry_file := tprint("%.jai", module_path);
assert(write_entire_file(entry_file, tprint(SUBMODULE_STRING, module_path)), "could not create %", entry_file);
case;
usage();
return;
}
}
MODULE_STRING :: #string END
// %1 is a module that does things.
//
#module_parameters(RUN_TESTS := false, IMPORTED_INTERNALLY := false);
#scope_export;
#if !IMPORTED_INTERNALLY {
// #import "jc/%1/submodule"(RUN_TESTS);
// ...
}
END;
SUBMODULE_STRING :: #string END
// %1 is a module that does stuff.
//
#module_parameters(RUN_TESTS := false);
#scope_export;
// ...
#scope_file;
// ----------------------------------------------------------
// TESTS
// ----------------------------------------------------------
#if RUN_TESTS #run {
test :: #import "jc/meta/test";
test.run("%1:works", t => {
test.expect(t, true);
});
}
END;
#import "File";
#import "Basic";
#import "String";
#import "Compiler";

View file

@ -2,17 +2,14 @@
compiler :: #import "Compiler"; compiler :: #import "Compiler";
compiler.set_build_options_dc(.{ do_output = false }); compiler.set_build_options_dc(.{ do_output = false });
// @note(judah): we use relative imports here because that'll #import "jc/array"(RUN_TESTS = true);
// print cleaner file locations. #import "jc/encoding"(RUN_TESTS = true);
#import "jc/hash"(RUN_TESTS = true);
#import "jc/memory"(RUN_TESTS = true);
#import "jc/meta"(RUN_TESTS = true);
#import "jc/platform"(RUN_TESTS = true);
#import,file "./array/module.jai"(RUN_TESTS_AT_COMPILE_TIME = true); rmath :: #import "jc/math"(.radians, RUN_TESTS = true);
#import,file "./encoding/module.jai"(RUN_TESTS_AT_COMPILE_TIME = true); dmath :: #import "jc/math"(.degrees, RUN_TESTS = true);
#import,file "./hash/module.jai"(RUN_TESTS_AT_COMPILE_TIME = true); tmath :: #import "jc/math"(.turns, RUN_TESTS = true);
#import,file "./memory/module.jai"(RUN_TESTS_AT_COMPILE_TIME = true);
#import,file "./meta/module.jai"(RUN_TESTS_AT_COMPILE_TIME = true);
#import,file "./platform/module.jai"(RUN_TESTS_AT_COMPILE_TIME = true);
rmath :: #import,file "./math/module.jai"(.radians, RUN_TESTS_AT_COMPILE_TIME = true);
dmath :: #import,file "./math/module.jai"(.degrees, RUN_TESTS_AT_COMPILE_TIME = true);
tmath :: #import,file "./math/module.jai"(.turns, RUN_TESTS_AT_COMPILE_TIME = true);
} }

View file

@ -1,44 +1,58 @@
to_string :: (c: *u8, count := 1) -> string #expand { #module_parameters(RUN_TESTS := false);
to_string :: (c: cstring, count := 1) -> string #expand {
return string.{ data = c, count = count }; return string.{ data = c, count = count };
} }
Index_Mode :: enum { Index_Flag :: enum_flags {
from_left; from_end;
from_right; index_plus_one;
count_on_fail;
} }
find_index :: (b: []u8, c: u8, $mode := Index_Mode.from_left) -> bool, int { find_index :: (b: []byte, c: byte, $mode: Index_Flag) -> bool, int {
#if #complete mode == { count := 0;
case .from_left; #if mode & .from_end {
for b if it == c { i := b.count - 1;
return true, it_index; while i >= 0 {
if b[i] == c {
return true, #ifx mode & .index_plus_one i + 1 else i;
} }
case .from_right; i -= 1;
i := b.count - 1;
while i >= 0 {
if b[i] == c {
return true, i;
}
i -= 1; #if mode & .count_on_fail {
count += 1;
} }
}
}
else {
for b if it == c {
return true, #ifx mode & .index_plus_one then it_index + 1 else it_index;
}
else #if mode & .count_on_fail {
count += 1;
}
} }
return false, -1; return false, #ifx mode & .count_on_fail then count else -1;
} }
find_index :: inline (s: string, c: u8, $mode := Index_Mode.from_left) -> bool, int { find_index :: inline (s: string, c: byte, $mode: Index_Flag) -> bool, int {
ok, idx := find_index(s.([]u8), c, mode); ok, idx := find_index(s.([]byte), c, mode);
return ok, idx; return ok, idx;
} }
#scope_file; #scope_file;
#import "jc";
// ---------------------------------------------------------- // ----------------------------------------------------------
// TESTS // TESTS
// ---------------------------------------------------------- // ----------------------------------------------------------
#if #exists(RUN_TESTS) #run { #if RUN_TESTS #run {
test :: #import "jc/meta/test"; test :: #import "jc/meta/test";
} }

View file

@ -1,3 +1,5 @@
#module_parameters(RUN_TESTS := false);
// @todo(judah): replace array_add // @todo(judah): replace array_add
append :: inline (arr: *[..]$T, value: T) -> *T { append :: inline (arr: *[..]$T, value: T) -> *T {
@ -62,7 +64,12 @@ meta :: #import "jc/meta";
basic :: #import "Basic"; // @future basic :: #import "Basic"; // @future
#if #exists(RUN_TESTS) #run {
// ----------------------------------------------------------
// TESTS
// ----------------------------------------------------------
#if RUN_TESTS #run {
test :: #import "jc/meta/test"; test :: #import "jc/meta/test";
test.run("remove_ordered", t => { test.run("remove_ordered", t => {

View file

@ -1,13 +1,13 @@
#module_parameters(RUN_TESTS_AT_COMPILE_TIME := false); #module_parameters(RUN_TESTS := false, WITH_SUBMODULES := true);
#load "bytes.jai"; #scope_export;
#load "dynamic.jai";
#load "stable.jai"; #if WITH_SUBMODULES {
#load "static.jai"; using #import "jc/array/bytes"(RUN_TESTS);
#load "xar.jai"; using #import "jc/array/dynamic"(RUN_TESTS);
using #import "jc/array/stable"(RUN_TESTS);
using #import "jc/array/static"(RUN_TESTS);
using #import "jc/array/xar"(RUN_TESTS);
}
#scope_module; #scope_module;
#if RUN_TESTS_AT_COMPILE_TIME {
RUN_TESTS :: true;
}

View file

@ -1,3 +1,5 @@
#module_parameters(RUN_TESTS := false);
// A dynamic array whose values will never move in memory. // A dynamic array whose values will never move in memory.
// //
// This means it is safe to take a pointer to a value within the array // This means it is safe to take a pointer to a value within the array
@ -97,9 +99,6 @@ for_expansion :: (a: Stable_Array, body: Code, flags: For_Flags) #expand {
#scope_file; #scope_file;
mem :: #import "jc/memory";
meta :: #import "jc/meta";
find_or_create_chunk :: (a: *Stable_Array, amount: int) -> *a.Chunk { find_or_create_chunk :: (a: *Stable_Array, amount: int) -> *a.Chunk {
if a.chunks.count == 0 { if a.chunks.count == 0 {
return create_chunk(a); return create_chunk(a);
@ -122,12 +121,17 @@ create_chunk :: (a: *Stable_Array) -> *a.Chunk {
return chunk; return chunk;
} }
#import "jc/array";
mem :: #import "jc/memory";
meta :: #import "jc/meta";
// ---------------------------------------------------------- // ----------------------------------------------------------
// TESTS // TESTS
// ---------------------------------------------------------- // ----------------------------------------------------------
#if #exists(RUN_TESTS) #run { #if RUN_TESTS #run {
test :: #import "jc/meta/test"; test :: #import "jc/meta/test";
test.run("basic operations", t => { test.run("basic operations", t => {

View file

@ -1,3 +1,5 @@
#module_parameters(RUN_TESTS := false);
Static_Array :: struct(capacity: int, T: Type) { Static_Array :: struct(capacity: int, T: Type) {
items: [capacity]T; items: [capacity]T;
count: int; count: int;
@ -108,7 +110,7 @@ basic :: #import "Basic"; // @future
// TESTS // TESTS
// ---------------------------------------------------------- // ----------------------------------------------------------
#if #exists(RUN_TESTS) #run { #if RUN_TESTS #run {
test :: #import "jc/meta/test"; test :: #import "jc/meta/test";
test.run("basic operations", (t) => { test.run("basic operations", (t) => {

View file

@ -1,9 +1,11 @@
#module_parameters(RUN_TESTS := false);
#scope_file; #scope_file;
// ---------------------------------------------------------- // ----------------------------------------------------------
// TESTS // TESTS
// ---------------------------------------------------------- // ----------------------------------------------------------
#if #exists(RUN_TESTS) #run { #if RUN_TESTS #run {
test :: #import "jc/meta/test"; test :: #import "jc/meta/test";
} }

View file

@ -1,3 +1,5 @@
#module_parameters(RUN_TESTS := false);
base64_encode :: (str: string, $for_url := false) -> string, bool { base64_encode :: (str: string, $for_url := false) -> string, bool {
enc, ok := base64_encode(str.([]u8), for_url); enc, ok := base64_encode(str.([]u8), for_url);
return enc.(string), ok; return enc.(string), ok;
@ -153,9 +155,6 @@ encoded_length :: (count: int, with_padding := false) -> int {
return (count * 8 + 5) / 6; return (count * 8 + 5) / 6;
} }
#scope_file;
basic :: #import "Basic"; // @future basic :: #import "Basic"; // @future
strings :: #import "String"; // @future strings :: #import "String"; // @future
@ -164,7 +163,7 @@ strings :: #import "String"; // @future
// TESTS // TESTS
// ---------------------------------------------------------- // ----------------------------------------------------------
#if #exists(TESTS) #run { #if RUN_TESTS #run {
test :: #import "jc/meta/test"; test :: #import "jc/meta/test";
test.run("encodes", (t) => { test.run("encodes", (t) => {

View file

@ -1,3 +1,5 @@
#module_parameters(RUN_TESTS := false);
Json_Value :: struct { Json_Value :: struct {
kind: enum { kind: enum {
none; none;

View file

@ -1,10 +1,10 @@
#module_parameters(RUN_TESTS_AT_COMPILE_TIME := false); #module_parameters(RUN_TESTS := false, WITH_SUBMODULES := true);
#load "base64.jai"; #scope_export;
#load "json.jai";
#if WITH_SUBMODULES {
using #import "jc/encoding/base64"(RUN_TESTS);
using #import "jc/encoding/json"(RUN_TESTS);
}
#scope_module; #scope_module;
#if RUN_TESTS_AT_COMPILE_TIME {
RUN_TESTS :: true;
}

View file

@ -1,11 +1,10 @@
#module_parameters(RUN_TESTS_AT_COMPILE_TIME := false); #module_parameters(RUN_TESTS := false, WITH_SUBMODULES := false);
#load "murmur.jai"; #scope_export;
#load "xxhash.jai";
#load "table.jai";
#scope_module; #if WITH_SUBMODULES {
using #import "jc/hash/murmur"(RUN_TESTS);
#if RUN_TESTS_AT_COMPILE_TIME { using #import "jc/hash/xxhash"(RUN_TESTS);
RUN_TESTS :: true; using #import "jc/hash/table"(RUN_TESTS);
} }

View file

@ -1,3 +1,5 @@
#module_parameters(RUN_TESTS := false);
// Implementation: Demetri Spanos (github.com/demetri/scribbles) // Implementation: Demetri Spanos (github.com/demetri/scribbles)
// Jai Port: Jesse Coyle (github.com/Zilarrezko) // Jai Port: Jesse Coyle (github.com/Zilarrezko)

View file

@ -1,3 +1,5 @@
#module_parameters(RUN_TESTS := false);
// Dead simple key-value pair type (aka. hash table or hash map) // Dead simple key-value pair type (aka. hash table or hash map)
Table :: struct(Key: Type, Value: Type) { Table :: struct(Key: Type, Value: Type) {
allocator: Allocator; allocator: Allocator;
@ -132,7 +134,7 @@ basic :: #import "Basic"; // @future
// TESTS // TESTS
// ---------------------------------------------------------- // ----------------------------------------------------------
#if #exists(RUN_TESTS) #run { #if RUN_TESTS #run {
test :: #import "jc/meta/test"; test :: #import "jc/meta/test";
test.run("basic operations", t => { test.run("basic operations", t => {

View file

@ -1,3 +1,5 @@
#module_parameters(RUN_TESTS := false);
// Implementation: Demetri Spanos (github.com/demetri/scribbles) // Implementation: Demetri Spanos (github.com/demetri/scribbles)
// Jai Port: Jesse Coyle (github.com/Zilarrezko) // Jai Port: Jesse Coyle (github.com/Zilarrezko)

View file

@ -2,7 +2,7 @@
UNITS: enum { radians; degrees; turns; } = .turns, UNITS: enum { radians; degrees; turns; } = .turns,
RECT_TYPE: Type = float, RECT_TYPE: Type = float,
// RECT_METHOD: enum { dimension; absolute; } = absolute, // Note(Jesse): Maybe at a later point we can do this // RECT_METHOD: enum { dimension; absolute; } = absolute, // Note(Jesse): Maybe at a later point we can do this
RUN_TESTS_AT_COMPILE_TIME := false RUN_TESTS := false
); );
#assert meta.type_is_scalar(RECT_TYPE); #assert meta.type_is_scalar(RECT_TYPE);
@ -30,14 +30,10 @@ F64_Min, F64_Max :: #run meta.lo_for(float64), #run meta.hi_for(float64);
#scope_module; #scope_module;
meta :: #import "jc/meta"; meta :: #import "jc/meta";
math :: #import "Math"; // @future math :: #import "Math"; // @future
basic :: #import "Basic"; // @future basic :: #import "Basic"; // @future
#if RUN_TESTS_AT_COMPILE_TIME {
RUN_TESTS :: true;
}
// @temp(judah): move these to the right files // @temp(judah): move these to the right files
v2_eq :: (a: Vec2, b: Vec2) -> bool { v2_eq :: (a: Vec2, b: Vec2) -> bool {

View file

@ -651,9 +651,9 @@ cross :: (a: Vec3, b: Vec3) -> Vec3 {
return v; return v;
} }
#scope_file #scope_file;
#if #exists(RUN_TESTS) #run,stallable { #if RUN_TESTS #run,stallable {
test :: #import "jc/meta/test"; test :: #import "jc/meta/test";
test.run(basic.tprint("%: Vec2", UNITS), t => { test.run(basic.tprint("%: Vec2", UNITS), t => {

View file

@ -1,3 +1,5 @@
#module_parameters(RUN_TESTS := false);
make_crash_allocator :: () -> Allocator { make_crash_allocator :: () -> Allocator {
return .{ proc = crash_allocator_proc }; return .{ proc = crash_allocator_proc };
} }
@ -87,12 +89,12 @@ arena_allocator_proc :: (mode: Extended_Allocator_Mode, size: s64, old_size: s64
return null; return null;
} }
arena_alloc :: (a: *Arena, count: int, alignment := Default_Align, loc := #caller_location) -> *void { arena_alloc :: (a: *Arena, count: int, alignment := mem.Default_Align, loc := #caller_location) -> *void {
basic.assert(a.memory != null, "arena: not initialized", loc = loc); basic.assert(a.memory != null, "arena: not initialized", loc = loc);
basic.assert(power_of_two(alignment)); basic.assert(mem.power_of_two(alignment));
end := a.memory.(*u8) + a.offset; end := a.memory.(*u8) + a.offset;
ptr := align_to(end.(int), alignment); ptr := mem.align_to(end.(int), alignment);
total_size := (count + ptr.(*u8) - end.(*u8)).(u64); total_size := (count + ptr.(*u8) - end.(*u8)).(u64);
basic.assert(a.offset + total_size <= a.memory_size, "arena: out of memory", loc = loc); basic.assert(a.offset + total_size <= a.memory_size, "arena: out of memory", loc = loc);
@ -104,30 +106,32 @@ arena_alloc :: (a: *Arena, count: int, alignment := Default_Align, loc := #calle
#scope_file; #scope_file;
basic :: #import "Basic"; // @future mem :: #import "jc/memory";
meta :: #import "jc/meta"; meta :: #import "jc/meta";
basic :: #import "Basic"; // @future
// ---------------------------------------------------------- // ----------------------------------------------------------
// TESTS // TESTS
// ---------------------------------------------------------- // ----------------------------------------------------------
#if #exists(RUN_TESTS) #run { #if RUN_TESTS #run {
test :: #import "jc/meta/test"; test :: #import "jc/meta/test";
test.run("arena:basic", t => { test.run("arena:basic", t => {
memory := request_memory(1 * Kilobyte); memory := mem.request_memory(1 * mem.Kilobyte);
defer release_memory(memory); defer mem.release_memory(memory);
arena: Arena; arena: Arena;
init_arena(*arena, memory, 1 * Kilobyte); init_arena(*arena, memory, 1 * mem.Kilobyte);
context.allocator = make_arena_allocator(*arena); context.allocator = make_arena_allocator(*arena);
save_point := allocator_save(); save_point := mem.allocator_save();
i := request_memory(int); i := mem.request_memory(int);
basic.assert(i != null); basic.assert(i != null);
basic.assert(arena.offset == size_of(int)); basic.assert(arena.offset == size_of(int));
allocator_restore(save_point); mem.allocator_restore(save_point);
}); });
} }

View file

@ -1,3 +1,5 @@
#module_parameters(RUN_TESTS := false);
Buffer :: struct { Buffer :: struct {
allocator: Allocator; allocator: Allocator;
@ -42,10 +44,6 @@ ensure_buffer_has_room :: (buf: *Buffer, count: int) -> *u8 {
return ptr; return ptr;
} }
#if #exists(RUN_TESTS) #run { #if RUN_TESTS #run {
test :: #import "jc/meta/test"; test :: #import "jc/meta/test";
test.run("basic operations", t => {
buf: Buffer;
});
} }

View file

@ -1,4 +1,6 @@
#module_parameters(RUN_TESTS_AT_COMPILE_TIME := false); #module_parameters(RUN_TESTS := false, WITH_SUBMODULES := true);
#scope_export;
Kilobyte :: 1024; Kilobyte :: 1024;
Megabyte :: 1024 * Kilobyte; Megabyte :: 1024 * Kilobyte;
@ -172,14 +174,11 @@ lazy_set_allocator :: (array: *[..]$T, allocator := context.allocator) #expand {
} }
} }
#load "allocators.jai"; #if WITH_SUBMODULES {
using #import "jc/memory/allocators"(RUN_TESTS);
#scope_module;
#if RUN_TESTS_AT_COMPILE_TIME {
RUN_TESTS :: true;
} }
#scope_file; #scope_file;
meta :: #import "jc/meta"; meta :: #import "jc/meta";
@ -192,7 +191,7 @@ compiler :: #import "Compiler"; // @future
// TESTS // TESTS
// ---------------------------------------------------------- // ----------------------------------------------------------
#if #exists(RUN_TESTS) #run { #if RUN_TESTS #run {
test :: #import "jc/meta/test"; test :: #import "jc/meta/test";
test.run("request_memory:dynamic arrays", (t) => { test.run("request_memory:dynamic arrays", (t) => {

View file

@ -1,3 +1,5 @@
#module_parameters(RUN_TESTS := false);
/* /*
Allows structs to be copied and assigned inline. Allows structs to be copied and assigned inline.
@ -215,6 +217,8 @@ Unrolled_Loop :: struct(N: int, T: Type = void) {
#scope_file; #scope_file;
mem :: #import "jc/memory";
basic :: #import "Basic"; // @future basic :: #import "Basic"; // @future
pp :: #import "Program_Print"; // @future pp :: #import "Program_Print"; // @future
compiler :: #import "Compiler"; // @future compiler :: #import "Compiler"; // @future
@ -224,7 +228,7 @@ compiler :: #import "Compiler"; // @future
// TESTS // TESTS
// ---------------------------------------------------------- // ----------------------------------------------------------
#if #exists(RUN_TESTS) #run { #if RUN_TESTS #run {
test :: #import "jc/meta/test"; test :: #import "jc/meta/test";
test.run("this_block", (t) => { test.run("this_block", (t) => {

View file

@ -1,4 +1,6 @@
#module_parameters(RUN_TESTS_AT_COMPILE_TIME := false); #module_parameters(RUN_TESTS := false, WITH_SUBMODULES := true);
#scope_export;
get_stack_trace_caller_location :: (loc := #caller_location) -> Source_Code_Location { get_stack_trace_caller_location :: (loc := #caller_location) -> Source_Code_Location {
if context.stack_trace == null || context.stack_trace.info == null { if context.stack_trace == null || context.stack_trace.info == null {
@ -61,16 +63,13 @@ snake_to_pascal :: (name: string) -> string {
return basic.builder_to_string(*b); return basic.builder_to_string(*b);
} }
#load "macros.jai"; #if WITH_SUBMODULES {
#load "type_info.jai"; using #import "jc/meta/macros"(RUN_TESTS);
using #import "jc/meta/type_info"(RUN_TESTS);
}
#scope_module; #scope_module;
#if RUN_TESTS_AT_COMPILE_TIME {
RUN_TESTS :: true;
}
mem :: #import "jc/memory"; mem :: #import "jc/memory";
basic :: #import "Basic"; // @future basic :: #import "Basic"; // @future
@ -81,7 +80,7 @@ compiler :: #import "Compiler"; // @future
// TESTS // TESTS
// ---------------------------------------------------------- // ----------------------------------------------------------
#if RUN_TESTS_AT_COMPILE_TIME #run { #if RUN_TESTS #run {
test :: #import "jc/meta/test"; test :: #import "jc/meta/test";
test.run("snake_to_pascal", t => { test.run("snake_to_pascal", t => {

View file

@ -41,10 +41,33 @@ expect :: (t: *T, cond: bool, message := "", args: ..Any, loc := #caller_locatio
} }
run :: (name: string, proc: Proc, loc := #caller_location) { run :: (name: string, proc: Proc, loc := #caller_location) {
idx := strings.find_index_from_left(loc.fully_pathed_filename, "./") + 2; // @note(judah): incredibly dumb way to get nicer test runs
path := loc.fully_pathed_filename; path := loc.fully_pathed_filename;
path.data += idx;
path.count -= idx; i := path.count - 1;
found_first_slash := false;
while i >= 0 {
if path[i] == "/" {
if found_first_slash {
i += 1;
break;
}
found_first_slash = true;
}
i -= 1;
}
if !found_first_slash {
path = strings.path_filename(loc.fully_pathed_filename);
}
else {
path.count -= i;
path.data += i;
}
basic.print("%,%: %...", path, loc.line_number, name); basic.print("%,%: %...", path, loc.line_number, name);
t: T; t: T;

View file

@ -1,3 +1,5 @@
#module_parameters(RUN_TESTS := false);
// These return the bool first so you can check in a conditional, // These return the bool first so you can check in a conditional,
// rather than having to do '_, ok := ...' // rather than having to do '_, ok := ...'
@ -166,7 +168,7 @@ compiler :: #import "Compiler"; // @future
// TESTS // TESTS
// ---------------------------------------------------------- // ----------------------------------------------------------
#if #exists(RUN_TESTS) #run { #if RUN_TESTS #run {
test :: #import "jc/meta/test"; test :: #import "jc/meta/test";
test.run("lo_for:primitives", t => { test.run("lo_for:primitives", t => {

26
module.jai Normal file
View file

@ -0,0 +1,26 @@
#scope_export;
byte :: u8;
f32 :: float32;
f64 :: float64;
cstring :: *byte;
rawptr :: *void;
#if size_of(int) == size_of(s64) {
sint :: s64;
uint :: u64;
}
else {
sint :: s32;
uint :: u32;
}
#if size_of(rawptr) == size_of(u64) {
uptr :: u64;
sptr :: s64;
}
else {
uptr :: u32;
sptr :: s32;
}

View file

@ -1,3 +1,5 @@
#module_parameters(RUN_TESTS := false);
// All of the architecture-specific extensions we care to look for. // All of the architecture-specific extensions we care to look for.
// Note: Checking for impossible extensions will always turn into a no-op (ex. NEON support on x64). // Note: Checking for impossible extensions will always turn into a no-op (ex. NEON support on x64).
ISA_Extension :: enum { ISA_Extension :: enum {

View file

@ -1,10 +1,9 @@
#module_parameters(RUN_TESTS_AT_COMPILE_TIME := false); #module_parameters(RUN_TESTS := false, WITH_SUBMODULES := true);
#load "arch.jai"; #scope_export;
#if WITH_SUBMODULES {
using #import "jc/platform/arch"(RUN_TESTS);
}
#scope_module; #scope_module;
#if RUN_TESTS_AT_COMPILE_TIME {
RUN_TESTS :: true;
}