reorganize slightly to make importing easier

This commit is contained in:
Judah Caruso 2025-05-12 19:51:25 -06:00
parent 121a1d8ed4
commit 8b013ce0fa
8 changed files with 192 additions and 67 deletions

18
base.jai Normal file
View file

@ -0,0 +1,18 @@
uint :: #type u64;
sint :: #type s64;
rune :: #type u32;
rawptr :: #type *void;
Default_Align :: #run 2 * align_of(rawptr);
align_of :: ($T: Type) -> uint #expand {
return #run -> uint {
info := type_info(struct{ p: u8; t: T; });
return info.members[1].offset_in_bytes.(uint);
};
}
bitcast :: ($T: Type, expr: Code) -> T #expand {
value := expr;
return (*value).(*T).*;
}

View file

@ -144,7 +144,7 @@ base64_decode :: (data: []u8) -> []u8, bool {
#scope_file;
Padding_Character :: #char "=";
Padding_Character :: #char "=";
Encoding_Url :: "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_";
Encoding_Standard :: "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
@ -153,12 +153,14 @@ encoded_length :: (count: int, with_padding := false) -> int {
return (count * 8 + 5) / 6;
}
#scope_file;
basic :: #import "Basic";
strings :: #import "String";
#if RUN_TESTS #run {
test :: #import,file "../test/module.jai";
#if RUN_TESTS #run {
test.run("encodes", (t) => {
str :: "Hello, World";

View file

@ -2,3 +2,9 @@
#load "base64.jai";
#scope_module;
#if RUN_TESTS {
test :: #import,file "../test/module.jai";
}

View file

@ -1,18 +1,3 @@
verify :: (block: Code) #expand {
for 0..0 #insert,scope(block) block;
}
c_call :: (block: Code) #expand {
push_context context {
#insert,scope() block;
}
}
zero_value :: ($T: Type) -> T #expand {
zero: T;
return zero;
}
// Allows structs to be copy assigned.
with :: (old: $T, $new: Code, location := #caller_location) -> T
#modify { return T.(*Type_Info).type == .STRUCT, "with can only be used on structs"; }
@ -77,8 +62,6 @@ operator | :: with;
#scope_file;
test :: #import,file "test/module.jai";
pp :: #import "Program_Print";
compiler :: #import "Compiler";

View file

@ -2,20 +2,6 @@ Kilobyte :: 1024;
Megabyte :: 1024 * Kilobyte;
Gigabyte :: 1024 * Megabyte;
Default_Align :: #run 2 * align_of(rawptr);
align_of :: ($T: Type) -> uint #expand {
return #run -> uint {
info := type_info(struct{ p: u8; t: T; });
return info.members[1].offset_in_bytes.(uint);
};
}
bitcast :: ($T: Type, expr: Code) -> T #expand {
value := expr;
return (*value).(*T).*;
}
power_of_two :: (x: uint) -> bool {
if x == 0 return false;
return x & (x - 1) == 0;
@ -30,3 +16,76 @@ align_forward :: (ptr: uint, align: uint = Default_Align) -> uint {
return p;
}
init_or_zero :: inline (ptr: *$T, custom_init: (*T) = null) {
init :: initializer_of(T);
if custom_init != null {
custom_init(ptr);
}
#if init != null {
inline init(ptr);
}
else {
memset(ptr, 0, size_of(T));
}
}
make :: ($T: Type, reserved := 0, $init := true) -> [..]T
#modify {
ok, info := type_is_array(T);
if ok && info.array_type == .RESIZABLE {
T = compiler.get_type(info.element_type);
return true;
}
return false;
}
{
size := align_forward(size_of(T) * basic.max(reserved, 0).(uint)).(sint);
data := basic.alloc(size);
#if init if size != 0 {
memset(data, 0, size);
}
arr: [..]T;
arr.data = data;
arr.count = 0;
arr.allocated = size / size_of(T);
arr.allocator = context.allocator;
return arr;
}
make :: ($T: Type, $init := true) -> *T
#modify { return !type_is_array(T); }
{
ptr := basic.alloc(size_of(T)).(*T);
#if init init_or_zero(ptr);
return ptr;
}
#scope_file;
#if RUN_TESTS #run {
test :: #import,file "./test/module.jai";
test.run("make:dynamic arrays", (t) => {
a1 := make([..]int);
test.expect(t, a1.count == 0);
test.expect(t, a1.allocated == 0);
basic.array_add(*a1, 10, 20, 30);
test.expect(t, a1.count == 3);
test.expect(t, a1.allocated != 0, "%", a1.allocated);
a2 := make([..]int, 8);
test.expect(t, a2.count == 0);
test.expect(t, a2.allocated == 8);
});
test.run("make:values", (t) => {
v1 := make(int);
test.expect(t, v1.* == 0);
});
}

