changed 'verify' to 'this_block' + it now uses for_expansion rules, documentation
This commit is contained in:
parent
6e7cad63b4
commit
4c4aa60c7b
4 changed files with 84 additions and 16 deletions
|
|
@ -4,6 +4,7 @@
|
||||||
|
|
||||||
#import,file "./module.jai"(true);
|
#import,file "./module.jai"(true);
|
||||||
#import,file "./encoding/module.jai"(true);
|
#import,file "./encoding/module.jai"(true);
|
||||||
|
#import,file "./hash/module.jai"(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,2 +1,4 @@
|
||||||
|
#module_parameters(RUN_TESTS := false);
|
||||||
|
|
||||||
#load "murmur.jai";
|
#load "murmur.jai";
|
||||||
#load "xxhash.jai";
|
#load "xxhash.jai";
|
||||||
|
|
|
||||||
80
macros.jai
80
macros.jai
|
|
@ -1,4 +1,10 @@
|
||||||
// Allows structs to be copy assigned.
|
/*
|
||||||
|
Allows structs to be copied and assigned inline.
|
||||||
|
|
||||||
|
For example, copying a Vector3 while changing a single value:
|
||||||
|
old := Vector3.{ 10, 20, 30 }; // 10, 20, 30
|
||||||
|
new := with(old, .{ y = -20 }); // 10, -20, 30
|
||||||
|
*/
|
||||||
with :: (old: $T, $new: Code, location := #caller_location) -> T
|
with :: (old: $T, $new: Code, location := #caller_location) -> T
|
||||||
#modify { return T.(*Type_Info).type == .STRUCT, "with can only be used on structs"; }
|
#modify { return T.(*Type_Info).type == .STRUCT, "with can only be used on structs"; }
|
||||||
#expand {
|
#expand {
|
||||||
|
|
@ -57,34 +63,94 @@ with :: (old: $T, $new: Code, location := #caller_location) -> T
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// @note(judah): I like doing this with an operator, but your mileage may vary
|
||||||
operator | :: with;
|
operator | :: with;
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
Creates a named block that can exit early (via 'break' or 'continue').
|
||||||
|
|
||||||
|
This mostly replaces the case where you'd like to jump to
|
||||||
|
the end of a scope based on some logic within. Without
|
||||||
|
gotos, this is the next best thing.
|
||||||
|
|
||||||
|
Usage:
|
||||||
|
// within a loop
|
||||||
|
for this_block() { // this is named 'block' by default
|
||||||
|
if !moving break;
|
||||||
|
// do movement here
|
||||||
|
}
|
||||||
|
for this_block("render_player") {
|
||||||
|
if invisible break render_player;
|
||||||
|
// do rendering here
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
this_block :: ($name: string = Default_Name) -> Named_Block(name) #expand { return .{}; }
|
||||||
|
|
||||||
|
// Call #c_call procedures inline with the current context: 'c_call(some_c_call_proc(10, 20))'
|
||||||
|
c_call :: (call: Code) #expand {
|
||||||
|
push_context context { #insert,scope(call) call; }
|
||||||
|
}
|
||||||
|
|
||||||
|
// Call #c_call procedures inline with a custom context: 'c_call(some_c_call_proc(10, 20), c_context)'
|
||||||
|
c_call :: (call: Code, ctx: #Context) #expand {
|
||||||
|
push_context ctx { #insert,scope(call) call; }
|
||||||
|
}
|
||||||
|
|
||||||
#scope_file;
|
#scope_file;
|
||||||
|
|
||||||
|
Default_Name :: "block";
|
||||||
|
Named_Block :: struct(NAME: string) {}
|
||||||
|
|
||||||
|
for_expansion :: (v: *Named_Block, code: Code, _: For_Flags) #expand {
|
||||||
|
#insert #run basic.tprint(#string END
|
||||||
|
for `%: 0..0 {
|
||||||
|
`it :: #run zero_of(void);
|
||||||
|
`it_index :: #run zero_of(void);
|
||||||
|
#insert,scope(code) code;
|
||||||
|
}
|
||||||
|
END,
|
||||||
|
// @note(judah): guards against calling this_block with
|
||||||
|
// an empty string which results in weird error messages.
|
||||||
|
ifx v.NAME.count != 0 v.NAME else Default_Name);
|
||||||
|
}
|
||||||
|
|
||||||
pp :: #import "Program_Print";
|
pp :: #import "Program_Print";
|
||||||
compiler :: #import "Compiler";
|
compiler :: #import "Compiler";
|
||||||
|
|
||||||
#if RUN_TESTS #run {
|
#if RUN_TESTS #run {
|
||||||
test.run("verify", (t) => {
|
test.run("this_block", (t) => {
|
||||||
i := 0;
|
i := 0;
|
||||||
verify(#code {
|
|
||||||
|
for this_block() {
|
||||||
i += 1;
|
i += 1;
|
||||||
|
for this_block() {
|
||||||
|
break block;
|
||||||
|
}
|
||||||
|
|
||||||
|
for this_block() {
|
||||||
|
continue block;
|
||||||
|
}
|
||||||
|
|
||||||
if i == 1 {
|
if i == 1 {
|
||||||
break;
|
break block;
|
||||||
}
|
}
|
||||||
|
|
||||||
i += 2;
|
i += 2;
|
||||||
});
|
}
|
||||||
|
|
||||||
j := 0;
|
j := 0;
|
||||||
verify(#code {
|
for this_block("named") {
|
||||||
for 0..10 {
|
for 0..10 {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if i != 1 {
|
||||||
|
break named;
|
||||||
|
}
|
||||||
|
|
||||||
j = 1;
|
j = 1;
|
||||||
});
|
}
|
||||||
|
|
||||||
test.expect(t, i == 1, "i was %", i);
|
test.expect(t, i == 1, "i was %", i);
|
||||||
test.expect(t, j == 1, "j was %", j);
|
test.expect(t, j == 1, "j was %", j);
|
||||||
|
|
|
||||||
17
utils.jai
17
utils.jai
|
|
@ -1,12 +1,5 @@
|
||||||
verify :: (block: Code) #expand {
|
// These return the bool first so you can check in a conditional,
|
||||||
for 0..0 #insert,scope(block) block;
|
// rather than having to do '_, ok := ...'
|
||||||
}
|
|
||||||
|
|
||||||
c_call :: (block: Code) #expand {
|
|
||||||
push_context context {
|
|
||||||
#insert,scope() block;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
check_type_tag :: ($$T: Type, tag: Type_Info_Tag) -> bool, *Type_Info {
|
check_type_tag :: ($$T: Type, tag: Type_Info_Tag) -> bool, *Type_Info {
|
||||||
#if is_constant(T) {
|
#if is_constant(T) {
|
||||||
|
|
@ -90,5 +83,11 @@ rune_width :: (r: rune) -> int {
|
||||||
|
|
||||||
#if RUN_TESTS #run {
|
#if RUN_TESTS #run {
|
||||||
test.run("snake_to_pascal", t => {
|
test.run("snake_to_pascal", t => {
|
||||||
|
test.expect(t, snake_to_pascal("some_name") == "SomeName");
|
||||||
|
test.expect(t, snake_to_pascal("_some_name") == "SomeName");
|
||||||
|
test.expect(t, snake_to_pascal("some__name") == "SomeName");
|
||||||
|
test.expect(t, snake_to_pascal("some_name_") == "SomeName");
|
||||||
|
test.expect(t, snake_to_pascal("X_Y_Z") == "XYZ");
|
||||||
|
test.expect(t, snake_to_pascal("XY_Z") == "XYZ");
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue