verify :: (block: Code) #expand { for 0..0 #insert,scope(block) block; } c_call :: (block: Code) #expand { push_context context { #insert,scope() block; } } 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; if r <= 0x7F return 1; if r <= 0x7FF return 2; if r >= 0xD800 && r <= 0xDFFF return -1; if r <= 0xFFFF return 3; if r <= 0x10FFFF return 4; return -1; } #scope_file; #if RUN_TESTS #run { test.run("snake_to_pascal", t => { }); }