View file

@ -1,9 +1,6 @@
#module_parameters(RUN_TESTS := false);
uint :: #type u64;
rune :: #type u32;
rawptr :: #type *void;
#load "base.jai";
#load "utils.jai";
#load "memory.jai";
#load "macros.jai";
@ -15,12 +12,10 @@ rawptr :: #type *void;
basic :: #import "Basic";
compiler :: #import "Compiler";
#scope_file;
#if RUN_TESTS {
#run compiler.set_build_options_dc(.{ do_output = false });
test :: #import,file "test/module.jai";
#import,file "./encoding/module.jai"(RUN_TESTS);
}

View file

@ -1,7 +1,7 @@
T :: struct {
location: Source_Code_Location;
expects_run: int;
expects_ok: int;
expects_run: sint;
expects_ok: sint;
failed: bool;
}
@ -43,6 +43,11 @@ run :: (name: string, proc: Proc, loc := #caller_location) {
}
}
#scope_file;
#import,file "../base.jai";
basic :: #import "Basic";
strings :: #import "String";
compiler :: #import "Compiler";

105
utils.jai
View file

@ -1,3 +1,80 @@
verify :: (block: Code) #expand {
for 0..0 #insert,scope(block) block;
}
c_call :: (block: Code) #expand {
push_context context {
#insert,scope() block;
}
}
zero_value :: ($T: Type) -> T #expand {
zero: T;
return zero;
}
check_type_tag :: ($$T: Type, tag: Type_Info_Tag) -> bool, *Type_Info {
#if is_constant(T) {
info :: type_info(T);
if info.type == tag return true, info;
}
else {
info := T.(*Type_Info);
if info.type == tag return true, info;
}
return false, null;
}
type_is_integer :: ($$T: Type) -> bool, *Type_Info_Integer {
ok, info := check_type_tag(T, .INTEGER);
return ok, info.(*Type_Info_Integer);
}
type_is_float :: ($$T: Type) -> bool, *Type_Info_Float {
ok, info := check_type_tag(T, .FLOAT);
return ok, info.(*Type_Info_Float);
}
type_is_array :: ($$T: Type) -> bool, *Type_Info_Array {
ok, info := check_type_tag(T, .ARRAY);
return ok, info.(*Type_Info_Array);
}
type_is_struct :: ($$T: Type) -> bool, *Type_Info_Struct {
ok, info := check_type_tag(T, .STRUCT);
return ok, info.(*Type_Info_Struct);
}
// Can be passed directly to using,map
remap_snake_to_pascal :: (names: []string) {
for names {
names[it_index] = snake_to_pascal(it);
}
}
snake_to_pascal :: (name: string) -> string {
b: basic.String_Builder;
upper := true;
for i: 0..name.count - 1 {
c := name[i];
if c == #char "_" {
upper = true;
continue;
}
if upper {
basic.append(*b, basic.to_upper(c));
upper = false;
} else {
basic.append(*b, c);
}
}
return basic.builder_to_string(*b);
}
rune_width :: (r: rune) -> int {
if r < 0 return -1;
@ -13,30 +90,10 @@ rune_width :: (r: rune) -> int {
return -1;
}
use_pascal_names :: (names: []string) {
for name: names {
b: basic.String_Builder;
upper := false;
for i: 0..name.count - 1 {
c := name[i];
if c == #char "_" {
upper = true;
continue;
}
#scope_file;
if i == 0 {
upper = true;
}
if upper {
basic.append(*b, basic.to_upper(c));
upper = false;
} else {
basic.append(*b, c);
}
}
names[it_index] = basic.builder_to_string(*b);
}
#if RUN_TESTS #run {
test.run("snake_to_pascal", t => {
});
}