├── source ├── compiler │ ├── std │ │ ├── .gitignore │ │ ├── term.axec │ │ ├── memory.axec │ │ ├── parallelism.axec │ │ ├── random.axec │ │ ├── errors.axec │ │ ├── typecons.axec │ │ ├── uuid.axec │ │ ├── algorithms.axec │ │ ├── time.axec │ │ ├── arena.axec │ │ ├── io.axec │ │ ├── lists.axec │ │ ├── regex.axec │ │ ├── math.axec │ │ ├── json.axec │ │ └── maps.axec │ ├── .gitignore │ ├── axe.mod │ ├── external │ │ ├── lib-linux │ │ │ ├── libcurl.a │ │ │ ├── libpcre.a │ │ │ └── libyyjson.a │ │ ├── lib-macos │ │ │ ├── libcurl.a │ │ │ ├── libpcre.a │ │ │ └── libyyjson.a │ │ ├── x64-windows │ │ │ ├── pcre.lib │ │ │ ├── zlib.lib │ │ │ ├── libcurl.lib │ │ │ └── yyjson.lib │ │ ├── curl │ │ │ └── include │ │ │ │ └── curl │ │ │ │ ├── stdcheaders.h │ │ │ │ ├── options.h │ │ │ │ ├── header.h │ │ │ │ ├── curlver.h │ │ │ │ ├── mprintf.h │ │ │ │ ├── websockets.h │ │ │ │ ├── easy.h │ │ │ │ └── urlapi.h │ │ └── pcre │ │ │ └── include │ │ │ ├── config.h │ │ │ ├── pcre_stringpiece.h │ │ │ └── pcrecpparg.h │ ├── gstate.axe │ ├── axc.axe │ └── structs.axe └── tests │ ├── legacy_tests │ ├── .gitignore │ ├── h2.axe │ ├── test.axe │ ├── hello2.axe │ ├── plat.axe │ ├── using.axe │ ├── global_usage.axe │ ├── external_import.axe │ ├── test_interp_guard.axe │ ├── test_interp.axe │ ├── use_all.axe │ ├── raw_c.axec │ ├── undec.axe │ ├── hello3.axe │ ├── test_comments.axe │ ├── math.axe │ ├── test_return.axe │ ├── funcs.axe │ ├── test_raw_reject.axe │ ├── test_dot_simple.axe │ ├── stress5.axe │ ├── pub_test_main.axe │ ├── test_keywords.axe │ ├── test_union_keywords.axe │ ├── bug_demo.axe │ ├── hello.axe │ ├── s_test.axe │ ├── multiline_string.axe │ ├── test_inference.axe │ ├── tests.axe │ ├── hi.axe │ ├── nested_calls.axe │ ├── inference.axe │ ├── member_inc_dec.axe │ ├── test_pointer_syntax.axe │ ├── test_double_pointer.axe │ ├── test_cast.axe │ ├── test_dot_syntax.axe │ ├── enums.axe │ ├── forin_bug.axe │ ├── test_union_model.axe │ ├── pure_parallel.axe │ ├── for_to_syntax.axe │ ├── test2.axe │ ├── test_dynamic_lists.axe │ ├── case_switch.axe │ ├── platform_in_model.axe │ ├── refs.axe │ ├── fizzbuzz.axe │ ├── func_args.axe │ ├── structs.axe │ ├── parallel_for_reduce.axe │ ├── arr_lits.axe │ ├── pub_test_lib.axe │ ├── test_opaque_extern.axe │ ├── gen.axe │ ├── guess_game.axe │ ├── macros.axec │ ├── crossplat.axe │ ├── for_in_lists.axe │ ├── local.axe │ ├── fib.axe │ ├── test_list_of.axe │ ├── linked.axe │ ├── matrix.axe │ ├── stress4.axe │ ├── stress2.axe │ ├── game_of_life.axe │ ├── stress.axe │ └── stress3.axe │ └── self_tests │ ├── test_no_entry.axe │ ├── .gitignore │ ├── test_undefined_func.axe │ ├── test_null.axe │ ├── test_put.axe │ ├── test_mscl.axe │ ├── test_undeclared.axe │ ├── test_unused.axe │ ├── test_io.axe │ ├── test_lite.axe │ ├── test_input.axe │ ├── test_ms.axe │ ├── mods │ └── lite_io.axe │ ├── test_syntax_error.axe │ ├── test_strcat.axe │ ├── test_dir.axe │ ├── test_semicolons.axe │ ├── test_wtype_simple.axe │ ├── test_models_fields.axe │ ├── test_ptr_fail.axe │ ├── test_correct_types.axe │ ├── test_tags.axe │ ├── test_ptr.axe │ ├── test_first.axe │ ├── test_wtype.axe │ ├── test_tld.axe │ ├── test_zero.axe │ ├── test_line_error.axe │ ├── test_generics_ii.axe │ ├── test_unsafe.axe │ ├── test_import_check.axe │ ├── test_inline.axe │ ├── test_dll.axe │ ├── test_plat.axe │ ├── test_parfor.axe │ ├── test_hoisting.axe │ ├── test_parallel_single.axe │ ├── test_generics.axe │ ├── test_complex.axe │ ├── test_shadowing.axe │ ├── test_blocks.axe │ ├── test_models.axe │ ├── test_compound_assign.axe │ ├── test_generics_adv.axe │ ├── test_function_tags.axe │ └── test_gol.axe ├── .gitignore ├── .github └── FUNDING.yml └── README.md /source/compiler/std/.gitignore: -------------------------------------------------------------------------------- 1 | *.c 2 | -------------------------------------------------------------------------------- /source/compiler/.gitignore: -------------------------------------------------------------------------------- 1 | *.c 2 | *.dll 3 | *.dSYM -------------------------------------------------------------------------------- /source/tests/legacy_tests/.gitignore: -------------------------------------------------------------------------------- 1 | *.c 2 | *.asm 3 | -------------------------------------------------------------------------------- /source/tests/self_tests/test_no_entry.axe: -------------------------------------------------------------------------------- 1 | use std.io; 2 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.exe 2 | .dub 3 | *.pdb 4 | *.o 5 | .vscode 6 | *.dSYM -------------------------------------------------------------------------------- /source/tests/legacy_tests/h2.axe: -------------------------------------------------------------------------------- 1 | pub val g_global: i32 = 20; 2 | -------------------------------------------------------------------------------- /source/tests/legacy_tests/test.axe: -------------------------------------------------------------------------------- 1 | def main() { println "unittest"; } -------------------------------------------------------------------------------- /source/tests/self_tests/.gitignore: -------------------------------------------------------------------------------- 1 | *.c 2 | *.dll 3 | *.lib 4 | *.obj -------------------------------------------------------------------------------- /source/compiler/axe.mod: -------------------------------------------------------------------------------- 1 | name: axe 2 | version: 0.0.9 3 | entry: axc.axe -------------------------------------------------------------------------------- /source/tests/self_tests/test_undefined_func.axe: -------------------------------------------------------------------------------- 1 | def main() { 2 | foo(); 3 | } -------------------------------------------------------------------------------- /source/tests/legacy_tests/hello2.axe: -------------------------------------------------------------------------------- 1 | def main() { 2 | println "Hello", "world"; 3 | } -------------------------------------------------------------------------------- /source/tests/self_tests/test_null.axe: -------------------------------------------------------------------------------- 1 | def main() { 2 | val x: i32 = nil; 3 | } 4 | -------------------------------------------------------------------------------- /source/tests/self_tests/test_put.axe: -------------------------------------------------------------------------------- 1 | def main() { 2 | put "Hello, world."; 3 | } 4 | -------------------------------------------------------------------------------- /source/tests/self_tests/test_mscl.axe: -------------------------------------------------------------------------------- 1 | def main() { 2 | val x: i32 = 12 3 | val y: i32 = 0; 4 | } -------------------------------------------------------------------------------- /source/tests/self_tests/test_undeclared.axe: -------------------------------------------------------------------------------- 1 | def main() { 2 | val x: i32 = y; //should fail 3 | } -------------------------------------------------------------------------------- /source/tests/self_tests/test_unused.axe: -------------------------------------------------------------------------------- 1 | def main() { 2 | val x: i32 = 42; 3 | put "hello"; 4 | } -------------------------------------------------------------------------------- /source/tests/legacy_tests/plat.axe: -------------------------------------------------------------------------------- 1 | use crossplat; 2 | 3 | def main() { 4 | cross_platform_func(); 5 | } -------------------------------------------------------------------------------- /source/tests/self_tests/test_io.axe: -------------------------------------------------------------------------------- 1 | use std.io; 2 | 3 | def main() { 4 | println("hello, world."); 5 | } 6 | -------------------------------------------------------------------------------- /source/tests/self_tests/test_lite.axe: -------------------------------------------------------------------------------- 1 | use mods.lite_io; 2 | 3 | def main() { 4 | print "Hi, world."; 5 | } -------------------------------------------------------------------------------- /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | #patreon: # Replace with a single Patreon username 2 | 3 | ko_fi: navid_m 4 | github: navid-m 5 | -------------------------------------------------------------------------------- /source/tests/legacy_tests/using.axe: -------------------------------------------------------------------------------- 1 | use math (add, subtract); 2 | 3 | def main() { 4 | println add(1, 2); 5 | } 6 | -------------------------------------------------------------------------------- /source/tests/legacy_tests/global_usage.axe: -------------------------------------------------------------------------------- 1 | use h2; 2 | use std.io; 3 | 4 | def main() { 5 | println ::g_global; 6 | } 7 | -------------------------------------------------------------------------------- /source/tests/self_tests/test_input.axe: -------------------------------------------------------------------------------- 1 | def hello() { 2 | val x = 42; 3 | } 4 | 5 | def main() { 6 | hello(); 7 | } 8 | -------------------------------------------------------------------------------- /source/tests/self_tests/test_ms.axe: -------------------------------------------------------------------------------- 1 | use test_mscl; 2 | 3 | def main() { 4 | val x: i32 = 12; 5 | val y: i32 = 0; 6 | } -------------------------------------------------------------------------------- /source/tests/self_tests/mods/lite_io.axe: -------------------------------------------------------------------------------- 1 | def print(str: ref char) { 2 | unsafe { 3 | C.printf(str); 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /source/compiler/external/lib-linux/libcurl.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/axelang/axe/HEAD/source/compiler/external/lib-linux/libcurl.a -------------------------------------------------------------------------------- /source/compiler/external/lib-linux/libpcre.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/axelang/axe/HEAD/source/compiler/external/lib-linux/libpcre.a -------------------------------------------------------------------------------- /source/compiler/external/lib-macos/libcurl.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/axelang/axe/HEAD/source/compiler/external/lib-macos/libcurl.a -------------------------------------------------------------------------------- /source/compiler/external/lib-macos/libpcre.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/axelang/axe/HEAD/source/compiler/external/lib-macos/libpcre.a -------------------------------------------------------------------------------- /source/compiler/external/x64-windows/pcre.lib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/axelang/axe/HEAD/source/compiler/external/x64-windows/pcre.lib -------------------------------------------------------------------------------- /source/compiler/external/x64-windows/zlib.lib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/axelang/axe/HEAD/source/compiler/external/x64-windows/zlib.lib -------------------------------------------------------------------------------- /source/tests/legacy_tests/external_import.axe: -------------------------------------------------------------------------------- 1 | use external("raylib.h"); 2 | 3 | def main() { 4 | InitWindow("Hello, Raylib."); 5 | } -------------------------------------------------------------------------------- /source/tests/legacy_tests/test_interp_guard.axe: -------------------------------------------------------------------------------- 1 | def main() { 2 | val name = "World"; 3 | println $"Hello, ${name}!"; 4 | } 5 | -------------------------------------------------------------------------------- /source/compiler/external/lib-linux/libyyjson.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/axelang/axe/HEAD/source/compiler/external/lib-linux/libyyjson.a -------------------------------------------------------------------------------- /source/compiler/external/lib-macos/libyyjson.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/axelang/axe/HEAD/source/compiler/external/lib-macos/libyyjson.a -------------------------------------------------------------------------------- /source/compiler/external/x64-windows/libcurl.lib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/axelang/axe/HEAD/source/compiler/external/x64-windows/libcurl.lib -------------------------------------------------------------------------------- /source/compiler/external/x64-windows/yyjson.lib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/axelang/axe/HEAD/source/compiler/external/x64-windows/yyjson.lib -------------------------------------------------------------------------------- /source/tests/self_tests/test_syntax_error.axe: -------------------------------------------------------------------------------- 1 | // Test file with syntax error for LSP testing 2 | def main() { 3 | val x: i32 = 4 | } 5 | -------------------------------------------------------------------------------- /source/tests/legacy_tests/test_interp.axe: -------------------------------------------------------------------------------- 1 | use std.string; 2 | 3 | def main() { 4 | val x = 42; 5 | print_str(str($"x = ${x}")); 6 | } 7 | -------------------------------------------------------------------------------- /source/tests/legacy_tests/use_all.axe: -------------------------------------------------------------------------------- 1 | use std.io; 2 | use std.string; 3 | 4 | def main() { 5 | println_str(str("Wow its usable")); 6 | } 7 | -------------------------------------------------------------------------------- /source/tests/legacy_tests/raw_c.axec: -------------------------------------------------------------------------------- 1 | def main() { 2 | println "Hello, world"; 3 | raw { 4 | printf("Hello, world\n"); 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /source/tests/legacy_tests/undec.axe: -------------------------------------------------------------------------------- 1 | def shouldnt_error() { 2 | put "Hello, world!"; 3 | } 4 | 5 | def main() { 6 | shouldnt_error(); 7 | } 8 | -------------------------------------------------------------------------------- /source/tests/self_tests/test_strcat.axe: -------------------------------------------------------------------------------- 1 | use std.io; 2 | 3 | def strcat() { 4 | println("hello"); 5 | } 6 | 7 | def main() { 8 | strcat(); 9 | } -------------------------------------------------------------------------------- /source/tests/legacy_tests/hello3.axe: -------------------------------------------------------------------------------- 1 | def sup(x: i32, y: i32, z: i32) { 2 | println "it works"; 3 | } 4 | 5 | def main() { 6 | sup 1, 2, 3; 7 | } 8 | -------------------------------------------------------------------------------- /source/tests/self_tests/test_dir.axe: -------------------------------------------------------------------------------- 1 | use std.io; 2 | 3 | def some_func() { 4 | println("hello."); 5 | } 6 | 7 | def main() { 8 | some_func(); 9 | } -------------------------------------------------------------------------------- /source/tests/legacy_tests/test_comments.axe: -------------------------------------------------------------------------------- 1 | // This is a comment 2 | def main() { 3 | // Another comment 4 | println "Hello"; // inline comment 5 | } 6 | -------------------------------------------------------------------------------- /source/tests/self_tests/test_semicolons.axe: -------------------------------------------------------------------------------- 1 | def main() { 2 | val x: i32 = 1 + 1 3 | val y: i32 = x * 2; // Should not compile. Missing semicolon above. 4 | } 5 | -------------------------------------------------------------------------------- /source/tests/self_tests/test_wtype_simple.axe: -------------------------------------------------------------------------------- 1 | def add(a: i32, b: i32): i32 { 2 | return a + b; 3 | } 4 | 5 | def main() { 6 | add("wrong", "wrong again"); 7 | } 8 | -------------------------------------------------------------------------------- /source/tests/legacy_tests/math.axe: -------------------------------------------------------------------------------- 1 | def add(a: int, b: int): int 2 | { 3 | return a + b; 4 | } 5 | 6 | def subtract(a: int, b: int): int 7 | { 8 | return a - b; 9 | } -------------------------------------------------------------------------------- /source/tests/legacy_tests/test_return.axe: -------------------------------------------------------------------------------- 1 | model Test { 2 | data: union { 3 | return_node: model { 4 | expr: string; 5 | }; 6 | }; 7 | } 8 | -------------------------------------------------------------------------------- /source/tests/self_tests/test_models_fields.axe: -------------------------------------------------------------------------------- 1 | model SomeModel { 2 | x: i32; 3 | y: i32; 4 | } 5 | 6 | def main() { 7 | val md = SomeModel{x: 20, y: 40}; 8 | } 9 | -------------------------------------------------------------------------------- /source/tests/legacy_tests/funcs.axe: -------------------------------------------------------------------------------- 1 | use std.io; 2 | 3 | def some_function { 4 | println "Hello, world."; 5 | } 6 | 7 | def main() { 8 | some_function(); 9 | } 10 | -------------------------------------------------------------------------------- /source/tests/legacy_tests/test_raw_reject.axe: -------------------------------------------------------------------------------- 1 | // This should fail - raw blocks not allowed in .axe files 2 | def main() { 3 | raw { 4 | printf("test\n"); 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /source/tests/self_tests/test_ptr_fail.axe: -------------------------------------------------------------------------------- 1 | // This should fail to compile. 2 | 3 | def some_func(c: char*) { 4 | println(c); 5 | } 6 | 7 | def main() { 8 | some_func("hi"); 9 | } -------------------------------------------------------------------------------- /source/tests/legacy_tests/test_dot_simple.axe: -------------------------------------------------------------------------------- 1 | use std.io (println_str); 2 | use std.string (string); 3 | 4 | def main() { 5 | val x = 10; 6 | println $"Testing dot {x} notation!"; 7 | } 8 | -------------------------------------------------------------------------------- /source/tests/self_tests/test_correct_types.axe: -------------------------------------------------------------------------------- 1 | use std.io; 2 | 3 | def add(a: i32, b: i32): i32 { 4 | return a + b; 5 | } 6 | 7 | def main() { 8 | println(add(1, 2)); 9 | } 10 | -------------------------------------------------------------------------------- /source/tests/self_tests/test_tags.axe: -------------------------------------------------------------------------------- 1 | use std.io; 2 | 3 | [inline] 4 | def some_function() { 5 | println("Hi, world."); 6 | } 7 | 8 | def main() { 9 | some_function(); 10 | } 11 | -------------------------------------------------------------------------------- /source/tests/legacy_tests/stress5.axe: -------------------------------------------------------------------------------- 1 | use std.io; 2 | 3 | def f ( ) { 4 | println "looks spaced normally right"; 5 | } 6 | 7 | def main() { 8 | f(); 9 | } 10 | -------------------------------------------------------------------------------- /source/tests/self_tests/test_ptr.axe: -------------------------------------------------------------------------------- 1 | pub def double_to_str(value: f64, buffer: char*): char* { 2 | unsafe { 3 | C.sprintf(buffer, "%lf", value); 4 | } 5 | return buffer; 6 | } 7 | -------------------------------------------------------------------------------- /source/tests/legacy_tests/pub_test_main.axe: -------------------------------------------------------------------------------- 1 | use pub_test_lib; 2 | 3 | def main() { 4 | pub_test_lib.public_func(); 5 | 6 | mut m = PublicModel{}; 7 | PublicModel.public_method(); 8 | } 9 | -------------------------------------------------------------------------------- /source/tests/legacy_tests/test_keywords.axe: -------------------------------------------------------------------------------- 1 | model Test { 2 | data: union { 3 | function: i32; 4 | macro: i32; 5 | opaque: i32; 6 | extern_node: i32; 7 | }; 8 | } 9 | -------------------------------------------------------------------------------- /source/tests/legacy_tests/test_union_keywords.axe: -------------------------------------------------------------------------------- 1 | model Test { 2 | data: union { 3 | function: model { 4 | name: string; 5 | }; 6 | macro: i32; 7 | }; 8 | } 9 | -------------------------------------------------------------------------------- /source/tests/self_tests/test_first.axe: -------------------------------------------------------------------------------- 1 | use std.string; 2 | 3 | def greet(name: string): void { 4 | println $"Hello, {name}"; 5 | } 6 | 7 | def main() { 8 | greet(str("Axe")); 9 | } 10 | -------------------------------------------------------------------------------- /source/tests/self_tests/test_wtype.axe: -------------------------------------------------------------------------------- 1 | use std.io; 2 | 3 | def add(a: i32, b: i32): i32 { 4 | return a + b; 5 | } 6 | 7 | def main() { 8 | println(add("wrong", "wrong again")); 9 | } 10 | -------------------------------------------------------------------------------- /source/tests/legacy_tests/bug_demo.axe: -------------------------------------------------------------------------------- 1 | use std.io; 2 | use std.string; 3 | 4 | def main() { 5 | val x: ref char = "hello"; 6 | val y: ref char = $"Hello, {x} world"; 7 | println(str(y)); 8 | } 9 | -------------------------------------------------------------------------------- /source/tests/legacy_tests/hello.axe: -------------------------------------------------------------------------------- 1 | use std.io; 2 | 3 | def main() { 4 | println "Hello, world."; 5 | 6 | loop { 7 | println "What is up..."; 8 | break; 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /source/tests/self_tests/test_tld.axe: -------------------------------------------------------------------------------- 1 | use std.io; 2 | 3 | val result = some_func(); 4 | 5 | def some_func(): i32 { 6 | return 42; 7 | } 8 | 9 | def main() { 10 | println(result); 11 | } 12 | -------------------------------------------------------------------------------- /source/tests/self_tests/test_zero.axe: -------------------------------------------------------------------------------- 1 | use std.io; 2 | 3 | model SomeModel { 4 | x: i32; 5 | y: i32; 6 | } 7 | 8 | def main() { 9 | val md = SomeModel{}; 10 | println $"{md.x}"; 11 | } -------------------------------------------------------------------------------- /source/tests/legacy_tests/s_test.axe: -------------------------------------------------------------------------------- 1 | use std.string; 2 | 3 | use std.io( 4 | println_str 5 | ); 6 | 7 | def main() { 8 | val x: string = string.create("Hello, world!"); 9 | println_str(x); 10 | } 11 | -------------------------------------------------------------------------------- /source/tests/self_tests/test_line_error.axe: -------------------------------------------------------------------------------- 1 | use std.io; 2 | 3 | def main() { 4 | val x: i32 = 10; 5 | val y: i32 = 20; 6 | val z: i32 = undefined_variable; 7 | 8 | println("Done"); 9 | } 10 | -------------------------------------------------------------------------------- /source/tests/legacy_tests/multiline_string.axe: -------------------------------------------------------------------------------- 1 | use std.io(println); 2 | 3 | def main() { 4 | mut message: ref char = `This is a 5 | multiline string 6 | with multiple lines`; 7 | 8 | println message; 9 | } 10 | -------------------------------------------------------------------------------- /source/tests/legacy_tests/test_inference.axe: -------------------------------------------------------------------------------- 1 | use std.io; 2 | 3 | model SomeType { 4 | stuff: i32; 5 | } 6 | 7 | def main() { 8 | val instance = new SomeType(stuff:42); 9 | println instance.stuff; 10 | } 11 | -------------------------------------------------------------------------------- /source/tests/legacy_tests/tests.axe: -------------------------------------------------------------------------------- 1 | def add(x: i32, y: i32): i32 { 2 | return x + y; 3 | } 4 | 5 | test { 6 | assert add(1, 2) == 3, "add(1, 2) should be 3"; 7 | assert add(1, 2) != 5, "add(1, 2) should not be 5"; 8 | } 9 | -------------------------------------------------------------------------------- /source/tests/self_tests/test_generics_ii.axe: -------------------------------------------------------------------------------- 1 | use std.io; 2 | 3 | def genfunc[T]() { 4 | when T is ref char { 5 | println("Type is ref char"); 6 | } 7 | } 8 | 9 | def main() { 10 | genfunc[ref char](); 11 | } -------------------------------------------------------------------------------- /source/tests/legacy_tests/hi.axe: -------------------------------------------------------------------------------- 1 | use stdlib/string ( 2 | string 3 | ); 4 | 5 | def greet(name: string): void { 6 | println "Hello, ", name.data, "."; 7 | } 8 | 9 | def main() { 10 | greet(string.create("Axe")); 11 | } -------------------------------------------------------------------------------- /source/tests/self_tests/test_unsafe.axe: -------------------------------------------------------------------------------- 1 | def hello() { 2 | unsafe { 3 | C.printf("Sup"); 4 | } 5 | } 6 | 7 | def main() { 8 | unsafe { 9 | C.printf("It works!"); 10 | } 11 | hello(); 12 | } 13 | -------------------------------------------------------------------------------- /source/tests/legacy_tests/nested_calls.axe: -------------------------------------------------------------------------------- 1 | def thing_of(x: i32): long { 2 | return 0; 3 | } 4 | 5 | def destroy(ptr: i64) { 6 | println "destroyed"; 7 | } 8 | 9 | def main() { 10 | val x: i32 = 5; 11 | destroy(thing_of(x)); 12 | } 13 | -------------------------------------------------------------------------------- /source/tests/self_tests/test_import_check.axe: -------------------------------------------------------------------------------- 1 | /// Test file for import checking 2 | 3 | def test_missing_import() { 4 | mut arena: Arena = Arena.create(1024); 5 | } 6 | 7 | def main() { 8 | println "If you see this, the test passed"; 9 | } 10 | -------------------------------------------------------------------------------- /source/tests/self_tests/test_inline.axe: -------------------------------------------------------------------------------- 1 | use std.io; 2 | use std.string; 3 | 4 | def main() { 5 | val x: i32 = add_inline(10, 20); 6 | println(i32_to_string(x)); 7 | } 8 | 9 | [inline] 10 | def add_inline(a: i32, b: i32): i32 { 11 | return a + b; 12 | } 13 | -------------------------------------------------------------------------------- /source/tests/self_tests/test_dll.axe: -------------------------------------------------------------------------------- 1 | foreign { 2 | BOOL, 3 | WINAPI, 4 | HINSTANCE, 5 | DWORD, 6 | LPVOID, 7 | TRUE, 8 | FALSE 9 | } 10 | 11 | [entry] 12 | def DllMain(hinst: HINSTANCE, reason: DWORD, reserved: LPVOID): BOOL { 13 | return TRUE; 14 | } 15 | -------------------------------------------------------------------------------- /source/tests/self_tests/test_plat.axe: -------------------------------------------------------------------------------- 1 | use std.io; 2 | 3 | def main() { 4 | platform dragonflybsd { 5 | print "DragonFly BSD\n"; 6 | } 7 | platform macos { 8 | print "macos"; 9 | } 10 | platform windows { 11 | print "windows"; 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /source/tests/legacy_tests/inference.axe: -------------------------------------------------------------------------------- 1 | use std.string; 2 | 3 | model Person { 4 | name: string; 5 | age: i32; 6 | } 7 | 8 | def main() { 9 | parallel for mut i = 0 to 10 { 10 | mut person = Person{name: "Alice", age: i}; 11 | println person.age; 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /source/tests/legacy_tests/member_inc_dec.axe: -------------------------------------------------------------------------------- 1 | model Counter { 2 | value: i32, 3 | } 4 | 5 | def main() { 6 | mut val counter: Counter; 7 | counter.value = 5; 8 | counter.value++; 9 | println counter.value; 10 | counter.value--; 11 | println counter.value; 12 | } 13 | -------------------------------------------------------------------------------- /source/tests/legacy_tests/test_pointer_syntax.axe: -------------------------------------------------------------------------------- 1 | use std.io; 2 | 3 | // This test should fail with an error about deprecated pointer syntax 4 | def test_raw_pointer() { 5 | val x: char* = "hello"; 6 | println str(x); 7 | } 8 | 9 | def main() { 10 | test_raw_pointer(); 11 | } 12 | -------------------------------------------------------------------------------- /source/tests/legacy_tests/test_double_pointer.axe: -------------------------------------------------------------------------------- 1 | use std.io; 2 | 3 | // This test should fail with an error about deprecated double pointer syntax 4 | def test_double_pointer() { 5 | val x: int** = 0; 6 | println str(x); 7 | } 8 | 9 | def main() { 10 | test_double_pointer(); 11 | } 12 | -------------------------------------------------------------------------------- /source/tests/legacy_tests/test_cast.axe: -------------------------------------------------------------------------------- 1 | use std.string; 2 | 3 | def main() { 4 | mut dummy: list(string); 5 | unsafe { 6 | val x: usize = 42; 7 | val y: ref i32 = cast[ref i32](x); 8 | val size: usize = C.sizeof(list(string)); 9 | println size; 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /source/tests/legacy_tests/test_dot_syntax.axe: -------------------------------------------------------------------------------- 1 | use std.string; 2 | 3 | model Person { 4 | name: string; 5 | age: i32; 6 | } 7 | 8 | def main() { 9 | parallel for mut i = 0 to 10 { 10 | mut person = new Person(name: "Alice", age: i); 11 | println person.age; 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /source/tests/legacy_tests/enums.axe: -------------------------------------------------------------------------------- 1 | use std.io; 2 | 3 | enum State { 4 | RUNNING, 5 | CHANGING, 6 | STOPPED 7 | } 8 | 9 | def main() { 10 | mut val fixed_state: State = State.CHANGING; 11 | println State.RUNNING; 12 | println fixed_state; 13 | fixed_state = State.RUNNING; 14 | } 15 | -------------------------------------------------------------------------------- /source/tests/legacy_tests/forin_bug.axe: -------------------------------------------------------------------------------- 1 | use std.arena(Arena); 2 | use std.os(get_cmdline_args); 3 | use std.io(print_str); 4 | 5 | def main() { 6 | mut arena: Arena = Arena.create(65536); 7 | for arg in get_cmdline_args(addr(arena)) { 8 | print_str(arg); 9 | print " "; 10 | } 11 | } -------------------------------------------------------------------------------- /source/tests/legacy_tests/test_union_model.axe: -------------------------------------------------------------------------------- 1 | use std.io; 2 | 3 | model Test { 4 | data: union { 5 | simple_field: model { 6 | name: string; 7 | value: i32; 8 | }; 9 | another: i32; 10 | }; 11 | } 12 | 13 | test { 14 | println "Test passed"; 15 | } 16 | -------------------------------------------------------------------------------- /source/tests/self_tests/test_parfor.axe: -------------------------------------------------------------------------------- 1 | use std.io; 2 | use std.string; 3 | 4 | model Person { 5 | name: string; 6 | age: i32; 7 | } 8 | 9 | def main() { 10 | parallel for mut i = 0 to 10 { 11 | val person = Person{name: "Alice", age: i}; 12 | println person.age; 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /source/tests/legacy_tests/pure_parallel.axe: -------------------------------------------------------------------------------- 1 | def some_task() { 2 | println "hello"; 3 | } 4 | 5 | def some_other_task() { 6 | println "world"; 7 | } 8 | 9 | def main() { 10 | parallel { 11 | single { 12 | some_task(); 13 | some_other_task(); 14 | } 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /source/tests/legacy_tests/for_to_syntax.axe: -------------------------------------------------------------------------------- 1 | // Test for 'to' syntax 2 | // for mut x = 0 to 10 should desugar to: for mut x = 0; x < 10; x++ 3 | 4 | def main() { 5 | println "Testing 'for to' syntax:"; 6 | 7 | for mut i = 0 to 5 { 8 | println i; 9 | } 10 | 11 | println "Done!"; 12 | } 13 | -------------------------------------------------------------------------------- /source/tests/self_tests/test_hoisting.axe: -------------------------------------------------------------------------------- 1 | /// Demonstrating function hoisting in the self hosted compiler. 2 | def main() { 3 | some_func(); 4 | } 5 | 6 | def some_func() { 7 | some_other_func(); 8 | } 9 | 10 | def some_other_func() { 11 | unsafe { 12 | C.printf("Hello, world."); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /source/tests/legacy_tests/test2.axe: -------------------------------------------------------------------------------- 1 | use std.string; 2 | use std.io; 3 | 4 | model Person { 5 | name: string; 6 | age: i32; 7 | } 8 | 9 | def main() { 10 | parallel for mut i = 0 to 10 { 11 | mut person = new Person(name: "Alice", age: i); 12 | println_str(str($"Hello {person.age}")); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /source/tests/legacy_tests/test_dynamic_lists.axe: -------------------------------------------------------------------------------- 1 | use std.io; 2 | 3 | def main() { 4 | mut nums: list(i32); 5 | 6 | append(nums, 1); 7 | append(nums, 2); 8 | append(nums, 3); 9 | 10 | println "Length: "; 11 | println len(nums); 12 | 13 | for n in nums { 14 | println n; 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /source/tests/legacy_tests/case_switch.axe: -------------------------------------------------------------------------------- 1 | use std.io; 2 | 3 | def main() { 4 | val x: i32 = 1; 5 | 6 | switch x { 7 | case 1 { 8 | println "one"; 9 | } 10 | case 2 { 11 | println "two"; 12 | } 13 | default { 14 | println "other"; 15 | } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /source/tests/self_tests/test_parallel_single.axe: -------------------------------------------------------------------------------- 1 | use std.io; 2 | 3 | def some_task() { 4 | println "hello"; 5 | } 6 | 7 | def some_other_task() { 8 | println "world"; 9 | } 10 | 11 | def main() { 12 | parallel { 13 | single { 14 | some_task(); 15 | some_other_task(); 16 | } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /source/tests/self_tests/test_generics.axe: -------------------------------------------------------------------------------- 1 | use std.io; 2 | 3 | [inline] 4 | def some_func[T](arg: T): T { 5 | when T is i32 { 6 | return arg + 1; 7 | } 8 | when T is f32 { 9 | return arg * 2.0; 10 | } 11 | } 12 | 13 | def some_other_func(x: i32) { 14 | println(x); 15 | } 16 | 17 | def main() { 18 | println(some_func(5)); 19 | } 20 | -------------------------------------------------------------------------------- /source/tests/legacy_tests/platform_in_model.axe: -------------------------------------------------------------------------------- 1 | model TestModel { 2 | value: i32; 3 | 4 | def test_method() { 5 | platform windows { 6 | println "Method on Windows"; 7 | } 8 | platform posix { 9 | println "Method on POSIX"; 10 | } 11 | } 12 | } 13 | 14 | def main() { 15 | TestModel.test_method(); 16 | } 17 | -------------------------------------------------------------------------------- /source/tests/legacy_tests/refs.axe: -------------------------------------------------------------------------------- 1 | def main() { 2 | val x: int = 10; 3 | mut val y: ref int = addr(x); 4 | val z: ref ref int = addr(y); 5 | 6 | println y; // Auto-dereference: prints 10 7 | y = 20; // Auto-dereference: sets x to 20 8 | val addr: long = addr(x); // Get raw address as integer 9 | } 10 | -------------------------------------------------------------------------------- /source/tests/legacy_tests/fizzbuzz.axe: -------------------------------------------------------------------------------- 1 | def main() { 2 | for mut i = 1; i <= 100; i++ { 3 | if i mod 3 == 0 and i mod 5 == 0 { 4 | println "FizzBuzz"; 5 | } elif i mod 3 == 0 { 6 | println "Fizz"; 7 | } elif i mod 5 == 0 { 8 | println "Buzz"; 9 | } else { 10 | println i; 11 | } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /source/tests/legacy_tests/func_args.axe: -------------------------------------------------------------------------------- 1 | use std.io; 2 | 3 | def greet(name: ref char, t: i32) { 4 | loop { 5 | println name; 6 | if t == 1 { 7 | break; 8 | } 9 | } 10 | } 11 | 12 | def main() { 13 | mut nums: list(i32) = [123, 142, 123123]; 14 | for n in nums { 15 | println n; 16 | } 17 | greet("world", 1); 18 | } 19 | -------------------------------------------------------------------------------- /source/tests/self_tests/test_complex.axe: -------------------------------------------------------------------------------- 1 | use std.string; 2 | 3 | model SomeComplexModel { 4 | hi: i32; 5 | data: string; 6 | } 7 | 8 | def main() { 9 | mut md: SomeComplexModel; 10 | md.hi = 42; 11 | md.data = str("The answer to life, the universe, and everything."); 12 | 13 | println $"Model hi: {md.hi}"; 14 | println $"Model data: {md.data.data}"; 15 | } 16 | -------------------------------------------------------------------------------- /source/tests/legacy_tests/structs.axe: -------------------------------------------------------------------------------- 1 | use std.io; 2 | 3 | model Cat { 4 | annoyingness_level: i32, 5 | health : i32, 6 | name : ref char 7 | } 8 | 9 | def main() { 10 | mut cat = new Cat( 11 | health: 100, 12 | name: "Garfield", 13 | annoyingness_level: 9999 14 | ); 15 | cat.health = 90; 16 | println cat.health; 17 | } 18 | -------------------------------------------------------------------------------- /source/tests/self_tests/test_shadowing.axe: -------------------------------------------------------------------------------- 1 | /// Test file to check if shadowing detection works 2 | /// Expected: error about shadowing imported symbol 3 | 4 | use std.arena (Arena); 5 | 6 | // This should trigger an error: function 'Arena' shadows imported symbol 'Arena' 7 | def Arena() { 8 | println "This is a function named Arena"; 9 | } 10 | 11 | def main() { 12 | Arena(); 13 | } 14 | -------------------------------------------------------------------------------- /source/tests/legacy_tests/parallel_for_reduce.axe: -------------------------------------------------------------------------------- 1 | use std.io; 2 | 3 | def main() { 4 | println "Testing parallel for with reduction:"; 5 | 6 | mut sum: i32 = 0; 7 | mut n: i32 = 100; 8 | 9 | parallel for mut i = 0 to n reduce(+:sum) { 10 | sum += i; 11 | } 12 | 13 | println "Sum from 0 to 99 = "; 14 | println sum; 15 | println "Expected: 4950"; 16 | } 17 | -------------------------------------------------------------------------------- /source/tests/self_tests/test_blocks.axe: -------------------------------------------------------------------------------- 1 | macro add(x: untyped, y: untyped) { 2 | def some_function(): i32 { 3 | return x + y; 4 | } 5 | } 6 | 7 | def some_other_function(): i32 { 8 | return 1; 9 | } 10 | 11 | add(1, 2); 12 | 13 | test { 14 | val x: i32 = 1; 15 | assert x == 1, "Should be true."; 16 | unsafe { 17 | C.printf("%d", some_function()); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /source/tests/self_tests/test_models.axe: -------------------------------------------------------------------------------- 1 | model SomeModel { 2 | x: i32; 3 | y: i32; 4 | 5 | def static_method() { 6 | put "wow its called! :D"; 7 | } 8 | } 9 | 10 | def yo(): i32 { 11 | return 2; 12 | } 13 | 14 | def main() { 15 | mut md = SomeModel{}; 16 | md.x = 1; 17 | md.y = 2; 18 | put "ASDASD"; 19 | SomeModel.static_method(); 20 | val x: i32 = yo(); 21 | } 22 | -------------------------------------------------------------------------------- /source/tests/legacy_tests/arr_lits.axe: -------------------------------------------------------------------------------- 1 | use std.io ( 2 | print_i32 3 | ); 4 | 5 | def arr_length(a: i32[]): usize { 6 | return 4; 7 | } 8 | 9 | def func_that_takes_arr_literal(a: i32[]) { 10 | for mut i = 0; i < arr_length(a); i++ { 11 | print_i32(a[i]); 12 | print " "; 13 | } 14 | println ""; 15 | } 16 | 17 | def main() { 18 | func_that_takes_arr_literal([i32]{10, 20, 30, 40}); //should become (int32_t[]){10, 20, 30, 40} 19 | } -------------------------------------------------------------------------------- /source/tests/legacy_tests/pub_test_lib.axe: -------------------------------------------------------------------------------- 1 | pub def public_func() { 2 | put "public_func called\n"; 3 | } 4 | 5 | def private_func() { 6 | put "private_func called\n"; 7 | } 8 | 9 | pub model PublicModel { 10 | pub def public_method() { 11 | put "public_method called\n"; 12 | } 13 | 14 | def private_method() { 15 | put "private_method called\n"; 16 | } 17 | } 18 | 19 | model PrivateModel { 20 | def method() {} 21 | } 22 | -------------------------------------------------------------------------------- /source/tests/legacy_tests/test_opaque_extern.axe: -------------------------------------------------------------------------------- 1 | use std.io ( 2 | println_str 3 | ); 4 | 5 | opaque { MyCustomType, AnotherOpaqueType }; 6 | 7 | extern def fopen(filename: ref char, mode: ref char): usize; 8 | extern def fclose(file: usize): i32; 9 | extern def fprintf(file: usize, format: ref char): i32; 10 | 11 | def main() { 12 | println_str(string.create("Testing opaque and extern features")); 13 | println_str(string.create("Compilation successful!")); 14 | } 15 | -------------------------------------------------------------------------------- /source/tests/legacy_tests/gen.axe: -------------------------------------------------------------------------------- 1 | use std.string; 2 | use std.io; 3 | 4 | def main() { 5 | val s: string = str("hello from string"); 6 | mut cs: ref char = "hello from cstring"; 7 | val n: i32 = 42; 8 | val ch: char = 'A'; 9 | 10 | println s; 11 | println cs; 12 | println n; 13 | println ch; 14 | 15 | print "no newline "; 16 | println " <- after print"; 17 | 18 | print n; 19 | println " is the answer"; 20 | 21 | print ch; 22 | println " is a character"; 23 | } 24 | -------------------------------------------------------------------------------- /source/tests/legacy_tests/guess_game.axe: -------------------------------------------------------------------------------- 1 | use std.random; 2 | use std.io; 3 | 4 | def main() { 5 | randomize(); 6 | val secret: i32 = random(1, 100); 7 | mut guess: i32; 8 | 9 | loop { 10 | print("Guess the number between 1 and 100: "); 11 | guess = read_int(); 12 | if guess == secret { 13 | print("You guessed it."); 14 | break; 15 | } elif guess < secret { 16 | print("Too low\n"); 17 | continue; 18 | } 19 | print("Too high\n"); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /source/compiler/std/term.axec: -------------------------------------------------------------------------------- 1 | use std.os; 2 | use std.string; 3 | 4 | def clear_screen() { 5 | platform windows { 6 | exec("cls"); 7 | } 8 | platform posix { 9 | exec("clear"); 10 | } 11 | } 12 | 13 | def color_text(text: string, color_code: i32): string { 14 | mut i: string = concat(str("\033["), i32_to_string(color_code)); 15 | i = concat(i, str("m")); 16 | i = concat(i, text); 17 | i = concat(i, str("\033[0m")); 18 | return i; 19 | } 20 | 21 | test { 22 | clear_screen(); 23 | print "it worked"; 24 | } 25 | -------------------------------------------------------------------------------- /source/tests/self_tests/test_compound_assign.axe: -------------------------------------------------------------------------------- 1 | use std.io; 2 | 3 | def main() { 4 | println "Testing compound assignment operators:"; 5 | 6 | mut x: i32 = 10; 7 | println x; 8 | 9 | x += 5; 10 | println x; // Should be 15 11 | 12 | x -= 3; 13 | println x; // Should be 12 14 | 15 | mut sum: i32 = 0; 16 | val n: i32 = 100; 17 | 18 | parallel for mut i = 0 to n reduce(+:sum) { 19 | sum += i; 20 | } 21 | 22 | println "Sum from 0 to 99:"; 23 | println sum; 24 | println "Expected: 4950"; 25 | } 26 | -------------------------------------------------------------------------------- /source/compiler/std/memory.axec: -------------------------------------------------------------------------------- 1 | /// Copies a value from one location to another. 2 | macro copy(src: untyped, dest: untyped, type: untyped) { 3 | unsafe { 4 | if C.sizeof(type) > 0 { 5 | C.memcpy(&dest, &src, C.sizeof(type)); 6 | } 7 | } 8 | } 9 | 10 | /// Returns the size of a type in bytes. 11 | macro size_of(type: untyped) { 12 | cast[i32](sizeof(type)) 13 | } 14 | 15 | test { 16 | val a: i32 = 42; 17 | mut b: i32 = 0; 18 | copy(a, b, i32); 19 | assert b == 42, "Copy macro failed."; 20 | assert size_of(i32) == 4, "Size of i32 should be 4 bytes."; 21 | } -------------------------------------------------------------------------------- /source/tests/legacy_tests/macros.axec: -------------------------------------------------------------------------------- 1 | macro copy_of(thing: untyped, dest: untyped, type: untyped) { 2 | raw { 3 | memcpy(&{{dest}}, &{{thing}}, sizeof({{type}})); 4 | } 5 | } 6 | 7 | // When called with copy_of(grid, new_grid, Cell[10][10]) this should generate: 8 | // memcpy(&new_grid, &grid, sizeof(Cell[10][10])); 9 | // But wrap memcpy in some "safeness" code. 10 | 11 | model Cell { 12 | temperature: i32; 13 | } 14 | 15 | def main() { 16 | val grid: Cell[10][10]; 17 | val new_grid: Cell[10][10]; 18 | copy_of(grid, new_grid, Cell[10][10]); 19 | println "wow it worked :D"; 20 | } -------------------------------------------------------------------------------- /source/compiler/std/parallelism.axec: -------------------------------------------------------------------------------- 1 | pub model Parallel { 2 | pub def thread_id(): i32 { 3 | unsafe { 4 | return C.omp_get_thread_num(); 5 | } 6 | } 7 | 8 | pub def num_threads(): i32 { 9 | unsafe { 10 | return C.omp_get_num_threads(); 11 | } 12 | } 13 | 14 | pub def max_threads(): i32 { 15 | unsafe { 16 | return C.omp_get_max_threads(); 17 | } 18 | } 19 | 20 | pub def set_num_threads(num: i32) { 21 | unsafe { 22 | C.omp_set_num_threads(num); 23 | } 24 | } 25 | } 26 | 27 | test { 28 | 29 | } 30 | -------------------------------------------------------------------------------- /source/tests/legacy_tests/crossplat.axe: -------------------------------------------------------------------------------- 1 | use std.io; 2 | 3 | def cross_platform_func() { 4 | platform windows { 5 | parallel for mut i = 0; i < 10; i++ { 6 | println i; 7 | } 8 | } 9 | platform posix { 10 | parallel for mut i = 0; i < 10; i++ { 11 | println i; 12 | } 13 | } 14 | } 15 | 16 | platform windows { 17 | def some_function() { 18 | println "hi from windows!"; 19 | } 20 | } 21 | 22 | platform posix { 23 | def some_function() { 24 | println "hi from posix!"; 25 | } 26 | } 27 | 28 | def main() { 29 | cross_platform_func(); 30 | some_function(); 31 | } -------------------------------------------------------------------------------- /source/tests/legacy_tests/for_in_lists.axe: -------------------------------------------------------------------------------- 1 | use std.arena ( 2 | Arena 3 | ); 4 | 5 | use std.lists ( 6 | IntList 7 | ); 8 | 9 | def main() { 10 | mut arena: Arena = Arena.create(65536); 11 | mut my_list: ref IntList = IntList.create(addr(arena), 4); 12 | 13 | IntList.push(my_list, addr(arena), 10); 14 | IntList.push(my_list, addr(arena), 20); 15 | IntList.push(my_list, addr(arena), 30); 16 | IntList.push(my_list, addr(arena), 40); 17 | IntList.push(my_list, addr(arena), 50); 18 | 19 | println "Iterating with for-in syntax:"; 20 | 21 | for x in my_list { 22 | println x; 23 | } 24 | 25 | println "Done!"; 26 | } 27 | -------------------------------------------------------------------------------- /source/tests/legacy_tests/local.axe: -------------------------------------------------------------------------------- 1 | use std.arena; 2 | use std.io; 3 | use std.parallelism; 4 | 5 | def worker(arena: ref Arena, value: i32): i32 { 6 | mut p: ref i32 = cast[ref i32](Arena.alloc(arena, sizeof(i32))); 7 | deref(p) = value * value; 8 | return deref(p); 9 | } 10 | 11 | def main() { 12 | println "Running parallel computation..."; 13 | 14 | parallel local(mut arena: Arena) { 15 | arena = Arena.create(1024); 16 | val tid: i32 = Parallel.thread_id(); 17 | val result: i32 = worker(addr(arena), tid); 18 | println $"Thread {tid} computed {result}"; 19 | Arena.destroy(addr(arena)); 20 | } 21 | 22 | println "Done."; 23 | } 24 | -------------------------------------------------------------------------------- /source/tests/legacy_tests/fib.axe: -------------------------------------------------------------------------------- 1 | use std.io; 2 | 3 | def fib(n: i32): i32 { 4 | if n <= 1 { 5 | return n; 6 | } 7 | 8 | mut a: i32 = 0; 9 | mut b: i32 = 1; 10 | mut i: i32 = 2; 11 | 12 | loop { 13 | if i > n { 14 | break; 15 | } 16 | 17 | mut temp: i32 = a + b; 18 | a = b; 19 | b = temp; 20 | 21 | i = i + 1; 22 | } 23 | 24 | return b; 25 | } 26 | 27 | def main() { 28 | mut i: i32 = 0; 29 | loop { 30 | if i > 20 { 31 | break; 32 | } 33 | 34 | print "fib("; 35 | print i; 36 | print ") = "; 37 | println(fib(i)); 38 | 39 | i = i + 1; 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /source/tests/self_tests/test_generics_adv.axe: -------------------------------------------------------------------------------- 1 | use std.io; 2 | use std.string; 3 | 4 | model SomeModel { 5 | pub def some_function[T](arg: T): T { 6 | println("Will always print."); 7 | when T is i32 { 8 | return arg + 1; 9 | } 10 | when T is f32 { 11 | return arg * 2.0; 12 | } 13 | println("hello"); 14 | when T is string { 15 | return concat_c(arg, "!\n"); 16 | } 17 | println("will never print"); 18 | } 19 | } 20 | 21 | def main() { 22 | println(SomeModel.some_function[i32](5)); 23 | println(SomeModel.some_function[f32](5.0)); 24 | println(SomeModel.some_function[string](str("Hello"))); 25 | println(SomeModel.some_function(3.0)); 26 | } -------------------------------------------------------------------------------- /source/tests/self_tests/test_function_tags.axe: -------------------------------------------------------------------------------- 1 | use std.string; 2 | 3 | [noinline] 4 | def no_inline_function(x: i32): i32 { 5 | return x + 1; 6 | } 7 | 8 | [cold] 9 | def cold_function(msg: string) { 10 | println "This is rarely called"; 11 | println msg; 12 | } 13 | 14 | [hot] 15 | def hot_function(x: i32, y: i32): i32 { 16 | return x * y + x - y; 17 | } 18 | 19 | [inline] 20 | def inline_function(a: i32): i32 { 21 | return a * 2; 22 | } 23 | 24 | def main() { 25 | val result1: i32 = no_inline_function(5); 26 | val result2: i32 = hot_function(3, 4); 27 | val result3: i32 = inline_function(7); 28 | 29 | println "Results:"; 30 | println result1; 31 | println result2; 32 | println result3; 33 | 34 | cold_function(str("Error occurred")); 35 | } 36 | -------------------------------------------------------------------------------- /source/compiler/std/random.axec: -------------------------------------------------------------------------------- 1 | use std.io; 2 | use std.time; 3 | 4 | /// Obtain random seed. 5 | pub def randomize(): void { 6 | unsafe { 7 | C.srand(cast[u32](now().epoch_ms)); 8 | } 9 | } 10 | 11 | /// Get random value between two i32s. 12 | pub def random(a: i32, b: i32): i32 { 13 | unsafe { 14 | return C.rand() mod (b - a + 1) + a; 15 | } 16 | } 17 | 18 | /// Get random value between two f32s. 19 | pub def random_float(a: f64, b: f64): f64 { 20 | unsafe { 21 | return (C.rand() / cast[float](C.RAND_MAX)) * (b - a) + a; 22 | } 23 | } 24 | 25 | test { 26 | randomize(); 27 | 28 | assert(random(1, 10) >= 1, "Random number should be between 1 and 10"); 29 | assert(random(1, 10) <= 10, "Random number should be between 1 and 10"); 30 | assert(random_float(1.0, 10.0) >= 1.0, "Random float should be between 1.0 and 10.0"); 31 | assert(random_float(1.0, 10.0) <= 10.0, "Random float should be between 1.0 and 10.0"); 32 | 33 | print_f64(random_float(1.0, 10.0)); 34 | } 35 | -------------------------------------------------------------------------------- /source/compiler/std/errors.axec: -------------------------------------------------------------------------------- 1 | use std.string ( 2 | string 3 | ); 4 | 5 | use std.io( 6 | print 7 | ); 8 | 9 | /// Represents some kind of error in the program. 10 | pub model error { 11 | msg: string; 12 | 13 | pub def create(msg: ref char): error { 14 | return error{msg: string.create(msg)}; 15 | } 16 | 17 | pub def print_self(err: error) { 18 | print(err.msg); 19 | } 20 | } 21 | 22 | /// Stops the program with the given error message. 23 | pub def panic(err: error) { 24 | print "\nerror: "; 25 | error.print_self(err); 26 | 27 | unsafe { 28 | C.exit(1); 29 | } 30 | } 31 | 32 | /// Enforces a condition, panics if the condition is false. 33 | pub def enforce(condition: bool, err: error) { 34 | if !condition { 35 | panic(err); 36 | } 37 | } 38 | 39 | /// Enforces a condition, panics with the given message if the condition is false. 40 | pub def enforce_raw(condition: bool, msg: ref char) { 41 | if !condition { 42 | panic(error.create(msg)); 43 | } 44 | } 45 | 46 | def test_error(): error { 47 | return error{msg: string.create("Some bad thing happened")}; 48 | } 49 | 50 | test { 51 | print(test_error().msg); 52 | enforce(true, error.create("Should be fine")); 53 | panic(error.create("Should NOT be fine")); 54 | } 55 | -------------------------------------------------------------------------------- /source/compiler/external/curl/include/curl/stdcheaders.h: -------------------------------------------------------------------------------- 1 | #ifndef CURLINC_STDCHEADERS_H 2 | #define CURLINC_STDCHEADERS_H 3 | /*************************************************************************** 4 | * _ _ ____ _ 5 | * Project ___| | | | _ \| | 6 | * / __| | | | |_) | | 7 | * | (__| |_| | _ <| |___ 8 | * \___|\___/|_| \_\_____| 9 | * 10 | * Copyright (C) Daniel Stenberg, , et al. 11 | * 12 | * This software is licensed as described in the file COPYING, which 13 | * you should have received as part of this distribution. The terms 14 | * are also available at https://curl.se/docs/copyright.html. 15 | * 16 | * You may opt to use, copy, modify, merge, publish, distribute and/or sell 17 | * copies of the Software, and permit persons to whom the Software is 18 | * furnished to do so, under the terms of the COPYING file. 19 | * 20 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY 21 | * KIND, either express or implied. 22 | * 23 | * SPDX-License-Identifier: curl 24 | * 25 | ***************************************************************************/ 26 | 27 | #include 28 | 29 | size_t fread(void *, size_t, size_t, FILE *); 30 | size_t fwrite(const void *, size_t, size_t, FILE *); 31 | 32 | int strcasecmp(const char *, const char *); 33 | int strncasecmp(const char *, const char *, size_t); 34 | 35 | #endif /* CURLINC_STDCHEADERS_H */ 36 | -------------------------------------------------------------------------------- /source/compiler/external/pcre/include/config.h: -------------------------------------------------------------------------------- 1 | /* config.h for CMake builds */ 2 | 3 | /* #undef HAVE_DIRENT_H */ 4 | #define HAVE_SYS_STAT_H 1 5 | #define HAVE_SYS_TYPES_H 1 6 | /* #undef HAVE_UNISTD_H */ 7 | #define HAVE_WINDOWS_H 1 8 | #define HAVE_STDINT_H 1 9 | #define HAVE_INTTYPES_H 1 10 | 11 | /* #undef HAVE_TYPE_TRAITS_H */ 12 | /* #undef HAVE_BITS_TYPE_TRAITS_H */ 13 | 14 | /* #undef HAVE_BCOPY */ 15 | #define HAVE_MEMMOVE 1 16 | #define HAVE_STRERROR 1 17 | #define HAVE_STRTOLL 1 18 | /* #undef HAVE_STRTOQ */ 19 | #define HAVE__STRTOI64 1 20 | 21 | #define PCRE_STATIC 1 22 | 23 | #define SUPPORT_PCRE8 1 24 | #define SUPPORT_PCRE16 1 25 | #define SUPPORT_PCRE32 1 26 | #define SUPPORT_JIT 1 27 | #define SUPPORT_PCREGREP_JIT 1 28 | #define SUPPORT_UTF 1 29 | #define SUPPORT_UCP 1 30 | /* #undef EBCDIC */ 31 | /* #undef EBCDIC_NL25 */ 32 | /* #undef BSR_ANYCRLF */ 33 | /* #undef NO_RECURSE */ 34 | 35 | #define HAVE_LONG_LONG 1 36 | #define HAVE_UNSIGNED_LONG_LONG 1 37 | 38 | /* #undef SUPPORT_LIBBZ2 */ 39 | /* #undef SUPPORT_LIBZ */ 40 | /* #undef SUPPORT_LIBEDIT */ 41 | /* #undef SUPPORT_LIBREADLINE */ 42 | 43 | /* #undef SUPPORT_VALGRIND */ 44 | /* #undef SUPPORT_GCOV */ 45 | 46 | #define NEWLINE 10 47 | #define POSIX_MALLOC_THRESHOLD 10 48 | #define LINK_SIZE 2 49 | #define PARENS_NEST_LIMIT 250 50 | #define MATCH_LIMIT 10000000 51 | #define MATCH_LIMIT_RECURSION MATCH_LIMIT 52 | #define PCREGREP_BUFSIZE 20480 53 | 54 | #define MAX_NAME_SIZE 32 55 | #define MAX_NAME_COUNT 10000 56 | 57 | /* end config.h for CMake builds */ 58 | -------------------------------------------------------------------------------- /source/compiler/std/typecons.axec: -------------------------------------------------------------------------------- 1 | use std.string( 2 | string 3 | ); 4 | 5 | /// An enumeration for any type. 6 | enum AnyKind { 7 | INT_T; 8 | FLOAT_T; 9 | STRING_T; 10 | BOOL_T; 11 | PTR_T; 12 | } 13 | 14 | /// A type constructor for any type. 15 | pub model Any { 16 | kind: AnyKind; 17 | 18 | value: union { 19 | i: i32; 20 | f: f32; 21 | s: string; 22 | b: bool; 23 | ptr: ref void; 24 | } 25 | 26 | /// Creates an Any from an i32. 27 | def from_i32(v: i32): Any { 28 | mut result: Any; 29 | result.kind = AnyKind.INT_T; 30 | result.value.i = v; 31 | return result; 32 | } 33 | 34 | /// Creates an Any from an f32. 35 | def from_f32(v: f32): Any { 36 | mut result: Any; 37 | result.kind = AnyKind.FLOAT_T; 38 | result.value.f = v; 39 | return result; 40 | } 41 | 42 | /// Creates an Any from a string. 43 | def from_string(v: string): Any { 44 | mut result: Any; 45 | result.kind = AnyKind.STRING_T; 46 | result.value.s = v; 47 | return result; 48 | } 49 | 50 | /// Creates an Any from a bool. 51 | def from_bool(v: bool): Any { 52 | mut result: Any; 53 | result.kind = AnyKind.BOOL_T; 54 | result.value.b = v; 55 | return result; 56 | } 57 | 58 | /// Creates an Any from a pointer. 59 | def from_ptr(v: ref void): Any { 60 | mut result: Any; 61 | result.kind = AnyKind.PTR_T; 62 | result.value.ptr = v; 63 | return result; 64 | } 65 | } 66 | 67 | test { 68 | 69 | } -------------------------------------------------------------------------------- /source/tests/legacy_tests/test_list_of.axe: -------------------------------------------------------------------------------- 1 | // Test the list() feature for dynamic arrays 2 | 3 | use std.io ( 4 | print_i32, 5 | println 6 | ); 7 | 8 | model Token { 9 | token_type: i32; 10 | value: i32; 11 | } 12 | 13 | def main() { 14 | // Create a dynamic array using list() 15 | mut tokens: list(Token); 16 | 17 | // Create some tokens 18 | mut t1: Token; 19 | t1.token_type = 1; 20 | t1.value = 100; 21 | 22 | mut t2: Token; 23 | t2.token_type = 2; 24 | t2.value = 200; 25 | 26 | mut t3: Token; 27 | t3.token_type = 3; 28 | t3.value = 300; 29 | 30 | // Append tokens to the list 31 | append(tokens, t1); 32 | append(tokens, t2); 33 | append(tokens, t3); 34 | 35 | // Access and print the tokens 36 | println "Token 0: type="; 37 | print_i32(tokens[0].token_type); 38 | print " value="; 39 | print_i32(tokens[0].value); 40 | println ""; 41 | 42 | println "Token 1: type="; 43 | print_i32(tokens[1].token_type); 44 | print " value="; 45 | print_i32(tokens[1].value); 46 | println ""; 47 | 48 | println "Token 2: type="; 49 | print_i32(tokens[2].token_type); 50 | print " value="; 51 | print_i32(tokens[2].value); 52 | println ""; 53 | 54 | // Test with simple types 55 | mut numbers: list(i32); 56 | append(numbers, 10); 57 | append(numbers, 20); 58 | append(numbers, 30); 59 | append(numbers, 40); 60 | 61 | println "Numbers:"; 62 | print_i32(numbers[0]); 63 | print " "; 64 | print_i32(numbers[1]); 65 | print " "; 66 | print_i32(numbers[2]); 67 | print " "; 68 | print_i32(numbers[3]); 69 | println ""; 70 | } 71 | -------------------------------------------------------------------------------- /source/tests/legacy_tests/linked.axe: -------------------------------------------------------------------------------- 1 | use std.arena ( 2 | Arena 3 | ); 4 | 5 | use std.io ( 6 | print_i32 7 | ); 8 | 9 | model Node { 10 | value: i32; 11 | next: ref Node; 12 | } 13 | 14 | /// Allocate a new Node from the arena and initialize it 15 | def new_node(arena: ref Arena, value: i32): ref Node { 16 | mut n: ref Node = Arena.alloc(arena, sizeof(Node)); 17 | n.value = value; 18 | n.next = nil; 19 | return n; 20 | } 21 | 22 | /// Push a new value to the front of the list 23 | def list_push_front(head: ref Node, arena: ref Arena, value: i32): ref Node { 24 | mut new_head: ref Node = new_node(arena, value); 25 | new_head.next = head; 26 | return new_head; 27 | } 28 | 29 | /// Push a new value to the back of the list 30 | def list_push_back(head: ref Node, arena: ref Arena, value: i32): ref Node { 31 | if head == nil { 32 | return new_node(arena, value); 33 | } 34 | 35 | mut cur: ref Node = head; 36 | loop { 37 | if cur.next == nil { 38 | break; 39 | } 40 | cur = cur.next; 41 | } 42 | 43 | cur.next = new_node(arena, value); 44 | return head; 45 | } 46 | 47 | /// Print linked list values 48 | def list_print(head: ref Node) { 49 | mut cur: ref Node = head; 50 | 51 | loop { 52 | if cur == nil { 53 | break; 54 | } 55 | print_i32(cur.value); 56 | print " "; 57 | cur = cur.next; 58 | } 59 | 60 | println ""; 61 | } 62 | 63 | def main() { 64 | mut arena: Arena = Arena.create(65536); 65 | mut head: ref Node = nil; 66 | 67 | head = list_push_front(head, addr(arena), 10); 68 | head = list_push_front(head, addr(arena), 5); 69 | head = list_push_back(head, addr(arena), 20); 70 | head = list_push_back(head, addr(arena), 25); 71 | 72 | println "List contents:"; 73 | list_print(head); 74 | 75 | Arena.destroy(addr(arena)); 76 | println "Arena destroyed."; 77 | } 78 | -------------------------------------------------------------------------------- /source/tests/legacy_tests/matrix.axe: -------------------------------------------------------------------------------- 1 | def print_matrix(m: int[rows][cols], rows: int, cols: int) { 2 | mut r: int = 0; 3 | loop { 4 | if r >= rows { 5 | break; 6 | } 7 | 8 | mut c: int = 0; 9 | loop { 10 | if c >= cols { 11 | break; 12 | } 13 | 14 | print m[r][c]; 15 | print " "; 16 | c = c + 1; 17 | } 18 | 19 | println ""; 20 | r = r + 1; 21 | } 22 | } 23 | 24 | def matmul(a: int[n][m], b: int[m][p], result: int[n][p], n: int, m: int, p: int) { 25 | // a: n × m 26 | // b: m × p 27 | // result: n × p 28 | 29 | mut r: int = 0; 30 | loop { 31 | if r >= n { 32 | break; 33 | } 34 | 35 | mut c: int = 0; 36 | loop { 37 | if c >= p { 38 | break; 39 | } 40 | 41 | mut sum: int = 0; 42 | 43 | mut k: int = 0; 44 | loop { 45 | if k >= m { 46 | break; 47 | } 48 | 49 | sum = sum + (a[r][k] * b[k][c]); 50 | k = k + 1; 51 | } 52 | 53 | result[r][c] = sum; 54 | c = c + 1; 55 | } 56 | 57 | r = r + 1; 58 | } 59 | } 60 | 61 | def main() { 62 | // Multiply: 63 | // [1 2 3] [1 2] 64 | // [4 5 6] x [3 4] 65 | // [5 6] 66 | 67 | val n: int = 2; 68 | val m: int = 3; 69 | val p: int = 2; 70 | 71 | mut A: int[2][3]; 72 | mut B: int[3][2]; 73 | mut R: int[2][2]; 74 | 75 | // Fill A 76 | A[0][0] = 1; A[0][1] = 2; A[0][2] = 3; 77 | A[1][0] = 4; A[1][1] = 5; A[1][2] = 6; 78 | 79 | // Fill B 80 | B[0][0] = 1; B[0][1] = 2; 81 | B[1][0] = 3; B[1][1] = 4; 82 | B[2][0] = 5; B[2][1] = 6; 83 | 84 | // Multiply 85 | matmul(A, B, R, n, m, p); 86 | 87 | println "Result:"; 88 | print_matrix(R, n, p); 89 | } 90 | -------------------------------------------------------------------------------- /source/tests/legacy_tests/stress4.axe: -------------------------------------------------------------------------------- 1 | use stdlib/arena ( 2 | Arena, 3 | arena_create, 4 | arena_destroy, 5 | arena_alloc, 6 | arena_get_remaining 7 | ); 8 | 9 | def main() { 10 | println "=== ASCII MOUNTAIN DEMO ==="; 11 | 12 | // configuration 13 | val width: int = 80; 14 | val max_height: int = 25; 15 | 16 | // arena for scratch allocations 17 | mut val arena: Arena = arena_create(65536); 18 | 19 | // heightmap buffer on stack 20 | mut val height: int[width]; 21 | 22 | // initialize rough terrain 23 | mut val i: int = 0; 24 | mut val h: int = max_height / 2; 25 | 26 | loop { 27 | if i >= width { break; } 28 | 29 | // small random walk 30 | // (deterministic fake-random pattern) 31 | if i mod 7 == 0 { 32 | h = h + 2; 33 | } elif i mod 5 == 0 { 34 | h = h - 3; 35 | } elif i mod 3 == 0 { 36 | h = h + 1; 37 | } else { 38 | h = h - 1; 39 | } 40 | 41 | // clamp 42 | if h < 0 { h = 0; } 43 | if h > max_height { h = max_height; } 44 | 45 | height[i] = h; 46 | 47 | i = i + 1; 48 | } 49 | 50 | // smooth terrain (3 passes) 51 | mut val pass: int = 0; 52 | loop { 53 | if pass >= 3 { break; } 54 | 55 | mut val x: int = 1; 56 | loop { 57 | if x >= width - 1 { break; } 58 | height[x] = (height[x-1] + height[x] * 2 + height[x+1]) / 4; 59 | x = x + 1; 60 | } 61 | 62 | pass = pass + 1; 63 | } 64 | 65 | // draw from top to bottom 66 | mut val row: int = max_height; 67 | loop { 68 | if row < 0 { break; } 69 | 70 | mut val col: int = 0; 71 | loop { 72 | if col >= width { break; } 73 | 74 | if height[col] >= row { 75 | print "#"; 76 | } else { 77 | print " "; 78 | } 79 | 80 | col = col + 1; 81 | } 82 | 83 | println ""; 84 | row = row - 1; 85 | } 86 | 87 | println ""; 88 | print "Arena remaining: "; 89 | print arena_get_remaining(addr(arena)); 90 | println ""; 91 | 92 | arena_destroy(addr(arena)); 93 | println "Arena destroyed — memory freed!"; 94 | println "=== END ==="; 95 | } 96 | -------------------------------------------------------------------------------- /source/tests/legacy_tests/stress2.axe: -------------------------------------------------------------------------------- 1 | use std.arena ( 2 | Arena, 3 | arena_create, 4 | arena_destroy, 5 | arena_alloc 6 | ); 7 | 8 | use std.memory ( 9 | copy, 10 | size_of 11 | ); 12 | 13 | model Particle { 14 | x: int; 15 | y: int; 16 | vx: int; 17 | vy: int; 18 | } 19 | 20 | def init_particles(particles: Particle[count], count: int, arena: Arena) { 21 | mut val i: int = 0; 22 | loop { 23 | if i >= count { break; } 24 | 25 | // Allocate a particle in the arena 26 | val ptr: long = arena_alloc(addr(arena), size_of(Particle)); 27 | 28 | particles[i].x = i * 2; 29 | particles[i].y = 0; 30 | particles[i].vx = 1; 31 | particles[i].vy = 0; 32 | 33 | i = i + 1; 34 | } 35 | } 36 | 37 | def update_particles(particles: Particle[count], count: int) { 38 | mut val i: int = 0; 39 | loop { 40 | if i >= count { break; } 41 | 42 | // Gravity 43 | particles[i].vy = particles[i].vy + 1; 44 | 45 | // Update position 46 | particles[i].x = particles[i].x + particles[i].vx; 47 | particles[i].y = particles[i].y + particles[i].vy; 48 | 49 | // Bounce on the floor (y = 20) 50 | if particles[i].y > 20 { 51 | particles[i].y = 20; 52 | particles[i].vy = -particles[i].vy / 2; 53 | } 54 | 55 | i = i + 1; 56 | } 57 | } 58 | 59 | def print_particles(particles: Particle[count], count: int) { 60 | mut val i: int = 0; 61 | loop { 62 | if i >= count { break; } 63 | print "("; 64 | print particles[i].x; 65 | print ", "; 66 | print particles[i].y; 67 | println ")"; 68 | i = i + 1; 69 | } 70 | } 71 | 72 | def main() { 73 | val particle_count: int = 10; 74 | mut val arena: Arena = arena_create(65536); 75 | 76 | mut val particles: Particle[10]; 77 | 78 | init_particles(particles, particle_count, arena); 79 | 80 | println "Initial particle positions:"; 81 | print_particles(particles, particle_count); 82 | println ""; 83 | 84 | mut val step: int = 0; 85 | loop { 86 | if step >= 10 { break; } 87 | 88 | update_particles(particles, particle_count); 89 | 90 | println "Step "; 91 | print step; 92 | println ":"; 93 | print_particles(particles, particle_count); 94 | println ""; 95 | 96 | step = step + 1; 97 | } 98 | 99 | arena_destroy(addr(arena)); 100 | println "Arena destroyed - memory freed!"; 101 | } 102 | -------------------------------------------------------------------------------- /source/compiler/external/curl/include/curl/options.h: -------------------------------------------------------------------------------- 1 | #ifndef CURLINC_OPTIONS_H 2 | #define CURLINC_OPTIONS_H 3 | /*************************************************************************** 4 | * _ _ ____ _ 5 | * Project ___| | | | _ \| | 6 | * / __| | | | |_) | | 7 | * | (__| |_| | _ <| |___ 8 | * \___|\___/|_| \_\_____| 9 | * 10 | * Copyright (C) Daniel Stenberg, , et al. 11 | * 12 | * This software is licensed as described in the file COPYING, which 13 | * you should have received as part of this distribution. The terms 14 | * are also available at https://curl.se/docs/copyright.html. 15 | * 16 | * You may opt to use, copy, modify, merge, publish, distribute and/or sell 17 | * copies of the Software, and permit persons to whom the Software is 18 | * furnished to do so, under the terms of the COPYING file. 19 | * 20 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY 21 | * KIND, either express or implied. 22 | * 23 | * SPDX-License-Identifier: curl 24 | * 25 | ***************************************************************************/ 26 | 27 | #ifdef __cplusplus 28 | extern "C" { 29 | #endif 30 | 31 | typedef enum { 32 | CURLOT_LONG, /* long (a range of values) */ 33 | CURLOT_VALUES, /* (a defined set or bitmask) */ 34 | CURLOT_OFF_T, /* curl_off_t (a range of values) */ 35 | CURLOT_OBJECT, /* pointer (void *) */ 36 | CURLOT_STRING, /* (char * to null-terminated buffer) */ 37 | CURLOT_SLIST, /* (struct curl_slist *) */ 38 | CURLOT_CBPTR, /* (void * passed as-is to a callback) */ 39 | CURLOT_BLOB, /* blob (struct curl_blob *) */ 40 | CURLOT_FUNCTION /* function pointer */ 41 | } curl_easytype; 42 | 43 | /* Flag bits */ 44 | 45 | /* "alias" means it is provided for old programs to remain functional, 46 | we prefer another name */ 47 | #define CURLOT_FLAG_ALIAS (1<<0) 48 | 49 | /* The CURLOPTTYPE_* id ranges can still be used to figure out what type/size 50 | to use for curl_easy_setopt() for the given id */ 51 | struct curl_easyoption { 52 | const char *name; 53 | CURLoption id; 54 | curl_easytype type; 55 | unsigned int flags; 56 | }; 57 | 58 | CURL_EXTERN const struct curl_easyoption * 59 | curl_easy_option_by_name(const char *name); 60 | 61 | CURL_EXTERN const struct curl_easyoption * 62 | curl_easy_option_by_id(CURLoption id); 63 | 64 | CURL_EXTERN const struct curl_easyoption * 65 | curl_easy_option_next(const struct curl_easyoption *prev); 66 | 67 | #ifdef __cplusplus 68 | } /* end of extern "C" */ 69 | #endif 70 | #endif /* CURLINC_OPTIONS_H */ 71 | -------------------------------------------------------------------------------- /source/compiler/std/uuid.axec: -------------------------------------------------------------------------------- 1 | use std.string (string); 2 | use std.io (println_str); 3 | use std.random; 4 | 5 | /// Generates a random UUID v4 string. 6 | /// Returns a string in the format: xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx 7 | /// Where x is any hexadecimal digit and y is one of 8, 9, A, or B. 8 | def generate_uuid(): string { 9 | mut result: string; 10 | randomize(); 11 | 12 | result.data = nil; 13 | result.len = 0; 14 | result.cap = 0; 15 | result.data = cast[ref char](C.malloc(37)); 16 | result.cap = 37; 17 | 18 | if result.data != nil { 19 | val hex_chars: ref char = "0123456789abcdef"; 20 | val variant_chars: ref char = "89ab"; 21 | 22 | for mut i = 0 to 35 { 23 | if i == 8 or i == 13 or i == 18 or i == 23 { 24 | result.data[i] = '-'; 25 | } 26 | elif i == 14 { 27 | result.data[i] = '4'; 28 | } 29 | elif i == 19 { 30 | result.data[i] = variant_chars[rand() % 4]; 31 | } 32 | else { 33 | result.data[i] = hex_chars[rand() % 16]; 34 | } 35 | } 36 | 37 | result.data[36] = '\0'; 38 | result.len = 36; 39 | } 40 | 41 | return result; 42 | } 43 | 44 | 45 | /// Generates a random hexadecimal string of specified length. 46 | /// Useful for generating UUIDs of custom lengths or other random identifiers. 47 | def generate_random_hex(length: usize): string { 48 | mut result: string; 49 | randomize(); 50 | 51 | result.data = nil; 52 | result.len = 0; 53 | result.cap = 0; 54 | result.data = cast[ref char](C.malloc(length + 1)); 55 | result.cap = length + 1; 56 | 57 | if result.data != nil { 58 | val hex_chars: ref char = "0123456789abcdef"; 59 | for mut i = 0 to length - 1 { 60 | result.data[i] = hex_chars[rand() % 16]; 61 | } 62 | result.data[length] = '\0'; 63 | result.len = length; 64 | } 65 | 66 | return result; 67 | } 68 | 69 | test { 70 | mut uuid1: string = generate_uuid(); 71 | 72 | assert str_len(uuid1) == 36, "UUID should be 36 characters long"; 73 | 74 | mut uuid2: string = generate_uuid(); 75 | assert uuid1.data != uuid2.data, "Two UUIDs should be different"; 76 | 77 | println_str(generate_uuid()); 78 | 79 | mut hex16: string = generate_random_hex(cast[usize](16)); 80 | assert str_len(hex16) == 16, "Random hex string should be 16 characters long"; 81 | 82 | mut hex32: string = generate_random_hex(cast[usize](32)); 83 | assert str_len(hex32) == 32, "Random hex string should be 32 characters long"; 84 | 85 | println_str(hex16); 86 | } 87 | -------------------------------------------------------------------------------- /source/compiler/std/algorithms.axec: -------------------------------------------------------------------------------- 1 | use std.arena; 2 | use std.io; 3 | use std.string; 4 | use std.lists; 5 | 6 | /// Check if some list contains a value. 7 | def list_contains[T, T2](lst: T, value: T2): bool { 8 | for mut i = 0; i < lst.len; i++ { 9 | when T2 is i32 and T is IntList { 10 | if lst.data[i] == cast[i32](value) { 11 | return true; 12 | } 13 | } 14 | when T2 is string and T is StringList { 15 | if compare(lst.data[i], cast[string](value)) == 0 { 16 | return true; 17 | } 18 | } 19 | when T2 is float and T is FloatList { 20 | if lst.data[i] == cast[float](value) { 21 | return true; 22 | } 23 | } 24 | when T2 is bool and T is BoolList { 25 | if lst.data[i] == cast[bool](value) { 26 | return true; 27 | } 28 | } 29 | } 30 | return false; 31 | } 32 | 33 | /// Check if some StringList contains a value 34 | def strlst_contains(lst: StringList, value: string): bool { 35 | for mut i = 0; i < lst.len; i++ { 36 | if compare(lst.data[i], value) == 0 { 37 | return true; 38 | } 39 | } 40 | return false; 41 | } 42 | 43 | /// Check if some StringList contains a value, but search by raw char pointer. 44 | def strlst_contains_c(lst: StringList, value: ref char): bool { 45 | for mut i = 0; i < lst.len; i++ { 46 | if equals_c(lst.data[i], value) { 47 | return true; 48 | } 49 | } 50 | return false; 51 | } 52 | 53 | /// Check if some IntList contains an i32. 54 | def intlst_contains(lst: IntList, vlue: i32): bool { 55 | for mut i = 0; i < lst.len; i++ { 56 | if lst.data[i] == vlue { 57 | return true; 58 | } 59 | } 60 | return false; 61 | } 62 | 63 | test { 64 | val arena: Arena = Arena.create(1024 * 10); 65 | println "\nTest 1: StringList contains"; 66 | 67 | val lst: ref StringList = StringList.create(addr(arena), 10); 68 | StringList.push(lst, addr(arena), str("hello")); 69 | StringList.push(lst, addr(arena), str("world")); 70 | 71 | assert strlst_contains(deref(lst), str("hello")), "Expected hello to be found in the list"; 72 | assert !strlst_contains(deref(lst), str("goodbye")), "Expected goodbye not to be found in the list"; 73 | 74 | println "\nTest 2: IntList contains"; 75 | val ilst: ref IntList = IntList.create(addr(arena), 10); 76 | IntList.push(ilst, addr(arena), 42); 77 | IntList.push(ilst, addr(arena), 1337); 78 | 79 | assert intlst_contains(deref(ilst), 42), "Expected 42 to be found in the list"; 80 | assert !intlst_contains(deref(ilst), 7), "Expected 7 not to be found in the list"; 81 | } 82 | -------------------------------------------------------------------------------- /source/compiler/external/curl/include/curl/header.h: -------------------------------------------------------------------------------- 1 | #ifndef CURLINC_HEADER_H 2 | #define CURLINC_HEADER_H 3 | /*************************************************************************** 4 | * _ _ ____ _ 5 | * Project ___| | | | _ \| | 6 | * / __| | | | |_) | | 7 | * | (__| |_| | _ <| |___ 8 | * \___|\___/|_| \_\_____| 9 | * 10 | * Copyright (C) Daniel Stenberg, , et al. 11 | * 12 | * This software is licensed as described in the file COPYING, which 13 | * you should have received as part of this distribution. The terms 14 | * are also available at https://curl.se/docs/copyright.html. 15 | * 16 | * You may opt to use, copy, modify, merge, publish, distribute and/or sell 17 | * copies of the Software, and permit persons to whom the Software is 18 | * furnished to do so, under the terms of the COPYING file. 19 | * 20 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY 21 | * KIND, either express or implied. 22 | * 23 | * SPDX-License-Identifier: curl 24 | * 25 | ***************************************************************************/ 26 | 27 | #ifdef __cplusplus 28 | extern "C" { 29 | #endif 30 | 31 | struct curl_header { 32 | char *name; /* this might not use the same case */ 33 | char *value; 34 | size_t amount; /* number of headers using this name */ 35 | size_t index; /* ... of this instance, 0 or higher */ 36 | unsigned int origin; /* see bits below */ 37 | void *anchor; /* handle privately used by libcurl */ 38 | }; 39 | 40 | /* 'origin' bits */ 41 | #define CURLH_HEADER (1<<0) /* plain server header */ 42 | #define CURLH_TRAILER (1<<1) /* trailers */ 43 | #define CURLH_CONNECT (1<<2) /* CONNECT headers */ 44 | #define CURLH_1XX (1<<3) /* 1xx headers */ 45 | #define CURLH_PSEUDO (1<<4) /* pseudo headers */ 46 | 47 | typedef enum { 48 | CURLHE_OK, 49 | CURLHE_BADINDEX, /* header exists but not with this index */ 50 | CURLHE_MISSING, /* no such header exists */ 51 | CURLHE_NOHEADERS, /* no headers at all exist (yet) */ 52 | CURLHE_NOREQUEST, /* no request with this number was used */ 53 | CURLHE_OUT_OF_MEMORY, /* out of memory while processing */ 54 | CURLHE_BAD_ARGUMENT, /* a function argument was not okay */ 55 | CURLHE_NOT_BUILT_IN /* if API was disabled in the build */ 56 | } CURLHcode; 57 | 58 | CURL_EXTERN CURLHcode curl_easy_header(CURL *easy, 59 | const char *name, 60 | size_t index, 61 | unsigned int origin, 62 | int request, 63 | struct curl_header **hout); 64 | 65 | CURL_EXTERN struct curl_header *curl_easy_nextheader(CURL *easy, 66 | unsigned int origin, 67 | int request, 68 | struct curl_header *prev); 69 | 70 | #ifdef __cplusplus 71 | } /* end of extern "C" */ 72 | #endif 73 | 74 | #endif /* CURLINC_HEADER_H */ 75 | -------------------------------------------------------------------------------- /source/tests/self_tests/test_gol.axe: -------------------------------------------------------------------------------- 1 | use std.io; 2 | 3 | /// Convert 2D coordinate (x, y) into 1D index 4 | def idx(x: i32, y: i32, width: i32): i32 { 5 | return y * width + x; 6 | } 7 | 8 | /// Print the grid (1-D list) 9 | def print_grid(grid: ref list(i32), width: i32, height: i32) { 10 | for mut y = 0; y < height; y++ { 11 | for mut x = 0; x < width; x++ { 12 | if grid.data[idx(x, y, width)] == 1 { 13 | print "■"; 14 | } else { 15 | print "□"; 16 | } 17 | } 18 | println ""; 19 | } 20 | } 21 | 22 | /// Count live neighbors around (x, y) 23 | def count_neighbors(grid: ref list(i32), x: i32, y: i32, width: i32, height: i32): i32 { 24 | mut count: i32 = 0; 25 | 26 | for mut dy = -1; dy <= 1; dy++ { 27 | for mut dx = -1; dx <= 1; dx++ { 28 | if dx == 0 and dy == 0 { 29 | continue; 30 | } 31 | 32 | val nx = x + dx; 33 | val ny = y + dy; 34 | 35 | if nx >= 0 and nx < width and ny >= 0 and ny < height { 36 | if grid.data[idx(nx, ny, width)] == 1 { 37 | count++; 38 | } 39 | } 40 | } 41 | } 42 | 43 | return count; 44 | } 45 | 46 | /// Compute next generation 47 | def next_generation(grid: ref list(i32), new_grid: ref list(i32), width: i32, height: i32) { 48 | for mut y = 0; y < height; y++ { 49 | for mut x = 0; x < width; x++ { 50 | 51 | val i = idx(x, y, width); 52 | val neighbors = count_neighbors(grid, x, y, width, height); 53 | 54 | if grid.data[i] == 1 { 55 | if neighbors == 2 or neighbors == 3 { 56 | new_grid.data[i] = 1; 57 | } else { 58 | new_grid.data[i] = 0; 59 | } 60 | } else { 61 | if neighbors == 3 { 62 | new_grid.data[i] = 1; 63 | } else { 64 | new_grid.data[i] = 0; 65 | } 66 | } 67 | } 68 | } 69 | } 70 | 71 | /// Copy new_grid back into grid 72 | def copy_grid(src: ref list(i32), dst: ref list(i32), size: i32) { 73 | for mut i = 0; i < size; i++ { 74 | dst.data[i] = src.data[i]; 75 | } 76 | } 77 | 78 | def main() { 79 | val width: i32 = 20; 80 | val height: i32 = 20; 81 | val size: i32 = width * height; 82 | 83 | mut grid: list(i32); 84 | mut new_grid: list(i32); 85 | 86 | for mut i = 0; i < size; i++ { 87 | append(grid, 0); 88 | append(new_grid, 0); 89 | } 90 | 91 | grid.data[idx(2,1,width)] = 1; 92 | grid.data[idx(3,2,width)] = 1; 93 | grid.data[idx(1,3,width)] = 1; 94 | grid.data[idx(2,3,width)] = 1; 95 | grid.data[idx(3,3,width)] = 1; 96 | 97 | println "Conway's Game of Life\n"; 98 | 99 | for mut gen = 0; gen < 20; gen++ { 100 | print "Generation "; 101 | println gen; 102 | println ""; 103 | 104 | print_grid(addr(grid), width, height); 105 | 106 | next_generation(addr(grid), addr(new_grid), width, height); 107 | copy_grid(addr(new_grid), addr(grid), size); 108 | 109 | println "\n---\n"; 110 | } 111 | } -------------------------------------------------------------------------------- /source/compiler/external/curl/include/curl/curlver.h: -------------------------------------------------------------------------------- 1 | #ifndef CURLINC_CURLVER_H 2 | #define CURLINC_CURLVER_H 3 | /*************************************************************************** 4 | * _ _ ____ _ 5 | * Project ___| | | | _ \| | 6 | * / __| | | | |_) | | 7 | * | (__| |_| | _ <| |___ 8 | * \___|\___/|_| \_\_____| 9 | * 10 | * Copyright (C) Daniel Stenberg, , et al. 11 | * 12 | * This software is licensed as described in the file COPYING, which 13 | * you should have received as part of this distribution. The terms 14 | * are also available at https://curl.se/docs/copyright.html. 15 | * 16 | * You may opt to use, copy, modify, merge, publish, distribute and/or sell 17 | * copies of the Software, and permit persons to whom the Software is 18 | * furnished to do so, under the terms of the COPYING file. 19 | * 20 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY 21 | * KIND, either express or implied. 22 | * 23 | * SPDX-License-Identifier: curl 24 | * 25 | ***************************************************************************/ 26 | 27 | /* This header file contains nothing but libcurl version info, generated by 28 | a script at release-time. This was made its own header file in 7.11.2 */ 29 | 30 | /* This is the global package copyright */ 31 | #define LIBCURL_COPYRIGHT "Daniel Stenberg, ." 32 | 33 | /* This is the version number of the libcurl package from which this header 34 | file origins: */ 35 | #define LIBCURL_VERSION "8.16.0-DEV" 36 | 37 | /* The numeric version number is also available "in parts" by using these 38 | defines: */ 39 | #define LIBCURL_VERSION_MAJOR 8 40 | #define LIBCURL_VERSION_MINOR 16 41 | #define LIBCURL_VERSION_PATCH 0 42 | /* This is the numeric version of the libcurl version number, meant for easier 43 | parsing and comparisons by programs. The LIBCURL_VERSION_NUM define will 44 | always follow this syntax: 45 | 46 | 0xXXYYZZ 47 | 48 | Where XX, YY and ZZ are the main version, release and patch numbers in 49 | hexadecimal (using 8 bits each). All three numbers are always represented 50 | using two digits. 1.2 would appear as "0x010200" while version 9.11.7 51 | appears as "0x090b07". 52 | 53 | This 6-digit (24 bits) hexadecimal number does not show pre-release number, 54 | and it is always a greater number in a more recent release. It makes 55 | comparisons with greater than and less than work. 56 | 57 | Note: This define is the full hex number and _does not_ use the 58 | CURL_VERSION_BITS() macro since curl's own configure script greps for it 59 | and needs it to contain the full number. 60 | */ 61 | #define LIBCURL_VERSION_NUM 0x081000 62 | 63 | /* 64 | * This is the date and time when the full source package was created. The 65 | * timestamp is not stored in git, as the timestamp is properly set in the 66 | * tarballs by the maketgz script. 67 | * 68 | * The format of the date follows this template: 69 | * 70 | * "2007-11-23" 71 | */ 72 | #define LIBCURL_TIMESTAMP "[unreleased]" 73 | 74 | #define CURL_VERSION_BITS(x,y,z) ((x)<<16|(y)<<8|(z)) 75 | #define CURL_AT_LEAST_VERSION(x,y,z) \ 76 | (LIBCURL_VERSION_NUM >= CURL_VERSION_BITS(x, y, z)) 77 | 78 | #endif /* CURLINC_CURLVER_H */ 79 | -------------------------------------------------------------------------------- /source/tests/legacy_tests/game_of_life.axe: -------------------------------------------------------------------------------- 1 | use std.term(clear_screen); 2 | use std.time(wait); 3 | use std.random(randomize, random); 4 | use std.io; 5 | 6 | /// Convert 2D coordinate (x, y) into 1D index 7 | def idx(x: i32, y: i32, width: i32): i32 { 8 | return y * width + x; 9 | } 10 | 11 | /// Print the grid (1-D array) 12 | def print_grid(grid: ref i32[], width: i32, height: i32) { 13 | for mut y = 0; y < height; y++ { 14 | for mut x = 0; x < width; x++ { 15 | if grid[idx(x, y, width)] == 1 { 16 | print "■"; 17 | } else { 18 | print "□"; 19 | } 20 | } 21 | println ""; 22 | } 23 | } 24 | 25 | /// Count live neighbors around (x, y) 26 | def count_neighbors(grid: ref i32[], x: i32, y: i32, width: i32, height: i32): i32 { 27 | mut count: i32 = 0; 28 | 29 | for mut dy = -1; dy <= 1; dy++ { 30 | for mut dx = -1; dx <= 1; dx++ { 31 | if dx == 0 and dy == 0 { 32 | continue; 33 | } 34 | 35 | val nx = x + dx; 36 | val ny = y + dy; 37 | 38 | if nx >= 0 and nx < width and ny >= 0 and ny < height { 39 | if grid[idx(nx, ny, width)] == 1 { 40 | count = count + 1; 41 | } 42 | } 43 | } 44 | } 45 | 46 | return count; 47 | } 48 | 49 | /// Compute next generation 50 | def next_generation(grid: ref i32[], new_grid: ref i32[], width: i32, height: i32) { 51 | for mut y = 0; y < height; y++ { 52 | for mut x = 0; x < width; x++ { 53 | 54 | val i = idx(x, y, width); 55 | val neighbors = count_neighbors(grid, x, y, width, height); 56 | 57 | if grid[i] == 1 { 58 | if neighbors == 2 or neighbors == 3 { 59 | new_grid[i] = 1; 60 | } else { 61 | new_grid[i] = 0; 62 | } 63 | } else { 64 | if neighbors == 3 { 65 | new_grid[i] = 1; 66 | } else { 67 | new_grid[i] = 0; 68 | } 69 | } 70 | } 71 | } 72 | } 73 | 74 | /// Copy new_grid back into grid 75 | def copy_grid(src: ref i32[], dst: ref i32[], size: i32) { 76 | for mut i = 0; i < size; i++ { 77 | dst[i] = src[i]; 78 | } 79 | } 80 | 81 | def main() { 82 | randomize(); 83 | 84 | val width: i32 = 20; 85 | val height: i32 = 20; 86 | val size: i32 = width * height; 87 | 88 | mut grid: i32[size]; 89 | mut new_grid: i32[size]; 90 | 91 | for mut i = 0; i < size; i++ { 92 | new_grid[i] = 0; 93 | if random(0, 100) < 25 { 94 | grid[i] = 1; 95 | } else { 96 | grid[i] = 0; 97 | } 98 | } 99 | 100 | println "Conway's Game of Life (Random Start)\n"; 101 | 102 | for mut gen = 0; gen < 20000; gen++ { 103 | wait(1); 104 | clear_screen(); 105 | print "Generation "; 106 | println gen; 107 | println ""; 108 | 109 | print_grid(grid, width, height); 110 | 111 | next_generation(grid, new_grid, width, height); 112 | copy_grid(new_grid, grid, size); 113 | 114 | println "\n---\n"; 115 | } 116 | } 117 | -------------------------------------------------------------------------------- /source/compiler/external/curl/include/curl/mprintf.h: -------------------------------------------------------------------------------- 1 | #ifndef CURLINC_MPRINTF_H 2 | #define CURLINC_MPRINTF_H 3 | /*************************************************************************** 4 | * _ _ ____ _ 5 | * Project ___| | | | _ \| | 6 | * / __| | | | |_) | | 7 | * | (__| |_| | _ <| |___ 8 | * \___|\___/|_| \_\_____| 9 | * 10 | * Copyright (C) Daniel Stenberg, , et al. 11 | * 12 | * This software is licensed as described in the file COPYING, which 13 | * you should have received as part of this distribution. The terms 14 | * are also available at https://curl.se/docs/copyright.html. 15 | * 16 | * You may opt to use, copy, modify, merge, publish, distribute and/or sell 17 | * copies of the Software, and permit persons to whom the Software is 18 | * furnished to do so, under the terms of the COPYING file. 19 | * 20 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY 21 | * KIND, either express or implied. 22 | * 23 | * SPDX-License-Identifier: curl 24 | * 25 | ***************************************************************************/ 26 | 27 | #include 28 | #include /* needed for FILE */ 29 | #include "curl.h" /* for CURL_EXTERN */ 30 | 31 | #ifdef __cplusplus 32 | extern "C" { 33 | #endif 34 | 35 | #ifndef CURL_TEMP_PRINTF 36 | #if (defined(__GNUC__) || defined(__clang__) || \ 37 | defined(__IAR_SYSTEMS_ICC__)) && \ 38 | defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) && \ 39 | !defined(CURL_NO_FMT_CHECKS) 40 | #if defined(__MINGW32__) && !defined(__clang__) 41 | #ifdef __MINGW_PRINTF_FORMAT /* mingw-w64 3.0.0+. Needs stdio.h. */ 42 | #define CURL_TEMP_PRINTF(fmt, arg) \ 43 | __attribute__((format(__MINGW_PRINTF_FORMAT, fmt, arg))) 44 | #else 45 | #define CURL_TEMP_PRINTF(fmt, arg) 46 | #endif 47 | #else 48 | #define CURL_TEMP_PRINTF(fmt, arg) \ 49 | __attribute__((format(printf, fmt, arg))) 50 | #endif 51 | #else 52 | #define CURL_TEMP_PRINTF(fmt, arg) 53 | #endif 54 | #endif 55 | 56 | CURL_EXTERN int curl_mprintf(const char *format, ...) 57 | CURL_TEMP_PRINTF(1, 2); 58 | CURL_EXTERN int curl_mfprintf(FILE *fd, const char *format, ...) 59 | CURL_TEMP_PRINTF(2, 3); 60 | CURL_EXTERN int curl_msprintf(char *buffer, const char *format, ...) 61 | CURL_TEMP_PRINTF(2, 3); 62 | CURL_EXTERN int curl_msnprintf(char *buffer, size_t maxlength, 63 | const char *format, ...) 64 | CURL_TEMP_PRINTF(3, 4); 65 | CURL_EXTERN int curl_mvprintf(const char *format, va_list args) 66 | CURL_TEMP_PRINTF(1, 0); 67 | CURL_EXTERN int curl_mvfprintf(FILE *fd, const char *format, va_list args) 68 | CURL_TEMP_PRINTF(2, 0); 69 | CURL_EXTERN int curl_mvsprintf(char *buffer, const char *format, va_list args) 70 | CURL_TEMP_PRINTF(2, 0); 71 | CURL_EXTERN int curl_mvsnprintf(char *buffer, size_t maxlength, 72 | const char *format, va_list args) 73 | CURL_TEMP_PRINTF(3, 0); 74 | CURL_EXTERN char *curl_maprintf(const char *format, ...) 75 | CURL_TEMP_PRINTF(1, 2); 76 | CURL_EXTERN char *curl_mvaprintf(const char *format, va_list args) 77 | CURL_TEMP_PRINTF(1, 0); 78 | 79 | #undef CURL_TEMP_PRINTF 80 | 81 | #ifdef __cplusplus 82 | } /* end of extern "C" */ 83 | #endif 84 | 85 | #endif /* CURLINC_MPRINTF_H */ 86 | -------------------------------------------------------------------------------- /source/compiler/external/curl/include/curl/websockets.h: -------------------------------------------------------------------------------- 1 | #ifndef CURLINC_WEBSOCKETS_H 2 | #define CURLINC_WEBSOCKETS_H 3 | /*************************************************************************** 4 | * _ _ ____ _ 5 | * Project ___| | | | _ \| | 6 | * / __| | | | |_) | | 7 | * | (__| |_| | _ <| |___ 8 | * \___|\___/|_| \_\_____| 9 | * 10 | * Copyright (C) Daniel Stenberg, , et al. 11 | * 12 | * This software is licensed as described in the file COPYING, which 13 | * you should have received as part of this distribution. The terms 14 | * are also available at https://curl.se/docs/copyright.html. 15 | * 16 | * You may opt to use, copy, modify, merge, publish, distribute and/or sell 17 | * copies of the Software, and permit persons to whom the Software is 18 | * furnished to do so, under the terms of the COPYING file. 19 | * 20 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY 21 | * KIND, either express or implied. 22 | * 23 | * SPDX-License-Identifier: curl 24 | * 25 | ***************************************************************************/ 26 | 27 | #ifdef __cplusplus 28 | extern "C" { 29 | #endif 30 | 31 | struct curl_ws_frame { 32 | int age; /* zero */ 33 | int flags; /* See the CURLWS_* defines */ 34 | curl_off_t offset; /* the offset of this data into the frame */ 35 | curl_off_t bytesleft; /* number of pending bytes left of the payload */ 36 | size_t len; /* size of the current data chunk */ 37 | }; 38 | 39 | /* flag bits */ 40 | #define CURLWS_TEXT (1<<0) 41 | #define CURLWS_BINARY (1<<1) 42 | #define CURLWS_CONT (1<<2) 43 | #define CURLWS_CLOSE (1<<3) 44 | #define CURLWS_PING (1<<4) 45 | #define CURLWS_OFFSET (1<<5) 46 | 47 | /* 48 | * NAME curl_ws_recv() 49 | * 50 | * DESCRIPTION 51 | * 52 | * Receives data from the websocket connection. Use after successful 53 | * curl_easy_perform() with CURLOPT_CONNECT_ONLY option. 54 | */ 55 | CURL_EXTERN CURLcode curl_ws_recv(CURL *curl, void *buffer, size_t buflen, 56 | size_t *recv, 57 | const struct curl_ws_frame **metap); 58 | 59 | /* flags for curl_ws_send() */ 60 | #define CURLWS_PONG (1<<6) 61 | 62 | /* 63 | * NAME curl_ws_send() 64 | * 65 | * DESCRIPTION 66 | * 67 | * Sends data over the websocket connection. Use after successful 68 | * curl_easy_perform() with CURLOPT_CONNECT_ONLY option. 69 | */ 70 | CURL_EXTERN CURLcode curl_ws_send(CURL *curl, const void *buffer, 71 | size_t buflen, size_t *sent, 72 | curl_off_t fragsize, 73 | unsigned int flags); 74 | 75 | /* 76 | * NAME curl_ws_start_frame() 77 | * 78 | * DESCRIPTION 79 | * 80 | * Buffers a websocket frame header with the given flags and length. 81 | * Errors when a previous frame is not complete, e.g. not all its 82 | * payload has been added. 83 | */ 84 | CURL_EXTERN CURLcode curl_ws_start_frame(CURL *curl, 85 | unsigned int flags, 86 | curl_off_t frame_len); 87 | 88 | /* bits for the CURLOPT_WS_OPTIONS bitmask: */ 89 | #define CURLWS_RAW_MODE (1L<<0) 90 | #define CURLWS_NOAUTOPONG (1L<<1) 91 | 92 | CURL_EXTERN const struct curl_ws_frame *curl_ws_meta(CURL *curl); 93 | 94 | #ifdef __cplusplus 95 | } 96 | #endif 97 | 98 | #endif /* CURLINC_WEBSOCKETS_H */ 99 | -------------------------------------------------------------------------------- /source/compiler/std/time.axec: -------------------------------------------------------------------------------- 1 | use std.io ( 2 | print_i32, 3 | print_i64 4 | ); 5 | 6 | /// Represents the current date and time 7 | pub model DateTime { 8 | year: i32; 9 | month: i32; 10 | day: i32; 11 | hour: i32; 12 | minute: i32; 13 | second: i32; 14 | millisecond: i32; 15 | epoch_ms: i64; 16 | } 17 | 18 | /// Suspends the current thread for the specified number of milliseconds 19 | pub def wait(ms: i32) { 20 | platform posix { 21 | unsafe { 22 | C.sleep(ms / 1000); 23 | } 24 | } 25 | platform windows { 26 | unsafe { 27 | C.Sleep(ms); 28 | } 29 | } 30 | } 31 | 32 | /// Returns the current date and time 33 | pub def now(): DateTime { 34 | platform posix { 35 | foreign {time_t. tm}; 36 | unsafe { 37 | C.gettimeofday(addr(tv), nil); 38 | mut epoch_ms: i64 = cast[i64](tv.tv_sec) * 1000 + cast[i64](tv.tv_usec) / 1000; 39 | mut t: time_t = tv.tv_sec; 40 | mut tm: ref tm = C.localtime(addr(t)); 41 | mut dt: DateTime; 42 | dt.year = tm.tm_year + 1900; 43 | dt.month = tm.tm_mon + 1; 44 | dt.day = tm.tm_mday; 45 | dt.hour = tm.tm_hour; 46 | dt.minute = tm.tm_min; 47 | dt.second = tm.tm_sec; 48 | dt.millisecond = cast[i32](tv.tv_usec / 1000); 49 | dt.epoch_ms = epoch_ms; 50 | return dt; 51 | } 52 | } 53 | platform windows { 54 | foreign {SYSTEMTIME, FILETIME, ULARGE_INTEGER}; 55 | unsafe { 56 | mut st: SYSTEMTIME; 57 | C.GetLocalTime(addr(st)); 58 | mut ft: FILETIME; 59 | C.GetSystemTimeAsFileTime(addr(ft)); 60 | mut uli: ULARGE_INTEGER; 61 | uli.LowPart = ft.dwLowDateTime; 62 | uli.HighPart = ft.dwHighDateTime; 63 | val win_time_100ns: i64 = uli.QuadPart; 64 | val unix_time_100ns: i64 = win_time_100ns - 116444736000000000; 65 | val epoch_ms: i64 = unix_time_100ns / 10000; 66 | mut dt: DateTime; 67 | dt.year = st.wYear; 68 | dt.month = st.wMonth; 69 | dt.day = st.wDay; 70 | dt.hour = st.wHour; 71 | dt.minute = st.wMinute; 72 | dt.second = st.wSecond; 73 | dt.millisecond = st.wMilliseconds; 74 | dt.epoch_ms = epoch_ms; 75 | return dt; 76 | } 77 | } 78 | } 79 | 80 | /// Simple and accurate epoch-based difference calculation 81 | pub def difference(dt1: DateTime, dt2: DateTime): i64 { 82 | return dt2.epoch_ms - dt1.epoch_ms; 83 | } 84 | 85 | /// Prints the date and time in the format "YYYY-MM-DD HH:MM:SS.mmm" with optional newline 86 | pub def print_time(dt: DateTime, newline: bool) { 87 | print_i32(dt.year); 88 | print "-"; 89 | print_i32(dt.month); 90 | print "-"; 91 | print_i32(dt.day); 92 | print " "; 93 | print_i32(dt.hour); 94 | print ":"; 95 | print_i32(dt.minute); 96 | print ":"; 97 | print_i32(dt.second); 98 | print "."; 99 | print_i32(dt.millisecond); 100 | if newline { 101 | println ""; 102 | } 103 | } 104 | 105 | test { 106 | print "Started waiting at:\t"; 107 | print_time(now(), true); 108 | val start: DateTime = now(); 109 | wait(1000); 110 | print "Done waiting at:\t"; 111 | print_time(now(), true); 112 | println "Difference: "; 113 | print_i64(difference(start, now())); 114 | } 115 | -------------------------------------------------------------------------------- /source/compiler/std/arena.axec: -------------------------------------------------------------------------------- 1 | use std.io ( 2 | println, 3 | print 4 | ); 5 | 6 | use std.string ( 7 | concat, 8 | i32_to_string, 9 | str 10 | ); 11 | 12 | use std.errors ( 13 | error, 14 | panic 15 | ); 16 | 17 | /// Arena for memory allocation. 18 | pub model Arena { 19 | buffer: usize; 20 | capacity: usize; 21 | offset: usize; 22 | 23 | /// Creates a new arena with the specified size. 24 | pub def create(size: usize): Arena { 25 | mut arena: Arena; 26 | 27 | unsafe { 28 | arena.buffer = C.malloc(size * 100); 29 | if arena.buffer == 0 { 30 | panic(error.create( 31 | concat(str("Arena: failed to allocate "), 32 | i32_to_string(cast[i32](size * 100))).data 33 | )); 34 | } 35 | arena.capacity = size * 100; 36 | arena.offset = 0; 37 | } 38 | 39 | return arena; 40 | } 41 | 42 | /// Destroys the arena and frees its memory. 43 | pub def destroy(arena: ref Arena) { 44 | unsafe { 45 | C.free(cast[ref void](arena*.buffer)); 46 | arena*.buffer = 0; 47 | arena*.offset = 0; 48 | arena*.capacity = 0; 49 | } 50 | } 51 | 52 | /// Allocates memory from the arena, returns a proper reference pointer. 53 | pub def alloc(arena: ref Arena, size: usize): ref void { 54 | mut result: ref void = nil; 55 | 56 | unsafe { 57 | if (arena*.offset + size > arena*.capacity) { 58 | mut msg: string = str("Arena out of memory! cap="); 59 | msg = concat(msg, i32_to_string(arena*.capacity)); 60 | msg = concat_c(msg, " used="); 61 | msg = concat(msg, i32_to_string(arena*.offset)); 62 | msg = concat_c(msg, " req="); 63 | msg = concat(msg, i32_to_string(cast[i32](size))); 64 | msg = concat_c(msg, "\n"); 65 | panic(error.create(msg.data)); 66 | return nil; 67 | } 68 | result = cast[ref void](arena*.buffer + arena*.offset); 69 | arena*.offset = arena*.offset + size; 70 | arena*.offset = (arena*.offset + 7) & ~7; 71 | } 72 | 73 | return result; 74 | } 75 | 76 | /// Allocates memory for an array from the arena. 77 | pub def alloc_array(arena: ref Arena, element_size: usize, count: usize): ref void { 78 | val total_size: usize = element_size * count; 79 | return Arena.alloc(arena, total_size); 80 | } 81 | 82 | /// Resets the arena, clearing all allocated memory. 83 | pub def reset(arena: ref Arena) { 84 | unsafe { 85 | arena*.offset = 0; 86 | C.memset(cast[ref void](arena*.buffer), 0, arena*.capacity); 87 | } 88 | } 89 | 90 | /// Returns the amount of memory used by the arena. 91 | pub def used(arena: ref Arena): i32 { 92 | mut result: i32 = 0; 93 | unsafe { 94 | result = arena*.offset; 95 | } 96 | return result; 97 | } 98 | 99 | /// Returns the amount of remaining memory in the arena. 100 | pub def remaining(arena: ref Arena): usize { 101 | mut result: usize = 0; 102 | unsafe { 103 | result = (arena*.capacity) - (arena*.offset); 104 | } 105 | return result; 106 | } 107 | } 108 | 109 | test { 110 | assert(Arena.create(1024).capacity == 102400, "Arena.create should set capacity correctly"); 111 | assert(Arena.create(2048).offset == 0, "new arena should have offset 0"); 112 | } 113 | -------------------------------------------------------------------------------- /source/tests/legacy_tests/stress.axe: -------------------------------------------------------------------------------- 1 | use std.arena ( 2 | Arena, 3 | arena_create, 4 | arena_destroy, 5 | arena_alloc 6 | ); 7 | 8 | use std.memory ( 9 | copy 10 | ); 11 | 12 | model Cell { 13 | temperature: int; 14 | } 15 | 16 | def init_grid(grid: Cell[rows][cols], rows: int, cols: int, arena: Arena) { 17 | mut val r: int = 0; 18 | loop { 19 | if r >= rows { 20 | break; 21 | } 22 | 23 | mut val c: int = 0; 24 | loop { 25 | if c >= cols { 26 | break; 27 | } 28 | 29 | // Allocate a Cell from the arena (not strictly necessary here but for stress-testing arena) 30 | val cell_ptr: long = arena_alloc(addr(arena), sizeof(Cell)); 31 | grid[r][c].temperature = 20 + (r * c) mod 50; 32 | c++; 33 | } 34 | r++; 35 | } 36 | } 37 | 38 | def diffuse(grid: Cell[rows][cols], new_grid: Cell[rows][cols], rows: int, cols: int) { 39 | mut val r: int = 0; 40 | loop { 41 | if r >= rows { 42 | break; 43 | } 44 | 45 | mut val c: int = 0; 46 | loop { 47 | if c >= cols { 48 | break; 49 | } 50 | 51 | mut val sum: int = grid[r][c].temperature; 52 | mut val count: int = 1; 53 | 54 | if r > 0 { 55 | sum = sum + grid[r-1][c].temperature; 56 | count = count + 1; 57 | } 58 | 59 | if r < rows - 1 { 60 | sum = sum + grid[r+1][c].temperature; 61 | count = count + 1; 62 | } 63 | 64 | if c > 0 { 65 | sum = sum + grid[r][c-1].temperature; 66 | count = count + 1; 67 | } 68 | 69 | if c < cols - 1 { 70 | sum = sum + grid[r][c+1].temperature; 71 | count = count + 1; 72 | } 73 | 74 | new_grid[r][c].temperature = sum / count; 75 | 76 | c++; 77 | } 78 | 79 | r++; 80 | } 81 | } 82 | 83 | def print_grid(grid: Cell[rows][cols], rows: int, cols: int) { 84 | mut val r: int = 0; 85 | loop { 86 | if r >= rows { 87 | break; 88 | } 89 | 90 | mut val c: int = 0; 91 | loop { 92 | if c >= cols { 93 | break; 94 | } 95 | 96 | print grid[r][c].temperature; 97 | print " "; 98 | c++; 99 | } 100 | 101 | println ""; 102 | r++; 103 | } 104 | } 105 | 106 | def main() { 107 | val rows: int = 10; 108 | val cols: int = 10; 109 | mut val arena: Arena = arena_create(65536); 110 | 111 | // Create two grids for double-buffering 112 | mut val grid: Cell[10][10]; 113 | mut val new_grid: Cell[10][10]; 114 | 115 | init_grid(grid, rows, cols, arena); 116 | 117 | println "Initial grid:"; 118 | print_grid(grid, rows, cols); 119 | println ""; 120 | 121 | mut val step: int = 0; 122 | loop { 123 | if step >= 5 { 124 | break; 125 | } 126 | 127 | diffuse(grid, new_grid, rows, cols); 128 | 129 | // Swap grids 130 | mut val temp: Cell[10][10]; 131 | 132 | copy(temp, grid, Cell[10][10]); 133 | copy(grid, new_grid, Cell[10][10]); 134 | copy(new_grid, temp, Cell[10][10]); 135 | 136 | println "Step "; 137 | print step; 138 | println ":"; 139 | print_grid(grid, rows, cols); 140 | println ""; 141 | 142 | step++; 143 | } 144 | 145 | arena_destroy(addr(arena)); 146 | println "Arena destroyed - memory freed!"; 147 | } 148 | -------------------------------------------------------------------------------- /source/compiler/std/io.axec: -------------------------------------------------------------------------------- 1 | use std.string; 2 | 3 | /// Print out some value with a newline 4 | overload println(x: generic) { 5 | string => print_str; 6 | char* => println_chrptr; 7 | i32 => println_i32; 8 | char => println_char; 9 | f32 => println_f32; 10 | f64 => println_f64; 11 | i64 => println_i64; 12 | bool => println_bool; 13 | }(x); 14 | 15 | /// Print out some value with no newline 16 | overload print(x: generic) { 17 | string => print_str; 18 | char* => print_chrptr; 19 | i32 => print_i32; 20 | char => print_char; 21 | f32 => print_f32; 22 | f64 => print_f64; 23 | i64 => print_i64; 24 | bool => print_bool; 25 | }(x); 26 | 27 | /// Print out some char 28 | pub def print_char(value: char) { 29 | unsafe { 30 | C.printf("%c", value); 31 | } 32 | } 33 | 34 | /// Print out some char with a newline 35 | pub def println_char(value: char) { 36 | unsafe { 37 | C.printf("%c\n", value); 38 | } 39 | } 40 | 41 | /// Print out some string 42 | pub def print_chrptr(value: ref char) { 43 | unsafe { 44 | C.printf("%s", value); 45 | } 46 | } 47 | 48 | /// Print out some string with a newline 49 | pub def println_chrptr(value: ref char) { 50 | unsafe { 51 | C.printf("%s\n", value); 52 | } 53 | } 54 | 55 | /// Print out some string 56 | pub def print_str(value: string) { 57 | unsafe { 58 | C.printf("%s", value.data); 59 | } 60 | } 61 | 62 | /// Print out some string with a newline 63 | pub def println_str(value: string) { 64 | unsafe { 65 | C.printf("%s\n", value.data); 66 | } 67 | } 68 | 69 | /// Print out some float with no newline 70 | pub def print_f32(value: f32) { 71 | unsafe { 72 | C.printf("%.10f", value); 73 | } 74 | } 75 | 76 | /// Print a float with newline 77 | pub def println_f32(value: f32) { 78 | unsafe { 79 | C.printf("%.10f\n", value); 80 | } 81 | } 82 | 83 | pub def println_f64(value: f64) { 84 | unsafe { 85 | C.printf("%.10f\n", value); 86 | } 87 | } 88 | 89 | pub def print_f64(value: f64) { 90 | unsafe { 91 | C.printf("%.10f", value); 92 | } 93 | } 94 | 95 | pub def println_i64(value: i64) { 96 | unsafe { 97 | C.printf("%ld\n", value); 98 | } 99 | } 100 | 101 | pub def print_i64(value: i64) { 102 | unsafe { 103 | C.printf("%ld", value); 104 | } 105 | } 106 | 107 | /// Print out some int with no newline 108 | pub def print_i32(value: i32) { 109 | unsafe { 110 | C.printf("%d", value); 111 | } 112 | } 113 | 114 | /// Print an int with newline 115 | pub def println_i32(value: i32) { 116 | unsafe { 117 | C.printf("%d\n", value); 118 | } 119 | } 120 | 121 | /// Print a boolean with no newline 122 | pub def print_bool(value: bool) { 123 | unsafe { 124 | if value { 125 | C.printf("true"); 126 | } else { 127 | C.printf("false"); 128 | } 129 | } 130 | } 131 | 132 | /// Print a boolean with newline 133 | pub def println_bool(value: bool) { 134 | unsafe { 135 | if value { 136 | C.printf("true\n"); 137 | } else { 138 | C.printf("false\n"); 139 | } 140 | } 141 | } 142 | 143 | test { 144 | val x: f32 = 3.14159; 145 | val y: f32 = 2.71828; 146 | 147 | print_f32(x); 148 | println ""; 149 | println "Testing println_float:"; 150 | println_f32(y); 151 | 152 | print_i32(42); 153 | println ""; 154 | println "Testing println_int:"; 155 | println_i32(42); 156 | 157 | print_bool(true); 158 | println ""; 159 | println "Testing println_bool:"; 160 | println_bool(true); 161 | } 162 | -------------------------------------------------------------------------------- /source/compiler/gstate.axe: -------------------------------------------------------------------------------- 1 | /// Author: Navid Momtahen (C) 2025 2 | /// License: GPL-3.0 3 | /// 4 | /// Handles the global state. 5 | 6 | use std.io; 7 | use std.lists (StringList); 8 | 9 | pub mut loud_logger: bool = false; 10 | pub mut is_release_build: bool = false; 11 | pub mut keep_emitted_file: bool = false; 12 | pub mut run_after_compile: bool = false; 13 | pub mut print_tokens: bool = false; 14 | pub mut print_ast: bool = false; 15 | pub mut build_shared_lib: bool = false; 16 | pub mut bootstrap_mode: bool = false; 17 | pub mut include_paths: ref StringList = nil; 18 | pub mut quiet_mode: bool = false; 19 | pub mut syntax_check_only: bool = false; 20 | pub mut target_triple: string; 21 | pub mut sysroot_path: string; 22 | pub mut compile_only: bool = false; 23 | pub mut library_paths: ref StringList = nil; 24 | pub mut link_libraries: ref StringList = nil; 25 | 26 | /// Print a debug message 27 | overload debug_print(x: generic) { 28 | string => debug_print_str; 29 | char* => debug_print_raw; 30 | i32 => debug_print_int; 31 | }(x); 32 | 33 | /// Enable verbose logging 34 | pub def set_loud_logger(v: bool) { 35 | loud_logger = v; 36 | } 37 | 38 | /// Set release build mode 39 | pub def set_release_build(v: bool) { 40 | is_release_build = v; 41 | } 42 | 43 | /// Set keep emitted file flag 44 | pub def set_keep_emitted_file(v: bool) { 45 | keep_emitted_file = v; 46 | } 47 | 48 | /// Set run after compile flag 49 | pub def set_run_after_compile(v: bool) { 50 | run_after_compile = v; 51 | } 52 | 53 | /// Set print tokens flag 54 | pub def set_print_tokens(v: bool) { 55 | print_tokens = v; 56 | } 57 | 58 | /// Set print AST flag 59 | pub def set_print_ast(v: bool) { 60 | print_ast = v; 61 | } 62 | 63 | /// Set build shared library flag 64 | pub def set_build_shared_lib(v: bool) { 65 | build_shared_lib = v; 66 | } 67 | 68 | /// Set bootstrap mode (emit raw C without line directives, write `axe.c`) 69 | pub def set_bootstrap_mode(v: bool) { 70 | bootstrap_mode = v; 71 | } 72 | 73 | /// Set include paths list 74 | pub def set_include_paths(paths: ref StringList) { 75 | include_paths = paths; 76 | } 77 | 78 | /// Get include paths list 79 | pub def get_include_paths(): ref StringList { 80 | return include_paths; 81 | } 82 | 83 | /// Set quiet mode flag 84 | pub def set_quiet_mode(v: bool) { 85 | quiet_mode = v; 86 | } 87 | 88 | /// Set syntax check only mode (no code generation) 89 | pub def set_syntax_check_only(v: bool) { 90 | syntax_check_only = v; 91 | } 92 | 93 | /// Set target triple for cross-compilation 94 | pub def set_target_triple(triple: string) { 95 | target_triple = triple; 96 | } 97 | 98 | /// Get target triple for cross-compilation 99 | pub def get_target_triple(): string { 100 | return target_triple; 101 | } 102 | 103 | /// Set sysroot path for cross-compilation 104 | pub def set_sysroot_path(path: string) { 105 | sysroot_path = path; 106 | } 107 | 108 | /// Get sysroot path for cross-compilation 109 | pub def get_sysroot_path(): string { 110 | return sysroot_path; 111 | } 112 | 113 | /// Set compile only mode (produce object file) 114 | pub def set_compile_only(v: bool) { 115 | compile_only = v; 116 | } 117 | 118 | /// Get compile only mode 119 | pub def get_compile_only(): bool { 120 | return compile_only; 121 | } 122 | 123 | /// Set library search paths list 124 | pub def set_library_paths(paths: ref StringList) { 125 | library_paths = paths; 126 | } 127 | 128 | /// Get library search paths list 129 | pub def get_library_paths(): ref StringList { 130 | return library_paths; 131 | } 132 | 133 | /// Set libraries to link list 134 | pub def set_link_libraries(libs: ref StringList) { 135 | link_libraries = libs; 136 | } 137 | 138 | /// Get libraries to link list 139 | pub def get_link_libraries(): ref StringList { 140 | return link_libraries; 141 | } 142 | 143 | /// Ditto. 144 | pub def debug_print_i32(msg: i32) { 145 | if loud_logger { 146 | println msg; 147 | } 148 | } 149 | 150 | /// Ditto. 151 | pub def debug_print_str(msg: string) { 152 | if loud_logger { 153 | println msg; 154 | } 155 | } 156 | 157 | /// Ditto. 158 | pub def debug_print_raw(msg: ref char) { 159 | if loud_logger { 160 | println msg; 161 | } 162 | } 163 | 164 | test { 165 | 166 | } 167 | -------------------------------------------------------------------------------- /source/compiler/std/lists.axec: -------------------------------------------------------------------------------- 1 | use std.arena ( 2 | Arena 3 | ); 4 | 5 | use std.io ( 6 | print_i32, 7 | print_str, 8 | print_char, 9 | println 10 | ); 11 | 12 | use std.string ( 13 | string, 14 | string_equals 15 | ); 16 | 17 | use std.errors ( 18 | panic, 19 | error 20 | ); 21 | 22 | macro make_list( 23 | name: string, 24 | type: string, 25 | nullval: untyped, 26 | cep: untyped, 27 | printer: untyped 28 | ) { 29 | pub model name { 30 | data: ref type; 31 | len: usize; 32 | cap: usize; 33 | 34 | pub def create(arena: ref Arena, capacity: usize): ref name { 35 | mut lst: ref name; 36 | unsafe { 37 | lst = Arena.alloc(arena, C.sizeof(name)); 38 | lst*.data = Arena.alloc_array(arena, C.sizeof(type), capacity); 39 | } 40 | if lst == nil { 41 | panic(error.create("List: failed to allocate list header")); 42 | } 43 | if lst*.data == nil { 44 | panic(error.create("List: failed to allocate list data")); 45 | } 46 | lst.len = 0; 47 | lst.cap = capacity; 48 | return lst; 49 | } 50 | 51 | pub def push(lst: ref name, arena: ref Arena, value: type) { 52 | if lst.len >= lst.cap { 53 | val new_cap: usize = lst.cap * 2; 54 | mut new_data: ref type; 55 | unsafe { 56 | new_data = Arena.alloc_array(arena, C.sizeof(type), new_cap); 57 | for mut i = 0; i < lst*.len; i++ { 58 | C.memcpy(&(new_data[i]), &(lst*.data[i]), C.sizeof(type)); 59 | } 60 | } 61 | lst.data = new_data; 62 | lst.cap = new_cap; 63 | } 64 | lst.data[lst.len] = value; 65 | lst.len = lst.len + 1; 66 | } 67 | 68 | pub def get(lst: ref name, index: usize): type { 69 | if index < 0 or index >= lst.len { 70 | panic(error.create("Index out of bounds for list.")); 71 | return nullval; 72 | } 73 | return lst.data[index]; 74 | } 75 | 76 | pub def clear(lst: ref name) { 77 | lst.len = 0; 78 | } 79 | 80 | pub def contains(lst: ref name, value: type): bool { 81 | for mut i = 0; i < lst.len; i++ { 82 | if cep(lst.data[i], value) { 83 | return true; 84 | } 85 | } 86 | return false; 87 | } 88 | 89 | pub def print_all(lst: ref name) { 90 | for mut i = 0; i < lst.len; i++ { 91 | printer(lst.data[i]); 92 | print " "; 93 | } 94 | println ""; 95 | } 96 | } 97 | } 98 | 99 | def int_eq(a: i32, b: i32): bool { return a == b; } 100 | def long_eq(a: i64, b: i64): bool { return a == b; } 101 | def float_eq(a: f32, b: f32): bool { return a == b; } 102 | def double_eq(a: f64, b: f64): bool { return a == b; } 103 | def char_eq(a: char, b: char): bool { return a == b; } 104 | def bool_eq(a: bool, b: bool): bool { return a == b; } 105 | 106 | make_list(IntList, i32, 0, int_eq, print_i32); 107 | make_list(FloatList, f32, 0.0, float_eq, print_i32); 108 | make_list(CharList, char, "", char_eq, print_char); 109 | make_list(LongList, i64, 0, long_eq, print_i32); 110 | make_list(DoubleList, f64, 0.0, double_eq, print_i32); 111 | make_list(StringList, std__string__string, string.create(""), string_equals, print_str); 112 | make_list(BoolList, bool, false, bool_eq, print_i32); 113 | 114 | test { 115 | mut arena: Arena = Arena.create(65536); 116 | mut my_list: ref IntList = IntList.create(addr(arena), 4); 117 | 118 | IntList.push(my_list, addr(arena), 10); 119 | IntList.push(my_list, addr(arena), 20); 120 | IntList.push(my_list, addr(arena), 30); 121 | IntList.push(my_list, addr(arena), 40); 122 | IntList.push(my_list, addr(arena), 50); 123 | 124 | println "IntList contents:"; 125 | 126 | IntList.print_all(my_list); 127 | 128 | println "Element at index 2:"; 129 | println IntList.get(my_list, cast[usize](2)); 130 | 131 | Arena.destroy(addr(arena)); 132 | } 133 | -------------------------------------------------------------------------------- /source/tests/legacy_tests/stress3.axe: -------------------------------------------------------------------------------- 1 | use stdlib/arena ( 2 | Arena, 3 | arena_create, 4 | arena_destroy, 5 | arena_alloc, 6 | arena_alloc_array, 7 | arena_get_remaining 8 | ); 9 | 10 | use stdlib/memory ( 11 | copy, 12 | size_of 13 | ); 14 | 15 | model Particle { 16 | x: int; 17 | y: int; 18 | vx: int; 19 | vy: int; 20 | } 21 | 22 | def main() { 23 | println "=== PARTICLE SNAPSHOT STRESS TEST ==="; 24 | 25 | // config 26 | val PARTICLE_COUNT: int = 50; 27 | val STEPS: int = 20; 28 | val SNAPSHOT_INTERVAL: int = 5; 29 | val MAX_SNAPSHOTS: int = (STEPS / SNAPSHOT_INTERVAL) + 1; 30 | 31 | // arenas for temporary text buffers (exercise arena_alloc) 32 | mut val arena: Arena = arena_create(131072); 33 | 34 | // particle storage (stack / dependent arrays) 35 | mut val particles: Particle[50]; 36 | 37 | // snapshot archive: MAX_SNAPSHOTS × PARTICLE_COUNT 38 | mut val snapshots: Particle[10][50]; // MAX_SNAPSHOTS=5 by config above, 10 is safe upper bound 39 | 40 | // initialize particles in a pattern 41 | mut val i: int = 0; 42 | loop { 43 | if i >= PARTICLE_COUNT { 44 | break; 45 | } 46 | particles[i].x = i * 2; 47 | particles[i].y = 0; 48 | particles[i].vx = (i mod 3) - 1; // -1,0,1 pattern 49 | particles[i].vy = 0; 50 | i = i + 1; 51 | } 52 | 53 | println "Initialized particles."; 54 | 55 | mut val step: int = 0; 56 | mut val snap_idx: int = 0; 57 | 58 | loop { 59 | if step > STEPS { 60 | break; 61 | } 62 | 63 | // take snapshot at step 0 and every SNAPSHOT_INTERVAL 64 | if step mod SNAPSHOT_INTERVAL == 0 { 65 | if snap_idx < MAX_SNAPSHOTS { 66 | // copy full particle array into snapshots[snap_idx] 67 | // copy(src, dest, type) 68 | copy(particles, snapshots[snap_idx], Particle[50]); 69 | print "Taken snapshot "; 70 | print snap_idx; 71 | print " at step "; 72 | println step; 73 | snap_idx = snap_idx + 1; 74 | } else { 75 | println "Snapshot buffer full; skipping snapshot"; 76 | } 77 | } 78 | 79 | // update physics for this step (skip update at final step to keep last snapshot) 80 | if step < STEPS { 81 | mut val u: int = 0; 82 | loop { 83 | if u >= PARTICLE_COUNT { 84 | break; 85 | } 86 | 87 | // gravity 88 | particles[u].vy = particles[u].vy + 1; 89 | 90 | // integrate 91 | particles[u].x = particles[u].x + particles[u].vx; 92 | particles[u].y = particles[u].y + particles[u].vy; 93 | 94 | // floor bounce at y = 20 95 | if particles[u].y > 20 { 96 | particles[u].y = 20; 97 | particles[u].vy = -particles[u].vy / 2; 98 | } 99 | 100 | u = u + 1; 101 | } 102 | } 103 | 104 | step = step + 1; 105 | } 106 | 107 | println "Simulation complete. Printing snapshots..."; 108 | 109 | // print all snapshots 110 | mut val s: int = 0; 111 | loop { 112 | if s >= snap_idx { 113 | break; 114 | } 115 | 116 | print "Snapshot "; 117 | print s; 118 | println ":"; 119 | 120 | mut val p: int = 0; 121 | loop { 122 | if p >= PARTICLE_COUNT { 123 | break; 124 | } 125 | 126 | print "("; 127 | print snapshots[s][p].x; 128 | print ", "; 129 | print snapshots[s][p].y; 130 | print ") "; 131 | 132 | p = p + 1; 133 | } 134 | 135 | println ""; 136 | println "----"; 137 | s = s + 1; 138 | } 139 | 140 | // allocate a text buffer in arena to exercise arena_alloc usage 141 | val buf_ptr: long = arena_alloc(addr(arena), 1024); 142 | // we won't dereference the numeric pointer here (std rules), but this ensures arena works under load 143 | print "Arena remaining after allocations: "; 144 | print arena_get_remaining(addr(arena)); 145 | println ""; 146 | 147 | arena_destroy(addr(arena)); 148 | 149 | println "Arena destroyed - memory freed!"; 150 | println "=== END TEST ==="; 151 | } 152 | -------------------------------------------------------------------------------- /source/compiler/external/curl/include/curl/easy.h: -------------------------------------------------------------------------------- 1 | #ifndef CURLINC_EASY_H 2 | #define CURLINC_EASY_H 3 | /*************************************************************************** 4 | * _ _ ____ _ 5 | * Project ___| | | | _ \| | 6 | * / __| | | | |_) | | 7 | * | (__| |_| | _ <| |___ 8 | * \___|\___/|_| \_\_____| 9 | * 10 | * Copyright (C) Daniel Stenberg, , et al. 11 | * 12 | * This software is licensed as described in the file COPYING, which 13 | * you should have received as part of this distribution. The terms 14 | * are also available at https://curl.se/docs/copyright.html. 15 | * 16 | * You may opt to use, copy, modify, merge, publish, distribute and/or sell 17 | * copies of the Software, and permit persons to whom the Software is 18 | * furnished to do so, under the terms of the COPYING file. 19 | * 20 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY 21 | * KIND, either express or implied. 22 | * 23 | * SPDX-License-Identifier: curl 24 | * 25 | ***************************************************************************/ 26 | #ifdef __cplusplus 27 | extern "C" { 28 | #endif 29 | 30 | /* Flag bits in the curl_blob struct: */ 31 | #define CURL_BLOB_COPY 1 /* tell libcurl to copy the data */ 32 | #define CURL_BLOB_NOCOPY 0 /* tell libcurl to NOT copy the data */ 33 | 34 | struct curl_blob { 35 | void *data; 36 | size_t len; 37 | unsigned int flags; /* bit 0 is defined, the rest are reserved and should be 38 | left zeroes */ 39 | }; 40 | 41 | CURL_EXTERN CURL *curl_easy_init(void); 42 | CURL_EXTERN CURLcode curl_easy_setopt(CURL *curl, CURLoption option, ...); 43 | CURL_EXTERN CURLcode curl_easy_perform(CURL *curl); 44 | CURL_EXTERN void curl_easy_cleanup(CURL *curl); 45 | 46 | /* 47 | * NAME curl_easy_getinfo() 48 | * 49 | * DESCRIPTION 50 | * 51 | * Request internal information from the curl session with this function. 52 | * The third argument MUST be pointing to the specific type of the used option 53 | * which is documented in each manpage of the option. The data pointed to 54 | * will be filled in accordingly and can be relied upon only if the function 55 | * returns CURLE_OK. This function is intended to get used *AFTER* a performed 56 | * transfer, all results from this function are undefined until the transfer 57 | * is completed. 58 | */ 59 | CURL_EXTERN CURLcode curl_easy_getinfo(CURL *curl, CURLINFO info, ...); 60 | 61 | 62 | /* 63 | * NAME curl_easy_duphandle() 64 | * 65 | * DESCRIPTION 66 | * 67 | * Creates a new curl session handle with the same options set for the handle 68 | * passed in. Duplicating a handle could only be a matter of cloning data and 69 | * options, internal state info and things like persistent connections cannot 70 | * be transferred. It is useful in multithreaded applications when you can run 71 | * curl_easy_duphandle() for each new thread to avoid a series of identical 72 | * curl_easy_setopt() invokes in every thread. 73 | */ 74 | CURL_EXTERN CURL *curl_easy_duphandle(CURL *curl); 75 | 76 | /* 77 | * NAME curl_easy_reset() 78 | * 79 | * DESCRIPTION 80 | * 81 | * Re-initializes a curl handle to the default values. This puts back the 82 | * handle to the same state as it was in when it was just created. 83 | * 84 | * It does keep: live connections, the Session ID cache, the DNS cache and the 85 | * cookies. 86 | */ 87 | CURL_EXTERN void curl_easy_reset(CURL *curl); 88 | 89 | /* 90 | * NAME curl_easy_recv() 91 | * 92 | * DESCRIPTION 93 | * 94 | * Receives data from the connected socket. Use after successful 95 | * curl_easy_perform() with CURLOPT_CONNECT_ONLY option. 96 | */ 97 | CURL_EXTERN CURLcode curl_easy_recv(CURL *curl, void *buffer, size_t buflen, 98 | size_t *n); 99 | 100 | /* 101 | * NAME curl_easy_send() 102 | * 103 | * DESCRIPTION 104 | * 105 | * Sends data over the connected socket. Use after successful 106 | * curl_easy_perform() with CURLOPT_CONNECT_ONLY option. 107 | */ 108 | CURL_EXTERN CURLcode curl_easy_send(CURL *curl, const void *buffer, 109 | size_t buflen, size_t *n); 110 | 111 | 112 | /* 113 | * NAME curl_easy_upkeep() 114 | * 115 | * DESCRIPTION 116 | * 117 | * Performs connection upkeep for the given session handle. 118 | */ 119 | CURL_EXTERN CURLcode curl_easy_upkeep(CURL *curl); 120 | 121 | #ifdef __cplusplus 122 | } /* end of extern "C" */ 123 | #endif 124 | 125 | #endif 126 | -------------------------------------------------------------------------------- /source/compiler/axc.axe: -------------------------------------------------------------------------------- 1 | /// Author: Navid Momtahen (C) 2025 2 | /// License: GPL-3.0 3 | 4 | use std.algorithms; 5 | use std.io; 6 | use std.os; 7 | use std.lists; 8 | use std.string; 9 | use builds; 10 | use gstate; 11 | 12 | def main() { 13 | val arena: Arena = Arena.create(1024); 14 | val args: ref StringList = get_cmdline_args(addr(arena)); 15 | 16 | if args.len < 2 { 17 | println("Usage: axe [options]"); 18 | println(""); 19 | println("Options:"); 20 | println(" -o Specify output binary name"); 21 | println(" -c Compile only; produce object file (.obj or .o)"); 22 | println(" -e Keep the emitted file"); 23 | println(" -r Run the built executable after compilation"); 24 | println(" -tokens Print lexer tokens and exit"); 25 | println(" -ast Print the parsed AST and exit"); 26 | println(" -dll Build shared instead of standalone executable"); 27 | println(" --release Build in release mode"); 28 | println(" --bootstrap Emit without line directives"); 29 | println(" -l, --loud Loud debug output"); 30 | println(" -q, --quiet Suppress all output"); 31 | println(" -I Pass a C include directory"); 32 | println(" -L Add C library search path"); 33 | println(" -l Link against C library (e.g. -lm, -lSDL2)"); 34 | println(" --syntax-check Check syntax only (no code generation)"); 35 | println(" --target Cross-compile for target (e.g. x86_64-w64-mingw32)"); 36 | println(" --sysroot Specify sysroot for cross-compilation"); 37 | println(" --version, -v Show axe version and exit"); 38 | println(""); 39 | println("Note: Cross-compiling requires the target platform's SDK and sysroot.\n"); 40 | quit(0); 41 | } 42 | 43 | mut source_file: string = StringList.get(args, 1); 44 | mut output_filename: string = str(""); 45 | val inc_paths: ref StringList = StringList.create(addr(arena), 16); 46 | val lib_paths: ref StringList = StringList.create(addr(arena), 16); 47 | val link_libs: ref StringList = StringList.create(addr(arena), 16); 48 | 49 | set_include_paths(inc_paths); 50 | set_library_paths(lib_paths); 51 | set_link_libraries(link_libs); 52 | 53 | mut i: i32 = 2; 54 | 55 | loop { 56 | if i >= args.len { 57 | break; 58 | } 59 | val arg: string = StringList.get(args, i); 60 | if equals_c(arg, "-o") and i + 1 < args.len { 61 | output_filename = StringList.get(args, i + 1); 62 | i += 2; 63 | continue; 64 | } 65 | if equals_c(arg, "-c") { 66 | set_compile_only(true); 67 | i++; 68 | continue; 69 | } 70 | if equals_c(arg, "--target") and i + 1 < args.len { 71 | val target: string = StringList.get(args, i + 1); 72 | set_target_triple(target); 73 | i += 2; 74 | continue; 75 | } 76 | if equals_c(arg, "--bootstrap") { 77 | set_bootstrap_mode(true); 78 | i++; 79 | continue; 80 | } 81 | if equals_c(arg, "--sysroot") and i + 1 < args.len { 82 | val sysroot: string = StringList.get(args, i + 1); 83 | set_sysroot_path(sysroot); 84 | i += 2; 85 | continue; 86 | } 87 | if has_prefix(arg, str("-I")) and str_len(arg) > 2 { 88 | val inc_path: string = substring_se(arg, 2, cast[i32](str_len(arg))); 89 | StringList.push(inc_paths, addr(arena), inc_path); 90 | } 91 | if has_prefix(arg, str("-L")) and str_len(arg) > 2 { 92 | val lib_path: string = substring_se(arg, 2, cast[i32](str_len(arg))); 93 | StringList.push(lib_paths, addr(arena), lib_path); 94 | } 95 | if has_prefix(arg, str("-l")) and str_len(arg) > 2 { 96 | val lib_name: string = substring_se(arg, 2, cast[i32](str_len(arg))); 97 | StringList.push(link_libs, addr(arena), lib_name); 98 | } 99 | i++; 100 | } 101 | 102 | if strlst_contains_c(deref(args), "-v") or strlst_contains_c(deref(args), "--version") { 103 | println("Axe v0.0.9"); 104 | println("Specification and compiler by Navid Momtahen ((C) GPL-3.0, 2025)\n"); 105 | quit(0); 106 | } 107 | 108 | if strlst_contains_c(deref(args), "-l") or strlst_contains_c(deref(args), "--loud") { 109 | set_loud_logger(true); 110 | } 111 | 112 | if strlst_contains_c(deref(args), "-q") or strlst_contains_c(deref(args), "--quiet") { 113 | set_quiet_mode(true); 114 | } 115 | 116 | if strlst_contains_c(deref(args), "--release") { 117 | set_release_build(true); 118 | } 119 | 120 | if strlst_contains_c(deref(args), "-e") { 121 | set_keep_emitted_file(true); 122 | } 123 | 124 | if strlst_contains_c(deref(args), "-r") { 125 | set_run_after_compile(true); 126 | } 127 | 128 | if strlst_contains_c(deref(args), "-tokens") { 129 | set_print_tokens(true); 130 | } 131 | 132 | if strlst_contains_c(deref(args), "-ast") { 133 | set_print_ast(true); 134 | } 135 | 136 | if strlst_contains_c(deref(args), "-dll") { 137 | set_build_shared_lib(true); 138 | } 139 | 140 | if strlst_contains_c(deref(args), "--syntax-check") { 141 | set_syntax_check_only(true); 142 | set_quiet_mode(true); 143 | } 144 | 145 | if !has_suffix(source_file, str(".axe")) and !has_suffix(source_file, str(".axec")) { 146 | source_file = concat(source_file, str(".axe")); 147 | } 148 | 149 | val is_axec: bool = has_suffix(source_file, str(".axec")); 150 | 151 | if !is_file(source_file) { 152 | println($"Error: File '{source_file}' not found"); 153 | quit(1); 154 | } 155 | 156 | val ok: bool = compile_file(source_file, is_axec, output_filename); 157 | 158 | Arena.destroy(addr(arena)); 159 | 160 | if !ok { 161 | quit(1); 162 | } 163 | 164 | quit(0); 165 | } 166 | -------------------------------------------------------------------------------- /source/compiler/external/curl/include/curl/urlapi.h: -------------------------------------------------------------------------------- 1 | #ifndef CURLINC_URLAPI_H 2 | #define CURLINC_URLAPI_H 3 | /*************************************************************************** 4 | * _ _ ____ _ 5 | * Project ___| | | | _ \| | 6 | * / __| | | | |_) | | 7 | * | (__| |_| | _ <| |___ 8 | * \___|\___/|_| \_\_____| 9 | * 10 | * Copyright (C) Daniel Stenberg, , et al. 11 | * 12 | * This software is licensed as described in the file COPYING, which 13 | * you should have received as part of this distribution. The terms 14 | * are also available at https://curl.se/docs/copyright.html. 15 | * 16 | * You may opt to use, copy, modify, merge, publish, distribute and/or sell 17 | * copies of the Software, and permit persons to whom the Software is 18 | * furnished to do so, under the terms of the COPYING file. 19 | * 20 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY 21 | * KIND, either express or implied. 22 | * 23 | * SPDX-License-Identifier: curl 24 | * 25 | ***************************************************************************/ 26 | 27 | #include "curl.h" 28 | 29 | #ifdef __cplusplus 30 | extern "C" { 31 | #endif 32 | 33 | /* the error codes for the URL API */ 34 | typedef enum { 35 | CURLUE_OK, 36 | CURLUE_BAD_HANDLE, /* 1 */ 37 | CURLUE_BAD_PARTPOINTER, /* 2 */ 38 | CURLUE_MALFORMED_INPUT, /* 3 */ 39 | CURLUE_BAD_PORT_NUMBER, /* 4 */ 40 | CURLUE_UNSUPPORTED_SCHEME, /* 5 */ 41 | CURLUE_URLDECODE, /* 6 */ 42 | CURLUE_OUT_OF_MEMORY, /* 7 */ 43 | CURLUE_USER_NOT_ALLOWED, /* 8 */ 44 | CURLUE_UNKNOWN_PART, /* 9 */ 45 | CURLUE_NO_SCHEME, /* 10 */ 46 | CURLUE_NO_USER, /* 11 */ 47 | CURLUE_NO_PASSWORD, /* 12 */ 48 | CURLUE_NO_OPTIONS, /* 13 */ 49 | CURLUE_NO_HOST, /* 14 */ 50 | CURLUE_NO_PORT, /* 15 */ 51 | CURLUE_NO_QUERY, /* 16 */ 52 | CURLUE_NO_FRAGMENT, /* 17 */ 53 | CURLUE_NO_ZONEID, /* 18 */ 54 | CURLUE_BAD_FILE_URL, /* 19 */ 55 | CURLUE_BAD_FRAGMENT, /* 20 */ 56 | CURLUE_BAD_HOSTNAME, /* 21 */ 57 | CURLUE_BAD_IPV6, /* 22 */ 58 | CURLUE_BAD_LOGIN, /* 23 */ 59 | CURLUE_BAD_PASSWORD, /* 24 */ 60 | CURLUE_BAD_PATH, /* 25 */ 61 | CURLUE_BAD_QUERY, /* 26 */ 62 | CURLUE_BAD_SCHEME, /* 27 */ 63 | CURLUE_BAD_SLASHES, /* 28 */ 64 | CURLUE_BAD_USER, /* 29 */ 65 | CURLUE_LACKS_IDN, /* 30 */ 66 | CURLUE_TOO_LARGE, /* 31 */ 67 | CURLUE_LAST 68 | } CURLUcode; 69 | 70 | typedef enum { 71 | CURLUPART_URL, 72 | CURLUPART_SCHEME, 73 | CURLUPART_USER, 74 | CURLUPART_PASSWORD, 75 | CURLUPART_OPTIONS, 76 | CURLUPART_HOST, 77 | CURLUPART_PORT, 78 | CURLUPART_PATH, 79 | CURLUPART_QUERY, 80 | CURLUPART_FRAGMENT, 81 | CURLUPART_ZONEID /* added in 7.65.0 */ 82 | } CURLUPart; 83 | 84 | #define CURLU_DEFAULT_PORT (1<<0) /* return default port number */ 85 | #define CURLU_NO_DEFAULT_PORT (1<<1) /* act as if no port number was set, 86 | if the port number matches the 87 | default for the scheme */ 88 | #define CURLU_DEFAULT_SCHEME (1<<2) /* return default scheme if 89 | missing */ 90 | #define CURLU_NON_SUPPORT_SCHEME (1<<3) /* allow non-supported scheme */ 91 | #define CURLU_PATH_AS_IS (1<<4) /* leave dot sequences */ 92 | #define CURLU_DISALLOW_USER (1<<5) /* no user+password allowed */ 93 | #define CURLU_URLDECODE (1<<6) /* URL decode on get */ 94 | #define CURLU_URLENCODE (1<<7) /* URL encode on set */ 95 | #define CURLU_APPENDQUERY (1<<8) /* append a form style part */ 96 | #define CURLU_GUESS_SCHEME (1<<9) /* legacy curl-style guessing */ 97 | #define CURLU_NO_AUTHORITY (1<<10) /* Allow empty authority when the 98 | scheme is unknown. */ 99 | #define CURLU_ALLOW_SPACE (1<<11) /* Allow spaces in the URL */ 100 | #define CURLU_PUNYCODE (1<<12) /* get the hostname in punycode */ 101 | #define CURLU_PUNY2IDN (1<<13) /* punycode => IDN conversion */ 102 | #define CURLU_GET_EMPTY (1<<14) /* allow empty queries and fragments 103 | when extracting the URL or the 104 | components */ 105 | #define CURLU_NO_GUESS_SCHEME (1<<15) /* for get, do not accept a guess */ 106 | 107 | typedef struct Curl_URL CURLU; 108 | 109 | /* 110 | * curl_url() creates a new CURLU handle and returns a pointer to it. 111 | * Must be freed with curl_url_cleanup(). 112 | */ 113 | CURL_EXTERN CURLU *curl_url(void); 114 | 115 | /* 116 | * curl_url_cleanup() frees the CURLU handle and related resources used for 117 | * the URL parsing. It will not free strings previously returned with the URL 118 | * API. 119 | */ 120 | CURL_EXTERN void curl_url_cleanup(CURLU *handle); 121 | 122 | /* 123 | * curl_url_dup() duplicates a CURLU handle and returns a new copy. The new 124 | * handle must also be freed with curl_url_cleanup(). 125 | */ 126 | CURL_EXTERN CURLU *curl_url_dup(const CURLU *in); 127 | 128 | /* 129 | * curl_url_get() extracts a specific part of the URL from a CURLU 130 | * handle. Returns error code. The returned pointer MUST be freed with 131 | * curl_free() afterwards. 132 | */ 133 | CURL_EXTERN CURLUcode curl_url_get(const CURLU *handle, CURLUPart what, 134 | char **part, unsigned int flags); 135 | 136 | /* 137 | * curl_url_set() sets a specific part of the URL in a CURLU handle. Returns 138 | * error code. The passed in string will be copied. Passing a NULL instead of 139 | * a part string, clears that part. 140 | */ 141 | CURL_EXTERN CURLUcode curl_url_set(CURLU *handle, CURLUPart what, 142 | const char *part, unsigned int flags); 143 | 144 | /* 145 | * curl_url_strerror() turns a CURLUcode value into the equivalent human 146 | * readable error string. This is useful for printing meaningful error 147 | * messages. 148 | */ 149 | CURL_EXTERN const char *curl_url_strerror(CURLUcode); 150 | 151 | #ifdef __cplusplus 152 | } /* end of extern "C" */ 153 | #endif 154 | 155 | #endif /* CURLINC_URLAPI_H */ 156 | -------------------------------------------------------------------------------- /source/compiler/std/regex.axec: -------------------------------------------------------------------------------- 1 | use std.string ( 2 | string 3 | ); 4 | 5 | use external("pcre.h"); 6 | 7 | /// Simple regex-like support built on substring search. 8 | pub model regex { 9 | pattern: string; 10 | } 11 | 12 | /// Compile a pattern into a regex value. 13 | pub def compile(pattern: string): regex { 14 | return regex{pattern: pattern}; 15 | } 16 | 17 | /// Returns true if the given text contains the pattern as a substring. 18 | pub def is_match(re: regex, text: string): bool { 19 | return match(re.pattern, text); 20 | } 21 | 22 | extern def pcre_compile(pattern: ref char, 23 | options: i32, 24 | errptr: addr ref char, 25 | erroffset: addr i32, 26 | tableptr: ref void): ref pcre; 27 | 28 | extern def pcre_exec(code: ref pcre, 29 | extra: ref void, 30 | subject: ref char, 31 | length: i32, 32 | startoffset: i32, 33 | options: i32, 34 | ovector: ref i32, 35 | ovecsize: i32): i32; 36 | 37 | extern def pcre_free(ptr: ref void); 38 | 39 | /// Returns true if the given text contains pattern as a substring. 40 | def match(pattern: string, text: string): bool { 41 | foreign {pcre}; 42 | 43 | mut result: bool = false; 44 | mut arena: Arena = Arena.create(text.len + pattern.len + 1024); 45 | val error: ref char = nil; 46 | val err_offset: i32 = 0; 47 | mut re: ref pcre = pcre_compile(cast[ref char](pattern.data), 0, addr(error), addr(err_offset), nil); 48 | 49 | if re != nil { 50 | val ovector: ref i32 = Arena.alloc_array(addr(arena), C.sizeof(i32), 30); 51 | val rc: i32 = pcre_exec( 52 | re, nil, cast[ref char](text.data), cast[i32](text.len), 0, 0, ovector, 30 53 | ); 54 | if rc >= 0 { 55 | result = true; 56 | } else { 57 | result = false; 58 | } 59 | pcre_free(cast[ref void](re)); 60 | } else { 61 | result = false; 62 | } 63 | 64 | return result; 65 | } 66 | 67 | /// Convenience helper: returns true if text fully equals pattern. 68 | pub def full_match(pattern: string, text: string): bool { 69 | if pattern.len != text.len { 70 | return false; 71 | } 72 | return match(pattern, text); 73 | } 74 | 75 | test { 76 | // Basic literal matching 77 | val text: string = string.create("hello world"); 78 | assert(match(string.create("hello"), text), "pattern 'hello' should match"); 79 | assert(match(string.create("world"), text), "pattern 'world' should match"); 80 | assert(!match(string.create("axe"), text), "pattern 'axe' should not match"); 81 | 82 | val re: regex = compile(string.create("lo wo")); 83 | assert(is_match(re, text), "compiled regex should match substring"); 84 | 85 | // Character classes 86 | val digits: string = string.create("abc123def"); 87 | assert(match(string.create("[0-9]+"), digits), "should match digit sequence"); 88 | assert(match(string.create("[a-z]+"), digits), "should match letter sequence"); 89 | assert(!match(string.create("^[0-9]+$"), digits), "should not match digits only"); 90 | 91 | // Anchors 92 | val sentence: string = string.create("The quick brown fox"); 93 | assert(match(string.create("^The"), sentence), "should match start anchor"); 94 | assert(match(string.create("fox$"), sentence), "should match end anchor"); 95 | assert(!match(string.create("^fox"), sentence), "should not match 'fox' at start"); 96 | assert(!match(string.create("The$"), sentence), "should not match 'The' at end"); 97 | 98 | // Quantifiers 99 | val repeated: string = string.create("aaaaabbbcc"); 100 | assert(match(string.create("a+"), repeated), "should match one or more 'a'"); 101 | assert(match(string.create("a{5}"), repeated), "should match exactly 5 'a's"); 102 | assert(match(string.create("b{3}"), repeated), "should match exactly 3 'b's"); 103 | assert(!match(string.create("a{6}"), repeated), "should not match 6 consecutive 'a's"); 104 | 105 | // Alternation 106 | val choice: string = string.create("I like cats"); 107 | assert(match(string.create("cat|dog"), choice), "should match 'cat' alternative"); 108 | assert(match(string.create("dog|cat"), choice), "should match 'cat' alternative (reversed)"); 109 | val choice2: string = string.create("I like dogs"); 110 | assert(match(string.create("cat|dog"), choice2), "should match 'dog' alternative"); 111 | 112 | // Wildcards 113 | val wildcard: string = string.create("a1b2c3"); 114 | assert(match(string.create("a.b"), wildcard), "should match with wildcard dot"); 115 | assert(match(string.create(".*"), wildcard), "should match entire string with .*"); 116 | 117 | // Word boundaries 118 | val boundary: string = string.create("hello world"); 119 | assert(match(string.create("\\bhello\\b"), boundary), "should match word 'hello' with boundaries"); 120 | assert(match(string.create("\\bworld\\b"), boundary), "should match word 'world' with boundaries"); 121 | assert(!match(string.create("\\bell\\b"), boundary), "should not match 'ell' as word"); 122 | 123 | // Email-like pattern (simple) 124 | val email: string = string.create("user@example.com"); 125 | assert(match(string.create("[a-z]+@[a-z]+\\.[a-z]+"), email), "should match email pattern"); 126 | val not_email: string = string.create("not an email"); 127 | assert(!match(string.create("[a-z]+@[a-z]+\\.[a-z]+"), not_email), "should not match non-email"); 128 | 129 | // Case sensitivity 130 | val mixed: string = string.create("Hello World"); 131 | assert(match(string.create("Hello"), mixed), "should match exact case"); 132 | assert(!match(string.create("hello"), mixed), "should not match different case"); 133 | assert(match(string.create("[Hh]ello"), mixed), "should match with character class"); 134 | 135 | // Greedy vs non-greedy (testing greedy behavior) 136 | val greedy_test: string = string.create("content"); 137 | assert(match(string.create("<.*>"), greedy_test), "should match greedily"); 138 | assert(match(string.create("<.*?>"), greedy_test), "should match non-greedily"); 139 | 140 | // Special characters escaped 141 | val special: string = string.create("price: $100"); 142 | assert(match(string.create("\\$100"), special), "should match escaped dollar sign"); 143 | assert(match(string.create("\\$[0-9]+"), special), "should match price pattern"); 144 | 145 | // Empty pattern edge case 146 | val empty_text: string = string.create(""); 147 | assert(match(string.create(".*"), empty_text), "empty string should match .*"); 148 | assert(!match(string.create(".+"), empty_text), "empty string should not match .+"); 149 | 150 | // Unicode/UTF-8 (if PCRE built with UTF-8 support) 151 | val unicode: string = string.create("café"); 152 | assert(match(string.create("café"), unicode), "should match UTF-8 string"); 153 | assert(match(string.create("caf."), unicode), "should match UTF-8 with wildcard"); 154 | } -------------------------------------------------------------------------------- /source/compiler/external/pcre/include/pcre_stringpiece.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2005, Google Inc. 2 | // All rights reserved. 3 | // 4 | // Redistribution and use in source and binary forms, with or without 5 | // modification, are permitted provided that the following conditions are 6 | // met: 7 | // 8 | // * Redistributions of source code must retain the above copyright 9 | // notice, this list of conditions and the following disclaimer. 10 | // * Redistributions in binary form must reproduce the above 11 | // copyright notice, this list of conditions and the following disclaimer 12 | // in the documentation and/or other materials provided with the 13 | // distribution. 14 | // * Neither the name of Google Inc. nor the names of its 15 | // contributors may be used to endorse or promote products derived from 16 | // this software without specific prior written permission. 17 | // 18 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | // 30 | // Author: Sanjay Ghemawat 31 | // 32 | // A string like object that points into another piece of memory. 33 | // Useful for providing an interface that allows clients to easily 34 | // pass in either a "const char*" or a "string". 35 | // 36 | // Arghh! I wish C++ literals were automatically of type "string". 37 | 38 | #ifndef _PCRE_STRINGPIECE_H 39 | #define _PCRE_STRINGPIECE_H 40 | 41 | #include 42 | #include 43 | #include // for ostream forward-declaration 44 | 45 | #if 0 46 | #define HAVE_TYPE_TRAITS 47 | #include 48 | #elif 0 49 | #define HAVE_TYPE_TRAITS 50 | #include 51 | #endif 52 | 53 | #include 54 | 55 | namespace pcrecpp { 56 | 57 | using std::memcmp; 58 | using std::strlen; 59 | using std::string; 60 | 61 | class PCRECPP_EXP_DEFN StringPiece { 62 | private: 63 | const char* ptr_; 64 | int length_; 65 | 66 | public: 67 | // We provide non-explicit singleton constructors so users can pass 68 | // in a "const char*" or a "string" wherever a "StringPiece" is 69 | // expected. 70 | StringPiece() 71 | : ptr_(NULL), length_(0) { } 72 | StringPiece(const char* str) 73 | : ptr_(str), length_(static_cast(strlen(ptr_))) { } 74 | StringPiece(const unsigned char* str) 75 | : ptr_(reinterpret_cast(str)), 76 | length_(static_cast(strlen(ptr_))) { } 77 | StringPiece(const string& str) 78 | : ptr_(str.data()), length_(static_cast(str.size())) { } 79 | StringPiece(const char* offset, int len) 80 | : ptr_(offset), length_(len) { } 81 | 82 | // data() may return a pointer to a buffer with embedded NULs, and the 83 | // returned buffer may or may not be null terminated. Therefore it is 84 | // typically a mistake to pass data() to a routine that expects a NUL 85 | // terminated string. Use "as_string().c_str()" if you really need to do 86 | // this. Or better yet, change your routine so it does not rely on NUL 87 | // termination. 88 | const char* data() const { return ptr_; } 89 | int size() const { return length_; } 90 | bool empty() const { return length_ == 0; } 91 | 92 | void clear() { ptr_ = NULL; length_ = 0; } 93 | void set(const char* buffer, int len) { ptr_ = buffer; length_ = len; } 94 | void set(const char* str) { 95 | ptr_ = str; 96 | length_ = static_cast(strlen(str)); 97 | } 98 | void set(const void* buffer, int len) { 99 | ptr_ = reinterpret_cast(buffer); 100 | length_ = len; 101 | } 102 | 103 | char operator[](int i) const { return ptr_[i]; } 104 | 105 | void remove_prefix(int n) { 106 | ptr_ += n; 107 | length_ -= n; 108 | } 109 | 110 | void remove_suffix(int n) { 111 | length_ -= n; 112 | } 113 | 114 | bool operator==(const StringPiece& x) const { 115 | return ((length_ == x.length_) && 116 | (memcmp(ptr_, x.ptr_, length_) == 0)); 117 | } 118 | bool operator!=(const StringPiece& x) const { 119 | return !(*this == x); 120 | } 121 | 122 | #define STRINGPIECE_BINARY_PREDICATE(cmp,auxcmp) \ 123 | bool operator cmp (const StringPiece& x) const { \ 124 | int r = memcmp(ptr_, x.ptr_, length_ < x.length_ ? length_ : x.length_); \ 125 | return ((r auxcmp 0) || ((r == 0) && (length_ cmp x.length_))); \ 126 | } 127 | STRINGPIECE_BINARY_PREDICATE(<, <); 128 | STRINGPIECE_BINARY_PREDICATE(<=, <); 129 | STRINGPIECE_BINARY_PREDICATE(>=, >); 130 | STRINGPIECE_BINARY_PREDICATE(>, >); 131 | #undef STRINGPIECE_BINARY_PREDICATE 132 | 133 | int compare(const StringPiece& x) const { 134 | int r = memcmp(ptr_, x.ptr_, length_ < x.length_ ? length_ : x.length_); 135 | if (r == 0) { 136 | if (length_ < x.length_) r = -1; 137 | else if (length_ > x.length_) r = +1; 138 | } 139 | return r; 140 | } 141 | 142 | string as_string() const { 143 | return string(data(), size()); 144 | } 145 | 146 | void CopyToString(string* target) const { 147 | target->assign(ptr_, length_); 148 | } 149 | 150 | // Does "this" start with "x" 151 | bool starts_with(const StringPiece& x) const { 152 | return ((length_ >= x.length_) && (memcmp(ptr_, x.ptr_, x.length_) == 0)); 153 | } 154 | }; 155 | 156 | } // namespace pcrecpp 157 | 158 | // ------------------------------------------------------------------ 159 | // Functions used to create STL containers that use StringPiece 160 | // Remember that a StringPiece's lifetime had better be less than 161 | // that of the underlying string or char*. If it is not, then you 162 | // cannot safely store a StringPiece into an STL container 163 | // ------------------------------------------------------------------ 164 | 165 | #ifdef HAVE_TYPE_TRAITS 166 | // This makes vector really fast for some STL implementations 167 | template<> struct __type_traits { 168 | typedef __true_type has_trivial_default_constructor; 169 | typedef __true_type has_trivial_copy_constructor; 170 | typedef __true_type has_trivial_assignment_operator; 171 | typedef __true_type has_trivial_destructor; 172 | typedef __true_type is_POD_type; 173 | }; 174 | #endif 175 | 176 | // allow StringPiece to be logged 177 | PCRECPP_EXP_DECL std::ostream& operator<<(std::ostream& o, 178 | const pcrecpp::StringPiece& piece); 179 | 180 | #endif /* _PCRE_STRINGPIECE_H */ 181 | -------------------------------------------------------------------------------- /source/compiler/external/pcre/include/pcrecpparg.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2005, Google Inc. 2 | // All rights reserved. 3 | // 4 | // Redistribution and use in source and binary forms, with or without 5 | // modification, are permitted provided that the following conditions are 6 | // met: 7 | // 8 | // * Redistributions of source code must retain the above copyright 9 | // notice, this list of conditions and the following disclaimer. 10 | // * Redistributions in binary form must reproduce the above 11 | // copyright notice, this list of conditions and the following disclaimer 12 | // in the documentation and/or other materials provided with the 13 | // distribution. 14 | // * Neither the name of Google Inc. nor the names of its 15 | // contributors may be used to endorse or promote products derived from 16 | // this software without specific prior written permission. 17 | // 18 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | // 30 | // Author: Sanjay Ghemawat 31 | 32 | #ifndef _PCRECPPARG_H 33 | #define _PCRECPPARG_H 34 | 35 | #include // for NULL 36 | #include 37 | 38 | #include 39 | 40 | namespace pcrecpp { 41 | 42 | class StringPiece; 43 | 44 | // Hex/Octal/Binary? 45 | 46 | // Special class for parsing into objects that define a ParseFrom() method 47 | template 48 | class _RE_MatchObject { 49 | public: 50 | static inline bool Parse(const char* str, int n, void* dest) { 51 | if (dest == NULL) return true; 52 | T* object = reinterpret_cast(dest); 53 | return object->ParseFrom(str, n); 54 | } 55 | }; 56 | 57 | class PCRECPP_EXP_DEFN Arg { 58 | public: 59 | // Empty constructor so we can declare arrays of Arg 60 | Arg(); 61 | 62 | // Constructor specially designed for NULL arguments 63 | Arg(void*); 64 | 65 | typedef bool (*Parser)(const char* str, int n, void* dest); 66 | 67 | // Type-specific parsers 68 | #define PCRE_MAKE_PARSER(type,name) \ 69 | Arg(type* p) : arg_(p), parser_(name) { } \ 70 | Arg(type* p, Parser parser) : arg_(p), parser_(parser) { } 71 | 72 | 73 | PCRE_MAKE_PARSER(char, parse_char); 74 | PCRE_MAKE_PARSER(unsigned char, parse_uchar); 75 | PCRE_MAKE_PARSER(short, parse_short); 76 | PCRE_MAKE_PARSER(unsigned short, parse_ushort); 77 | PCRE_MAKE_PARSER(int, parse_int); 78 | PCRE_MAKE_PARSER(unsigned int, parse_uint); 79 | PCRE_MAKE_PARSER(long, parse_long); 80 | PCRE_MAKE_PARSER(unsigned long, parse_ulong); 81 | #if 1 82 | PCRE_MAKE_PARSER(long long, parse_longlong); 83 | #endif 84 | #if 1 85 | PCRE_MAKE_PARSER(unsigned long long, parse_ulonglong); 86 | #endif 87 | PCRE_MAKE_PARSER(float, parse_float); 88 | PCRE_MAKE_PARSER(double, parse_double); 89 | PCRE_MAKE_PARSER(std::string, parse_string); 90 | PCRE_MAKE_PARSER(StringPiece, parse_stringpiece); 91 | 92 | #undef PCRE_MAKE_PARSER 93 | 94 | // Generic constructor 95 | template Arg(T*, Parser parser); 96 | // Generic constructor template 97 | template Arg(T* p) 98 | : arg_(p), parser_(_RE_MatchObject::Parse) { 99 | } 100 | 101 | // Parse the data 102 | bool Parse(const char* str, int n) const; 103 | 104 | private: 105 | void* arg_; 106 | Parser parser_; 107 | 108 | static bool parse_null (const char* str, int n, void* dest); 109 | static bool parse_char (const char* str, int n, void* dest); 110 | static bool parse_uchar (const char* str, int n, void* dest); 111 | static bool parse_float (const char* str, int n, void* dest); 112 | static bool parse_double (const char* str, int n, void* dest); 113 | static bool parse_string (const char* str, int n, void* dest); 114 | static bool parse_stringpiece (const char* str, int n, void* dest); 115 | 116 | #define PCRE_DECLARE_INTEGER_PARSER(name) \ 117 | private: \ 118 | static bool parse_ ## name(const char* str, int n, void* dest); \ 119 | static bool parse_ ## name ## _radix( \ 120 | const char* str, int n, void* dest, int radix); \ 121 | public: \ 122 | static bool parse_ ## name ## _hex(const char* str, int n, void* dest); \ 123 | static bool parse_ ## name ## _octal(const char* str, int n, void* dest); \ 124 | static bool parse_ ## name ## _cradix(const char* str, int n, void* dest) 125 | 126 | PCRE_DECLARE_INTEGER_PARSER(short); 127 | PCRE_DECLARE_INTEGER_PARSER(ushort); 128 | PCRE_DECLARE_INTEGER_PARSER(int); 129 | PCRE_DECLARE_INTEGER_PARSER(uint); 130 | PCRE_DECLARE_INTEGER_PARSER(long); 131 | PCRE_DECLARE_INTEGER_PARSER(ulong); 132 | PCRE_DECLARE_INTEGER_PARSER(longlong); 133 | PCRE_DECLARE_INTEGER_PARSER(ulonglong); 134 | 135 | #undef PCRE_DECLARE_INTEGER_PARSER 136 | }; 137 | 138 | inline Arg::Arg() : arg_(NULL), parser_(parse_null) { } 139 | inline Arg::Arg(void* p) : arg_(p), parser_(parse_null) { } 140 | 141 | inline bool Arg::Parse(const char* str, int n) const { 142 | return (*parser_)(str, n, arg_); 143 | } 144 | 145 | // This part of the parser, appropriate only for ints, deals with bases 146 | #define MAKE_INTEGER_PARSER(type, name) \ 147 | inline Arg Hex(type* ptr) { \ 148 | return Arg(ptr, Arg::parse_ ## name ## _hex); } \ 149 | inline Arg Octal(type* ptr) { \ 150 | return Arg(ptr, Arg::parse_ ## name ## _octal); } \ 151 | inline Arg CRadix(type* ptr) { \ 152 | return Arg(ptr, Arg::parse_ ## name ## _cradix); } 153 | 154 | MAKE_INTEGER_PARSER(short, short) /* */ 155 | MAKE_INTEGER_PARSER(unsigned short, ushort) /* */ 156 | MAKE_INTEGER_PARSER(int, int) /* Don't use semicolons */ 157 | MAKE_INTEGER_PARSER(unsigned int, uint) /* after these statement */ 158 | MAKE_INTEGER_PARSER(long, long) /* because they can cause */ 159 | MAKE_INTEGER_PARSER(unsigned long, ulong) /* compiler warnings if */ 160 | #if 1 /* the checking level is */ 161 | MAKE_INTEGER_PARSER(long long, longlong) /* turned up high enough. */ 162 | #endif /* */ 163 | #if 1 /* */ 164 | MAKE_INTEGER_PARSER(unsigned long long, ulonglong) /* */ 165 | #endif 166 | 167 | #undef PCRE_IS_SET 168 | #undef PCRE_SET_OR_CLEAR 169 | #undef MAKE_INTEGER_PARSER 170 | 171 | } // namespace pcrecpp 172 | 173 | 174 | #endif /* _PCRECPPARG_H */ 175 | -------------------------------------------------------------------------------- /source/compiler/structs.axe: -------------------------------------------------------------------------------- 1 | /// Author: Navid Momtahen (C) 2025 2 | /// License: GPL-3.0 3 | /// 4 | /// Structures used in the Axe compiler 5 | 6 | use std.string; 7 | use std.io; 8 | use std.maps; 9 | 10 | use lexer (Token); 11 | 12 | /// Macro definition modelure 13 | pub model MacroDef { 14 | params: ref list(string); 15 | body: ref list(Token); 16 | } 17 | 18 | /// Parser context - holds state during parsing 19 | pub model ParserContext { 20 | tokens: ref list(Token); 21 | pos: i32; 22 | is_axec: bool; 23 | check_entry_point: bool; 24 | current_module: string; 25 | current_scope: Scope; 26 | filename: string; 27 | in_test_block: bool; 28 | } 29 | 30 | /// Scope tracking for variable declarations 31 | pub model Scope { 32 | variables: StringStringMap; 33 | parent: ref Scope; 34 | } 35 | 36 | /// AST Node - all node types combined with a union 37 | pub model ASTNode { 38 | node_type: string; 39 | children: ref list(ASTNode); 40 | 41 | // Source line number for error reporting 42 | line: i32; 43 | 44 | // Source file name for error reporting 45 | source_file: string; 46 | 47 | // Union of all possible node-specific data 48 | // This allows each node to store only the data relevant to its type 49 | data: union { 50 | overload_node: model { 51 | name: string; 52 | param_name: string; 53 | call_expr: string; 54 | type_names: ref list(string); 55 | target_functions: ref list(string); 56 | }; 57 | 58 | declaration: model { 59 | name: string; 60 | is_mutable: bool; 61 | initializer: string; 62 | type_name: string; 63 | ref_depth: i32; 64 | }; 65 | 66 | array_decl: model { 67 | name: string; 68 | is_mutable: bool; 69 | element_type: string; 70 | size: string; 71 | size2: string; 72 | initializer: list(string); 73 | }; 74 | 75 | array_access: model { 76 | array_name: string; 77 | index: string; 78 | index2: string; 79 | }; 80 | 81 | array_assign: model { 82 | array_name: string; 83 | index: string; 84 | index2: string; 85 | value: string; 86 | }; 87 | 88 | array_literal: model { 89 | element_type: string; 90 | elements: list(string); 91 | }; 92 | 93 | function: model { 94 | name: string; 95 | params: list(string); 96 | return_type: string; 97 | is_public: bool; 98 | tags: ref list(string); 99 | type_params: ref list(string); 100 | is_generic: bool; 101 | when_branch_types: ref list(string); 102 | when_branch_counts: ref list(i32); 103 | when_branch_starts: ref list(i32); 104 | }; 105 | 106 | macro_node: model { 107 | name: string; 108 | params: list(string); 109 | param_types: list(string); 110 | body_tokens: list(Token); 111 | }; 112 | 113 | assert_node: model { 114 | condition: string; 115 | message: string; 116 | }; 117 | 118 | if_node: model { 119 | condition: string; 120 | elif_branches: list(ASTNode); 121 | else_body: list(ASTNode); 122 | }; 123 | 124 | println: model { 125 | messages: ref list(string); 126 | is_expressions: ref list(bool); 127 | }; 128 | 129 | print: model { 130 | messages: ref list(string); 131 | is_expressions: ref list(bool); 132 | }; 133 | 134 | assignment: model { 135 | variable: string; 136 | expression: string; 137 | operator: string; // "=", "+=", "-=" 138 | }; 139 | 140 | func_call: model { 141 | function_name: string; 142 | args: ref list(string); 143 | }; 144 | 145 | interpolated_str: model { 146 | parts: list(string); 147 | expressions: list(string); 148 | }; 149 | 150 | for_loop: model { 151 | initialization: string; 152 | condition: string; 153 | increment: string; 154 | is_mutable: bool; 155 | var_name: string; 156 | var_type: string; 157 | init_value: string; 158 | is_parallel: bool; 159 | reduction_clauses: list(string); 160 | }; 161 | 162 | for_in: model { 163 | var_name: string; 164 | array_name: string; 165 | array_size: string; 166 | }; 167 | 168 | return_node: model { 169 | expression: string; 170 | }; 171 | 172 | raw_c: model { 173 | code: string; 174 | }; 175 | 176 | use_node: model { 177 | module_name: string; 178 | imports: ref list(string); 179 | import_all: bool; 180 | }; 181 | 182 | model_node: model { 183 | name: string; 184 | is_public: bool; 185 | field_names: list(string); 186 | field_types: list(string); 187 | 188 | // Union field metadata (for fields declared as `field: union { ... }`). 189 | // For each union member, we store: 190 | // - union_member_parent: the parent union field name 191 | // - union_member_names/types: the member name and type 192 | union_member_parents: list(string); 193 | union_member_names: list(string); 194 | union_member_types: list(string); 195 | }; 196 | 197 | enum_node: model { 198 | name: string; 199 | values: list(string); 200 | }; 201 | 202 | model_instantiation: model { 203 | model_name: string; 204 | variable_name: string; 205 | is_mutable: bool; 206 | field_names: list(string); 207 | field_values: list(string); 208 | }; 209 | 210 | member_access: model { 211 | object_name: string; 212 | member_name: string; 213 | value: string; 214 | }; 215 | 216 | external_import: model { 217 | header_file: string; 218 | }; 219 | 220 | opaque_node: model { 221 | type_names: list(string); 222 | }; 223 | 224 | foreign_node: model { 225 | type_names: list(string); 226 | }; 227 | 228 | extern_node: model { 229 | function_name: string; 230 | params: list(string); 231 | return_type: string; 232 | }; 233 | 234 | unsafe_node: model { 235 | body: ref list(ASTNode); 236 | }; 237 | 238 | switch_node: model { 239 | expression: string; 240 | }; 241 | 242 | case_node: model { 243 | value: string; 244 | is_default: bool; 245 | }; 246 | 247 | inc_dec: model { 248 | variable: string; 249 | is_increment: bool; 250 | }; 251 | 252 | member_inc_dec: model { 253 | object_name: string; 254 | member_name: string; 255 | is_increment: bool; 256 | }; 257 | 258 | platform_node: model { 259 | platform_name: string; 260 | }; 261 | 262 | parallel_for: model { 263 | initialization: string; 264 | condition: string; 265 | increment: string; 266 | reduction_clauses: ref list(string); 267 | }; 268 | 269 | parallel_local: model { 270 | private_vars: ref list(string); 271 | private_types: ref list(string); 272 | is_mutable: ref list(bool); 273 | }; 274 | 275 | when_branch: model { 276 | type_params: ref list(string); // e.g., ["T2", "T"] 277 | concrete_types: ref list(string); // e.g., ["i32", "IntList"] 278 | }; 279 | 280 | /// Simple nodes with no additional data (Loop, Break, Continue, Test, Program, Parallel, Single) 281 | /// These just use node_type and children 282 | empty: i32; 283 | }; 284 | } 285 | 286 | test { 287 | 288 | } 289 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Axe 2 | 3 | Axe is a compiled programming language with a focus on type safety, ease of concurrency, and performance. 4 | 5 | It provides a clean syntax for systems programming with modern and parallel language features. 6 | 7 | ```axe 8 | use std.io; 9 | use std.string; 10 | 11 | model Person { 12 | name: string; 13 | age: i32; 14 | } 15 | 16 | def main() { 17 | parallel for mut i = 0 to 10 { 18 | val person = Person{name: "Alice", age: i}; 19 | println person.age; 20 | } 21 | } 22 | ``` 23 | 24 | ## Getting Started 25 | 26 | - [Latest release of the Axe compiler](https://github.com/axelang/axe/releases) 27 | - [Documentation on the language](https://axe-docs.pages.dev) 28 | - [The Visual Studio Code extension for Axe](https://marketplace.visualstudio.com/items?itemName=NavidM.axe-programming-language) 29 | - [The LSP, namely Axels](https://github.com/axelang/axels/releases/), installation involves just downloading it and adding it to PATH. 30 | - [Saw, a build tool and package manager for Axe](https://github.com/axelang/saw/releases) 31 | 32 | ## Features 33 | 34 | - **Type Safety**: Safe by default 35 | - **Parallelism at the core of the language** Supports parallelism at the language level, making it easy to write programs that can take advantage of multiple CPU cores. 36 | - **Clean Syntax**: Intuitive syntax inspired by modern languages 37 | - **Standard Library**: Built-in support for numerous data structures and utilities 38 | - **Cross-platform**: Works on Windows, macOS, and Linux 39 | - **Fast Compilation**: Optimized build system for quick iteration 40 | 41 | ### Language Features 42 | 43 | - Functions and variables, immutability by default 44 | - Control flow (if/else, for loops, `loop` construct) 45 | - Pointers and memory management with high level abstractions 46 | - Parallel processing support at the core of the language 47 | - Built-in println for debugging 48 | 49 | ## Installation 50 | 51 | ### Prerequisite 52 | 53 | [Clang compiler](https://clang.llvm.org/) 54 | 55 | ### Building from Source 56 | 57 | Without already having an `axe` binary, clone https://github.com/axelang/axe-bootstrap.git to get axe latest on POSIX systems. 58 | 59 | Bootstrapping process: 60 | 61 | ```bash 62 | git clone https://github.com/axelang/axe-bootstrap.git 63 | cd axe-bootstrap 64 | chmod +x install.sh 65 | ./install.sh 66 | ``` 67 | 68 | If you already have an axe binary (Windows users can download the .zip from GitHub releases), the build process is simply: 69 | 70 | ```bash 71 | git clone https://github.com/axelang/axe.git 72 | cd axe/source/compiler 73 | axe axc -o axe --release 74 | ``` 75 | 76 | Or use `saw build --release` with the saw build tool. 77 | 78 | This will create the `axe` executable. 79 | 80 | ## Usage 81 | 82 | ### Compiling Axe Programs 83 | 84 | ```bash 85 | # Compile and run a program 86 | ./axe hello.axe -r 87 | 88 | # Compile to executable 89 | ./axe hello.axe 90 | 91 | # Compile for release (optimized) 92 | ./axe hello.axe --release -r 93 | 94 | # Compile to shared library 95 | ./axe mylib.axe -dll 96 | ``` 97 | 98 | ## Language Syntax 99 | 100 | ### Hello World 101 | 102 | ``` 103 | use std.string; 104 | 105 | def greet(name: string): void { 106 | println $"Hello, {name}"; 107 | } 108 | 109 | def main() { 110 | greet(str("Axe")); 111 | } 112 | ``` 113 | 114 | ### Tagged Unions 115 | 116 | Axe supports tagged unions, allowing a value to take one of several typed forms. 117 | Each variant has its own fields, and the active variant is determined by the tag: 118 | 119 | ```axe 120 | model Expr { 121 | tag: string; 122 | 123 | data: union { 124 | literal: model { value: i32 }; 125 | variable: model { name: string }; 126 | binary: model { op: string; left: Expr; right: Expr }; 127 | }; 128 | } 129 | 130 | def main() { 131 | val x = Expr{ 132 | tag: "literal", 133 | data: literal{ value: 42 } 134 | }; 135 | 136 | println x.data.literal.value; // 42 137 | } 138 | ``` 139 | 140 | Tagged unions provide a safe and expressive way to model AST nodes, protocol messages, and other variant-based structures. 141 | 142 | ### Generics (new in v0.0.6) 143 | 144 | Generics in Axe allow writing of functions and models that operate on different types while maintaining type safety. You can specify type parameters using square brackets `[T]`, and use type-specific logic with `when` clauses. 145 | 146 | ``` 147 | use std.io; 148 | use std.string; 149 | 150 | model SomeModel { 151 | pub def some_function[T](arg: T): T { 152 | when T is i32 { 153 | return arg + 1; 154 | } 155 | when T is f32 { 156 | return arg * 2.0; 157 | } 158 | when T is string { 159 | return concat_c(arg, "!\n"); 160 | } 161 | } 162 | } 163 | 164 | def main() { 165 | println(SomeModel.some_function[i32](5)); 166 | println(SomeModel.some_function[f32](5.0)); 167 | println(SomeModel.some_function[string](str("Hello"))); 168 | println(SomeModel.some_function(3.0)); 169 | } 170 | ``` 171 | 172 | ### Game of Life 173 | 174 | ``` 175 | use std.io; 176 | 177 | /// Convert 2D coordinate (x, y) into 1D index 178 | def idx(x: i32, y: i32, width: i32): i32 { 179 | return y * width + x; 180 | } 181 | 182 | /// Print the grid (1-D list) 183 | def print_grid(grid: ref list(i32), width: i32, height: i32) { 184 | for mut y = 0; y < height; y++ { 185 | for mut x = 0; x < width; x++ { 186 | if grid.data[idx(x, y, width)] == 1 { 187 | print "■"; 188 | } else { 189 | print "□"; 190 | } 191 | } 192 | println ""; 193 | } 194 | } 195 | 196 | /// Count live neighbors around (x, y) 197 | def count_neighbors(grid: ref list(i32), x: i32, y: i32, width: i32, height: i32): i32 { 198 | mut count: i32 = 0; 199 | 200 | for mut dy = -1; dy <= 1; dy++ { 201 | for mut dx = -1; dx <= 1; dx++ { 202 | if dx == 0 and dy == 0 { 203 | continue; 204 | } 205 | 206 | val nx = x + dx; 207 | val ny = y + dy; 208 | 209 | if nx >= 0 and nx < width and ny >= 0 and ny < height { 210 | if grid.data[idx(nx, ny, width)] == 1 { 211 | count++; 212 | } 213 | } 214 | } 215 | } 216 | 217 | return count; 218 | } 219 | 220 | /// Compute next generation 221 | def next_generation(grid: ref list(i32), new_grid: ref list(i32), width: i32, height: i32) { 222 | for mut y = 0; y < height; y++ { 223 | for mut x = 0; x < width; x++ { 224 | 225 | val i = idx(x, y, width); 226 | val neighbors = count_neighbors(grid, x, y, width, height); 227 | 228 | if grid.data[i] == 1 { 229 | if neighbors == 2 or neighbors == 3 { 230 | new_grid.data[i] = 1; 231 | } else { 232 | new_grid.data[i] = 0; 233 | } 234 | } else { 235 | if neighbors == 3 { 236 | new_grid.data[i] = 1; 237 | } else { 238 | new_grid.data[i] = 0; 239 | } 240 | } 241 | } 242 | } 243 | } 244 | 245 | /// Copy new_grid back into grid 246 | def copy_grid(src: ref list(i32), dst: ref list(i32), size: i32) { 247 | for mut i = 0; i < size; i++ { 248 | dst.data[i] = src.data[i]; 249 | } 250 | } 251 | 252 | def main() { 253 | val width: i32 = 20; 254 | val height: i32 = 20; 255 | val size: i32 = width * height; 256 | 257 | mut grid: list(i32); 258 | mut new_grid: list(i32); 259 | 260 | for mut i = 0; i < size; i++ { 261 | append(grid, 0); 262 | append(new_grid, 0); 263 | } 264 | 265 | grid.data[idx(2,1,width)] = 1; 266 | grid.data[idx(3,2,width)] = 1; 267 | grid.data[idx(1,3,width)] = 1; 268 | grid.data[idx(2,3,width)] = 1; 269 | grid.data[idx(3,3,width)] = 1; 270 | 271 | println "Conway's Game of Life\n"; 272 | 273 | for mut gen = 0; gen < 20; gen++ { 274 | print "Generation "; 275 | println gen; 276 | println ""; 277 | 278 | print_grid(addr(grid), width, height); 279 | 280 | next_generation(addr(grid), addr(new_grid), width, height); 281 | copy_grid(addr(new_grid), addr(grid), size); 282 | 283 | println "\n---\n"; 284 | } 285 | } 286 | ``` 287 | 288 | ## Roadmap 289 | 290 | - [x] Control flow constructs, functions, variables, fundamentals... 291 | - [x] Immutability by default 292 | - [x] Parallel for 293 | - [x] Union types 294 | - [x] Pure `parallel { ... }` blocks 295 | - [x] Syntax (`single { ... }`) for isolating single threaded behaviours in parallel contexts 296 | - [x] Map and reduce clauses 297 | - [x] Smart type inference based on RHS of exprs. 298 | -------------------------------------------------------------------------------- /source/compiler/std/math.axec: -------------------------------------------------------------------------------- 1 | val PI: f64 = 3.141592653589793; 2 | val HALF_PI: f64 = PI / 2.0; 3 | val QUARTER_PI: f64 = PI / 4.0; 4 | val TWO_PI: f64 = PI * 2.0; 5 | val E: f64 = 2.718281828459045; 6 | 7 | /// Clamp integer 8 | pub def clamp(value: i32, min: i32, max: i32): i32 { 9 | if value < min { return min; } 10 | elif value > max { return max; } 11 | else { return value; } 12 | } 13 | 14 | /// Clamp float 15 | pub def clamp_float(value: f64, min: f64, max: f64): f64 { 16 | if value < min { return min; } 17 | elif value > max { return max; } 18 | else { return value; } 19 | } 20 | 21 | /// Absolute value 22 | pub def absolute(value: f64): f64 { 23 | if value < 0.0 { return -value; } else { return value; } 24 | } 25 | 26 | /// Approximately equal 27 | pub def approx_equal(a: f64, b: f64, eps: f64): bool { 28 | return absolute(a - b) <= eps; 29 | } 30 | 31 | /// Minimum 32 | pub def minimum(a: f64, b: f64): f64 { if a < b { return a; } else { return b; } } 33 | 34 | /// Maximum 35 | pub def maximum(a: f64, b: f64): f64 { if a > b { return a; } else { return b; } } 36 | 37 | /// Converts an integer to a float. 38 | pub def int_to_float(x: i32): f64 { 39 | return x + 0.0; 40 | } 41 | 42 | /// Floor of the number. 43 | pub def floor(x: f64): f64 { 44 | val xi: i32 = x; 45 | if x < 0.0 and (x - xi) != 0.0 { 46 | return (xi - 1); 47 | } else { 48 | return xi; 49 | } 50 | } 51 | 52 | /// Ceiling of the number. 53 | pub def ceil(x: f64): f64 { 54 | val xi: i32 = x; 55 | val xf: f64 = xi; 56 | if x > 0.0 and (x - xf) != 0.0 { 57 | val next: i32 = xi + 1; 58 | return next; 59 | } else { 60 | return xf; 61 | } 62 | } 63 | 64 | /// Round to the nearest float 65 | pub def round(x: f64): f64 { 66 | if x < 0.0 { 67 | return ceil(x - 0.5); 68 | } else { 69 | return floor(x + 0.5); 70 | } 71 | } 72 | 73 | /// Float modulus. 74 | pub def mod_float(a: f64, b: f64): f64 { 75 | return a - b * floor(a / b); 76 | } 77 | 78 | /// Reduce angle to [0, 2PI] 79 | pub def reduce_angle(x: f64): f64 { 80 | return mod_float(x, TWO_PI); 81 | } 82 | 83 | /// Square root (Newton) 84 | pub def sqrt(value: f64): f64 { 85 | if value <= 0.0 { return 0.0; } 86 | if value < 0.0000001 { return 0.00001; } 87 | 88 | mut x: f64 = 0.0; 89 | 90 | if value >= 1.0 { 91 | x = value * 0.5; 92 | } else { 93 | x = 1.0; 94 | } 95 | 96 | for mut i = 0; i < 50; i++ { 97 | val last: f64 = x; 98 | x = 0.5 * (x + value / x); 99 | if approx_equal(last, x, 0.0000000000001) { break; } 100 | } 101 | return x; 102 | } 103 | 104 | /// Integer exponent (exponentiation by squaring) 105 | pub def pow(base: f64, exp: i32): f64 { 106 | mut result: f64 = 1.0; 107 | mut b: f64 = base; 108 | mut e: i32 = exp; 109 | 110 | if e < 0 { 111 | b = 1.0 / b; 112 | e = -e; 113 | } 114 | 115 | loop { 116 | if e == 0 { break; } 117 | 118 | if e - (e / 2) * 2 == 1 { 119 | result = result * b; 120 | } 121 | 122 | b = b * b; 123 | e = e / 2; 124 | } 125 | 126 | return result; 127 | } 128 | 129 | /// Exponential series 130 | pub def exp(x: f64): f64 { 131 | if x < 0.0 { 132 | return 1.0 / exp(cast[f64](-x)); 133 | } 134 | 135 | mut n: i32 = 0; 136 | loop { 137 | if x > 1.0 { 138 | x = x * 0.5; 139 | n = n + 1; 140 | } else { 141 | break; 142 | } 143 | } 144 | 145 | mut sum: f64 = 1.0; 146 | mut term: f64 = 1.0; 147 | for mut k = 1; k < 25; k++ { 148 | term = term * x / k; 149 | sum = sum + term; 150 | } 151 | 152 | for mut i = 0; i < n; i++ { 153 | sum = sum * sum; 154 | } 155 | return sum; 156 | } 157 | 158 | 159 | /// Natural logarithm 160 | pub def ln(x: f64): f64 { 161 | if x <= 0.0 { return 0.0; } 162 | 163 | mut y: f64 = x - 1.0; 164 | for mut i = 0; i < 25; i++ { 165 | val last: f64 = y; 166 | val ey: f64 = exp(y); 167 | y = y - (ey - x) / ey; 168 | if approx_equal(last, y, 0.0000001) { break; } 169 | } 170 | return y; 171 | } 172 | 173 | /// Sine (reduced angle) 174 | pub def sin(x: f64): f64 { 175 | x = reduce_angle(x); 176 | mut term: f64 = x; 177 | mut sum: f64 = x; 178 | val x2: f64 = x * x; 179 | mut n: i32 = 1; 180 | for mut i = 1; i < 10; i++ { 181 | term = -term * x2 / ((2 * n) * (2 * n + 1)); 182 | sum = sum + term; 183 | n = n + 1; 184 | } 185 | return sum; 186 | } 187 | 188 | /// Cosine 189 | pub def cos(x: f64): f64 { 190 | x = reduce_angle(x); 191 | mut term: f64 = 1.0; 192 | mut sum: f64 = 1.0; 193 | val x2: f64 = x * x; 194 | mut n: i32 = 1; 195 | for mut i = 1; i < 10; i++ { 196 | term = -term * x2 / ((2 * n - 1) * (2 * n)); 197 | sum = sum + term; 198 | n = n + 1; 199 | } 200 | return sum; 201 | } 202 | 203 | /// Tangent 204 | pub def tan(x: f64): f64 { 205 | return sin(x) / cos(x); 206 | } 207 | 208 | /// Arcsine 209 | pub def asin(x: f64): f64 { 210 | x = clamp_float(x, -1.0, 1.0); 211 | 212 | if x > 0.7071067811865476 { 213 | return HALF_PI - asin(sqrt(1.0 - x*x)); 214 | } elif x < -0.7071067811865476 { 215 | return -HALF_PI + asin(sqrt(1.0 - x*x)); 216 | } 217 | 218 | mut term: f64 = x; 219 | mut sum: f64 = x; 220 | val x2: f64 = x * x; 221 | 222 | for mut n = 0; n < 15; n++ { 223 | term = term * ((2.0*n + 1.0)*(2.0*n + 1.0))/((2.0*n + 2.0)*(2.0*n + 3.0)) * x2; 224 | sum = sum + term; 225 | } 226 | 227 | return sum; 228 | } 229 | 230 | /// Arccosine 231 | pub def acos(x: f64): f64 { 232 | return HALF_PI - asin(x); 233 | } 234 | 235 | /// Arctangent 236 | pub def atan(x: f64): f64 { 237 | mut term: f64 = x; 238 | mut sum: f64 = x; 239 | val x2: f64 = x * x; 240 | mut sign: f64 = -1.0; 241 | for mut n = 3; n < 20; n += 2 { 242 | term = term * x2; 243 | sum = sum + sign * term / n; 244 | sign = -sign; 245 | } 246 | return sum; 247 | } 248 | 249 | /// Float power: base^exp for non-integer exponents 250 | pub def powf(base: f64, expp: f64): f64 { 251 | if base <= 0.0 { 252 | // avoid log(0) or negative base issues 253 | return 0.0; 254 | } 255 | return exp(ln(base) * expp); 256 | } 257 | 258 | /// Two-argument arctangent: returns angle in radians between [-PI, PI] 259 | pub def atan2(y: f64, x: f64): f64 { 260 | if x > 0.0 { 261 | return atan(y / x); 262 | } elif x < 0.0 and y >= 0.0 { 263 | return atan(y / x) + PI; 264 | } elif x < 0.0 and y < 0.0 { 265 | return atan(y / x) - PI; 266 | } elif x == 0.0 and y > 0.0 { 267 | return HALF_PI; 268 | } elif x == 0.0 and y < 0.0 { 269 | return -HALF_PI; 270 | } else { 271 | return 0.0; 272 | } 273 | } 274 | 275 | /// Hyperbolic tangent inverse 276 | pub def atanh(x: f64): f64 { 277 | if x <= -1.0 or x >= 1.0 { 278 | return 0.0; 279 | } 280 | return 0.5 * ln((1.0 + x) / (1.0 - x)); 281 | } 282 | 283 | test { 284 | assert(approx_equal(sqrt(16.0), 4.0, 0.001), "sqrt(16) should be ~4"); 285 | assert(approx_equal(sin(PI/2.0), 1.0, 0.01), "sin(pi/2) should be ~1"); 286 | assert(approx_equal(cos(0.0), 1.0, 0.01), "cos(0) should be ~1"); 287 | assert(approx_equal(tan(PI/4.0), 1.0, 0.05), "tan(pi/4) should be ~1"); 288 | assert(approx_equal(asin(1.0), PI/2.0, 0.05), "asin(1) should be ~pi/2"); 289 | assert(approx_equal(acos(0.0), PI/2.0, 0.05), "acos(0) should be ~pi/2"); 290 | assert(approx_equal(atan(1.0), PI/4.0, 0.05), "atan(1) should be ~pi/4"); 291 | assert(approx_equal(exp(1.0), E, 0.05), "exp(1) should be ~E"); 292 | assert(approx_equal(ln(E), 1.0, 0.05), "ln(E) should be ~1"); 293 | assert(clamp(5, 0, 10) == 5, "clamp mid"); 294 | assert(clamp(-5, 0, 10) == 0, "clamp below"); 295 | assert(clamp(50, 0, 10) == 10, "clamp above"); 296 | assert(clamp_float(5.5, 0.0, 10.0) == 5.5, "clamp_float mid"); 297 | assert(clamp_float(-1.0, 0.0, 10.0) == 0.0, "clamp_float below"); 298 | assert(clamp_float(20.0, 0.0, 10.0) == 10.0, "clamp_float above"); 299 | assert(absolute(-5.0) == 5.0, "absolute neg"); 300 | assert(absolute(5.0) == 5.0, "absolute pos"); 301 | assert(floor(5.2) == 5.0, "floor positive"); 302 | assert(floor(-1.2) == -2.0, "floor negative fractional"); 303 | assert(floor(-1.0) == -1.0, "floor negative exact"); 304 | assert(ceil(5.2) == 6.0, "ceil positive"); 305 | assert(ceil(-1.2) == -1.0, "ceil negative fractional"); 306 | assert(ceil(2.0) == 2.0, "ceil exact"); 307 | assert(round(5.4) == 5.0, "round down"); 308 | assert(round(5.6) == 6.0, "round up"); 309 | assert(round(-1.4) == -1.0, "round negative down"); 310 | assert(round(-1.6) == -2.0, "round negative up"); 311 | assert(approx_equal(sqrt(2.0), 1.4142, 0.01), "sqrt(2)"); 312 | assert(approx_equal(sqrt(0.25), 0.5, 0.01), "sqrt(0.25)"); 313 | assert(approx_equal(sqrt(10000.0), 100.0, 0.01), "sqrt(10000)"); 314 | assert(approx_equal(reduce_angle(PI), PI, 0.001), "reduce pi"); 315 | assert(approx_equal(reduce_angle(PI + TWO_PI), PI, 0.001), "reduce angle wrap"); 316 | assert(approx_equal(reduce_angle(-PI), TWO_PI - PI, 0.001), "reduce negative"); 317 | assert(approx_equal(mod_float(10.5, 2.0), 0.5, 0.001), "mod float basic"); 318 | assert(approx_equal(mod_float(-1.0, 2.0), 1.0, 0.001), "mod float negative"); 319 | assert(approx_equal(pow(2.0, 10), 1024.0, 0.001), "pow positive exp"); 320 | assert(approx_equal(pow(2.0, -3), 0.125, 0.001), "pow negative exp"); 321 | assert(approx_equal(pow(5.0, 0), 1.0, 0.0001), "pow zero"); 322 | assert(approx_equal(ln(exp(2.0)), 2.0, 0.05), "ln(exp(x)) ≈ x"); 323 | assert(approx_equal(exp(ln(2.0)), 2.0, 0.05), "exp(ln(x)) ≈ x"); 324 | assert(approx_equal(sin(0.0), 0.0, 0.01), "sin(0)"); 325 | assert(approx_equal(cos(PI), -1.0, 0.05), "cos(pi)"); 326 | 327 | val s: f64 = sin(1.0); 328 | val c: f64 = cos(1.0); 329 | 330 | assert(approx_equal(s*s + c*c, 1.0, 0.05), "sin^2 + cos^2 = 1"); 331 | assert(approx_equal(atan(0.0), 0.0, 0.01), "atan(0)"); 332 | assert(approx_equal(asin(0.0), 0.0, 0.05), "asin(0)"); 333 | assert(approx_equal(acos(1.0), 0.0, 0.05), "acos(1)"); 334 | assert(approx_equal(powf(2.0, 10.0), 1024.0, 0.01), "powf 2^10"); 335 | assert(approx_equal(powf(9.0, 0.5), 3.0, 0.01), "powf sqrt via powf"); 336 | assert(approx_equal(powf(E, 1.0), E, 0.01), "powf e^1"); 337 | assert(approx_equal(powf(E, 2.0), E*E, 0.05), "powf e^2"); 338 | assert(approx_equal(powf(10.0, -1.0), 0.1, 0.01), "powf 10^-1"); 339 | } 340 | -------------------------------------------------------------------------------- /source/compiler/std/json.axec: -------------------------------------------------------------------------------- 1 | use std.string ( 2 | string 3 | ); 4 | 5 | use external("yyjson.h"); 6 | 7 | /// JSON value types 8 | val JSON_TYPE_NULL: i32 = 0; 9 | val JSON_TYPE_BOOL: i32 = 1; 10 | val JSON_TYPE_NUM: i32 = 2; 11 | val JSON_TYPE_STR: i32 = 3; 12 | val JSON_TYPE_ARR: i32 = 4; 13 | val JSON_TYPE_OBJ: i32 = 5; 14 | 15 | extern def yyjson_read(json: char*, size: size_t, flags: i32): char*; 16 | extern def yyjson_doc_free(doc: char*); 17 | extern def yyjson_doc_get_root(doc: char*): char*; 18 | extern def yyjson_is_null(value: char*): bool; 19 | extern def yyjson_is_bool(value: char*): bool; 20 | extern def yyjson_is_num(value: char*): bool; 21 | extern def yyjson_is_str(value: char*): bool; 22 | 23 | /// Parse a JSON string and return a document 24 | def parse(json_str: string): ref char { 25 | mut doc: ref char = nil; 26 | doc = cast[ref char](yyjson_read(json_str.data, json_str.len, 0)); 27 | return doc; 28 | } 29 | 30 | /// Free a JSON document 31 | def free_doc(doc: ref char) { 32 | if doc != nil { 33 | yyjson_doc_free(cast[ref yyjson_doc](doc)); 34 | } 35 | } 36 | 37 | /// Get the root value from a JSON document 38 | def get_root(doc: ref char): ref char { 39 | mut root: ref char = nil; 40 | if doc != nil { 41 | root = cast[ref char](yyjson_doc_get_root(cast[ref yyjson_doc](doc))); 42 | } 43 | return root; 44 | } 45 | 46 | /// Check if a value is null 47 | def is_null(value: ref char): bool { 48 | mut result: bool = false; 49 | if value != nil { 50 | result = yyjson_is_null(cast[ref yyjson_val](value)); 51 | } 52 | return result; 53 | } 54 | 55 | /// Check if a value is a boolean 56 | def is_bool(value: ref char): bool { 57 | mut result: bool = false; 58 | if value != nil { 59 | result = yyjson_is_bool(cast[ref yyjson_val](value)); 60 | } 61 | return result; 62 | } 63 | 64 | /// Check if a value is a number 65 | def is_num(value: ref char): bool { 66 | mut result: bool = false; 67 | if value != nil { 68 | result = yyjson_is_num(cast[ref yyjson_val](value)); 69 | } 70 | return result; 71 | } 72 | 73 | /// Check if a value is a string 74 | def is_str(value: ref char): bool { 75 | mut result: bool = false; 76 | if value != nil { 77 | result = yyjson_is_str(cast[ref yyjson_val](value)); 78 | } 79 | return result; 80 | } 81 | 82 | extern def yyjson_is_arr(value: ref char): bool; 83 | 84 | /// Check if a value is an array 85 | def is_array(value: ref char): bool { 86 | mut result: bool = false; 87 | if value != nil { 88 | result = yyjson_is_arr(cast[ref yyjson_val](value)); 89 | } 90 | return result; 91 | } 92 | 93 | extern def yyjson_is_obj(value: ref char): bool; 94 | 95 | /// Check if a value is an object 96 | def is_object(value: ref char): bool { 97 | mut result: bool = false; 98 | if value != nil { 99 | result = yyjson_is_obj(cast[ref yyjson_val](value)); 100 | } 101 | return result; 102 | } 103 | 104 | extern def yyjson_get_bool(value: ref char): bool; 105 | 106 | /// Get boolean value 107 | def get_bool(value: ref char): bool { 108 | mut result: bool = false; 109 | if value != nil { 110 | result = yyjson_get_bool(cast[ref yyjson_val](value)); 111 | } 112 | return result; 113 | } 114 | 115 | extern def yyjson_get_int(value: ref char): i32; 116 | 117 | /// Get integer value 118 | def get_int(value: ref char): i32 { 119 | mut result: i32 = 0; 120 | if value != nil { 121 | result = yyjson_get_int(cast[ref yyjson_val](value)); 122 | } 123 | return result; 124 | } 125 | 126 | extern def yyjson_get_sint(value: ref char): i64; 127 | 128 | /// Get 64-bit integer value 129 | def get_int64(value: ref char): i64 { 130 | mut result: i64 = 0; 131 | if result != nil { 132 | result = yyjson_get_sint(cast[ref yyjson_val](value)); 133 | } 134 | return result; 135 | } 136 | 137 | extern def yyjson_get_real(value: ref char): f64; 138 | 139 | /// Get floating point value 140 | def get_real(value: ref char): f64 { 141 | mut result: f64 = 0.0; 142 | if value != nil { 143 | result = yyjson_get_real(cast[ref yyjson_val](value)); 144 | } 145 | return result; 146 | } 147 | 148 | extern def yyjson_get_str(value: ref char): ref char; 149 | extern def yyjson_get_len(value: ref char): usize; 150 | extern def yyjson_arr_get_first(arr: ref char): ref char; 151 | 152 | /// Get string value 153 | def get_str(value: ref char): string { 154 | mut result: string; 155 | 156 | result.data = nil; 157 | result.len = 0; 158 | result.cap = 0; 159 | 160 | if value != nil { 161 | val str: ref char = yyjson_get_str(cast[ref yyjson_val](value)); 162 | if str != nil { 163 | mut length: usize = yyjson_get_len(cast[ref yyjson_val](value)); 164 | result.data = cast[ref char](C.malloc(length + 1)); 165 | if result.data != nil { 166 | C.memcpy(result.data, str, length); 167 | result.data[length] = '\0'; 168 | result.len = length; 169 | result.cap = length + 1; 170 | } 171 | } 172 | } 173 | return result; 174 | } 175 | 176 | /// Get the length of an array or object 177 | def get_len(value: ref char): usize { 178 | mut result: usize = 0; 179 | if value != nil { 180 | result = yyjson_get_len(cast[ref yyjson_val](value)); 181 | } 182 | return result; 183 | } 184 | 185 | /// Get a value from an object by key 186 | def obj_get(obj: ref char, key: string): ref char { 187 | mut result: ref char = nil; 188 | if obj != nil && key.data != nil { 189 | result = yyjson_obj_get(cast[ref yyjson_val](obj), key.data); 190 | } 191 | return result; 192 | } 193 | 194 | /// Get a value from an array by index 195 | def arr_get(arr: ref char, idx: usize): ref char { 196 | mut result: ref char = nil; 197 | if arr != nil { 198 | result = yyjson_arr_get(cast[ref yyjson_val](arr), idx); 199 | } 200 | return result; 201 | } 202 | 203 | /// Get the first element in an array 204 | def arr_get_first(arr: ref char): ref char { 205 | mut result: ref char = nil; 206 | if arr != nil { 207 | result = yyjson_arr_get_first(cast[ref yyjson_val](arr)); 208 | } 209 | return result; 210 | } 211 | 212 | /// Get the last element in an array 213 | def arr_get_last(arr: ref char): ref char { 214 | mut result: ref char = nil; 215 | if arr != nil { 216 | result = yyjson_arr_get_last(cast[ref yyjson_val](arr)); 217 | } 218 | return result; 219 | } 220 | 221 | /// Serialize a JSON document to a string 222 | def stringify(doc: ref char): string { 223 | mut result: string; 224 | result.data = nil; 225 | result.len = 0; 226 | result.cap = 0; 227 | if doc != nil { 228 | mut len: usize; 229 | val json: ref char = yyjson_write(cast[ref yyjson_doc](doc), 0, addr(len)); 230 | if json != nil { 231 | result.data = json; 232 | result.len = len; 233 | result.cap = len + 1; 234 | } 235 | } 236 | return result; 237 | } 238 | 239 | /// Serialize a JSON value to a string 240 | def stringify_val(value: ref char): string { 241 | mut result: string; 242 | 243 | result.data = nil; 244 | result.len = 0; 245 | result.cap = 0; 246 | 247 | if value != nil { 248 | mut len: usize; 249 | val json: ref char = yyjson_val_write(cast[ref yyjson_val](value), 0, addr(len)); 250 | if json != nil { 251 | result.data = json; 252 | result.len = len; 253 | result.cap = len + 1; 254 | } 255 | } 256 | return result; 257 | } 258 | 259 | /// Serialize with pretty formatting 260 | def stringify_pretty(doc: ref char): string { 261 | mut result: string; 262 | result.data = nil; 263 | result.len = 0; 264 | result.cap = 0; 265 | 266 | foreign {YYJSON_WRITE_PRETTY}; 267 | 268 | if doc != nil { 269 | mut len: usize; 270 | val json: ref char = yyjson_write(cast[ref yyjson_doc](doc), YYJSON_WRITE_PRETTY, addr(len)); 271 | if json != nil { 272 | result.data = json; 273 | result.len = len; 274 | result.cap = len + 1; 275 | } 276 | } 277 | return result; 278 | } 279 | 280 | /// Read JSON from a file 281 | def read_file(path: string): ref char { 282 | mut doc: ref char = nil; 283 | if path.data != nil { 284 | doc = cast[ref char](yyjson_read_file(path.data, 0, nil, nil)); 285 | } 286 | return doc; 287 | } 288 | 289 | /// Write JSON to a file 290 | def write_file(path: string, doc: ref char): bool { 291 | mut success: bool = false; 292 | if path.data != nil and doc != nil { 293 | success = yyjson_write_file(path.data, cast[ref yyjson_doc](doc), 0, nil, nil); 294 | } 295 | return success; 296 | } 297 | 298 | test { 299 | mut json_str: string = string.create("{\"name\":\"John\",\"age\":30,\"active\":true}"); 300 | mut doc: ref char = parse(json_str); 301 | 302 | assert doc != nil, "Should parse valid JSON"; 303 | 304 | if doc != nil { 305 | mut root: ref char = get_root(doc); 306 | assert root != nil, "Should get root value"; 307 | assert is_object(root), "Root should be an object"; 308 | 309 | mut name_val: ref char = obj_get(root, string.create("name")); 310 | assert name_val != nil, "Should find 'name' key"; 311 | assert is_str(name_val), "name should be a string"; 312 | 313 | mut name: string = get_str(name_val); 314 | assert name.len > 0, "Should get string value"; 315 | 316 | mut age_val: ref char = obj_get(root, string.create("age")); 317 | assert age_val != nil, "Should find 'age' key"; 318 | assert is_num(age_val), "age should be a number"; 319 | 320 | mut age: i32 = get_int(age_val); 321 | assert age == 30, "age should be 30"; 322 | 323 | mut active_val: ref char = obj_get(root, string.create("active")); 324 | assert active_val != nil, "Should find 'active' key"; 325 | assert is_bool(active_val), "active should be a boolean"; 326 | 327 | mut active: bool = get_bool(active_val); 328 | assert active, "active should be true"; 329 | 330 | free_doc(doc); 331 | } 332 | 333 | mut arr_str: string = string.create("[1,2,3,4,5]"); 334 | mut arr_doc: ref char = parse(arr_str); 335 | 336 | assert arr_doc != nil, "Should parse JSON array"; 337 | 338 | if arr_doc != nil { 339 | mut arr_root: ref char = get_root(arr_doc); 340 | assert is_array(arr_root), "Root should be an array"; 341 | 342 | mut len: usize = get_len(arr_root); 343 | assert len == 5, "Array should have 5 elements"; 344 | 345 | mut first: ref char = arr_get(arr_root, cast[usize](0)); 346 | assert is_num(first), "First element should be a number"; 347 | assert get_int(first) == 1, "First element should be 1"; 348 | 349 | free_doc(arr_doc); 350 | } 351 | } 352 | -------------------------------------------------------------------------------- /source/compiler/std/maps.axec: -------------------------------------------------------------------------------- 1 | use std.lists; 2 | use std.arena; 3 | use std.string; 4 | 5 | /// Generic Map using memcmp for key comparison 6 | macro make_map(keytype_elem: untyped, valtype_elem: untyped, mapname: untyped, keytype: untyped, valtype: untyped) { 7 | pub model mapname { 8 | keys: ref keytype; 9 | values: ref valtype; 10 | 11 | pub def create(arena: ref Arena, capacity: i32): ref mapname { 12 | mut map: ref mapname; 13 | unsafe { 14 | map = Arena.alloc(arena, C.sizeof(mapname)); 15 | } 16 | map.keys = keytype.create(arena, capacity); 17 | map.values = valtype.create(arena, capacity); 18 | return map; 19 | } 20 | 21 | pub def clear(map: ref mapname) { 22 | map.keys.len = 0; 23 | map.values.len = 0; 24 | } 25 | 26 | pub def append(map: ref mapname, arena: ref Arena, key: keytype_elem, value: valtype_elem) { 27 | keytype.push(map.keys, arena, key); 28 | valtype.push(map.values, arena, value); 29 | } 30 | 31 | pub def add(map: ref mapname, arena: ref Arena, key: keytype_elem, value: valtype_elem) { 32 | keytype.push(map.keys, arena, key); 33 | valtype.push(map.values, arena, value); 34 | } 35 | 36 | pub def set(map: ref mapname, arena: ref Arena, key: keytype_elem, value: valtype_elem) { 37 | mut i: i32 = 0; 38 | val keys: ref keytype = map.keys; 39 | mut values: ref valtype = map.values; 40 | loop { 41 | if i >= keys.len { 42 | break; 43 | } 44 | unsafe { 45 | if C.memcmp(&(keys*.data[i]), &key, C.sizeof(key)) == 0 { 46 | values*.data[i] = value; 47 | return; 48 | } 49 | } 50 | i = i + 1; 51 | } 52 | keytype.push(map.keys, arena, key); 53 | valtype.push(map.values, arena, value); 54 | } 55 | 56 | pub def get(map: ref mapname, key: keytype_elem): valtype_elem { 57 | mut i: i32 = 0; 58 | val keys: ref keytype = map.keys; 59 | val values: ref valtype = map.values; 60 | loop { 61 | if i >= keys.len { 62 | break; 63 | } 64 | unsafe { 65 | if C.memcmp(&(keys*.data[i]), &key, C.sizeof(key)) == 0 { 66 | return values*.data[i]; 67 | } 68 | } 69 | i = i + 1; 70 | } 71 | mut default_val: valtype_elem; 72 | unsafe { 73 | C.memset(&default_val, 0, C.sizeof(default_val)); 74 | } 75 | return default_val; 76 | } 77 | 78 | pub def contains(map: ref mapname, key: keytype_elem): bool { 79 | mut i: i32 = 0; 80 | val keys: ref keytype = map.keys; 81 | loop { 82 | if i >= keys.len { 83 | break; 84 | } 85 | unsafe { 86 | if C.memcmp(&(keys*.data[i]), &key, C.sizeof(key)) == 0 { 87 | return true; 88 | } 89 | } 90 | i = i + 1; 91 | } 92 | return false; 93 | } 94 | 95 | pub def size(map: ref mapname): i32 { 96 | val keys: ref keytype = map.keys; 97 | return keys.len; 98 | } 99 | 100 | pub def pop(map: ref mapname, key: keytype_elem): valtype_elem { 101 | mut i: i32 = 0; 102 | mut keys: ref keytype = map.keys; 103 | mut values: ref valtype = map.values; 104 | mut result: valtype_elem; 105 | mut found: bool = false; 106 | loop { 107 | if i >= keys.len { 108 | break; 109 | } 110 | unsafe { 111 | if C.memcmp(&(keys*.data[i]), &key, C.sizeof(key)) == 0 { 112 | found = true; 113 | } 114 | } 115 | if found { 116 | result = values.data[i]; 117 | unsafe { 118 | for mut j = i; j < keys.len - 1; j++ { 119 | keys*.data[j] = keys*.data[j + 1]; 120 | values*.data[j] = values*.data[j + 1]; 121 | } 122 | keys*.len--; 123 | values*.len--; 124 | } 125 | return result; 126 | } 127 | i = i + 1; 128 | } 129 | mut default_val: valtype_elem; 130 | unsafe { 131 | C.memset(&default_val, 0, C.sizeof(default_val)); 132 | } 133 | return default_val; 134 | } 135 | } 136 | } 137 | 138 | /// Generic StringHashMap with proper string comparison 139 | macro make_string_map(valtype_elem: untyped, mapname: untyped, valtype: untyped) { 140 | pub model mapname { 141 | keys: ref StringList; 142 | values: ref valtype; 143 | 144 | pub def create(arena: ref Arena, capacity: i32): ref mapname { 145 | mut map: ref mapname; 146 | unsafe { 147 | map = Arena.alloc(arena, C.sizeof(mapname)); 148 | } 149 | map.keys = StringList.create(arena, capacity); 150 | map.values = valtype.create(arena, capacity); 151 | return map; 152 | } 153 | 154 | pub def clear(map: ref mapname) { 155 | map.keys.len = 0; 156 | map.values.len = 0; 157 | } 158 | 159 | pub def add(map: ref mapname, arena: ref Arena, key: string, value: valtype_elem) { 160 | StringList.push(map.keys, arena, key); 161 | valtype.push(map.values, arena, value); 162 | } 163 | 164 | pub def set(map: ref mapname, arena: ref Arena, key: string, value: valtype_elem) { 165 | mut i: i32 = 0; 166 | val keys: ref StringList = map.keys; 167 | mut values: ref valtype = map.values; 168 | loop { 169 | if i >= keys.len { 170 | break; 171 | } 172 | val current_key: string = keys.data[i]; 173 | unsafe { 174 | if current_key.len == key.len { 175 | if C.strncmp(current_key.data, key.data, key.len) == 0 { 176 | values*.data[i] = value; 177 | return; 178 | } 179 | } 180 | } 181 | i = i + 1; 182 | } 183 | StringList.push(map.keys, arena, key); 184 | valtype.push(map.values, arena, value); 185 | } 186 | 187 | pub def get(map: ref mapname, key: string): valtype_elem { 188 | mut i: i32 = 0; 189 | val keys: ref StringList = map.keys; 190 | val values: ref valtype = map.values; 191 | loop { 192 | if i >= keys.len { 193 | break; 194 | } 195 | val current_key: string = keys.data[i]; 196 | unsafe { 197 | if current_key.len == key.len { 198 | if C.strncmp(current_key.data, key.data, key.len) == 0 { 199 | return values*.data[i]; 200 | } 201 | } 202 | } 203 | i = i + 1; 204 | } 205 | mut default_val: valtype_elem; 206 | unsafe { 207 | C.memset(&default_val, 0, C.sizeof(default_val)); 208 | } 209 | return default_val; 210 | } 211 | 212 | pub def contains(map: ref mapname, key: string): bool { 213 | mut i: i32 = 0; 214 | val keys: ref StringList = map.keys; 215 | loop { 216 | if i >= keys.len { 217 | break; 218 | } 219 | val current_key: string = keys.data[i]; 220 | unsafe { 221 | if current_key.len == key.len { 222 | if C.strncmp(current_key.data, key.data, key.len) == 0 { 223 | return true; 224 | } 225 | } 226 | } 227 | i = i + 1; 228 | } 229 | return false; 230 | } 231 | 232 | pub def size(map: ref mapname): i32 { 233 | val keys: ref StringList = map.keys; 234 | return keys.len; 235 | } 236 | 237 | pub def pop(map: ref mapname, key: string): valtype_elem { 238 | mut i: i32 = 0; 239 | mut keys: ref StringList = map.keys; 240 | mut values: ref valtype = map.values; 241 | mut result: valtype_elem; 242 | mut found: bool = false; 243 | loop { 244 | if i >= keys.len { 245 | break; 246 | } 247 | val current_key: string = keys.data[i]; 248 | unsafe { 249 | if current_key.len == key.len { 250 | if C.strncmp(current_key.data, key.data, key.len) == 0 { 251 | found = true; 252 | } 253 | } 254 | } 255 | if found { 256 | result = values.data[i]; 257 | unsafe { 258 | for mut j = i; j < keys.len - 1; j++ { 259 | keys*.data[j] = keys*.data[j + 1]; 260 | values*.data[j] = values*.data[j + 1]; 261 | } 262 | keys*.len--; 263 | values*.len--; 264 | } 265 | return result; 266 | } 267 | i = i + 1; 268 | } 269 | mut default_val: valtype_elem; 270 | unsafe { 271 | C.memset(&default_val, 0, C.sizeof(default_val)); 272 | } 273 | return default_val; 274 | } 275 | } 276 | } 277 | 278 | make_string_map(i32, StringIntMap, IntList); 279 | make_string_map(f32, StringFloatMap, FloatList); 280 | make_string_map(bool, StringBoolMap, BoolList); 281 | make_string_map(string, StringStringMap, StringList); 282 | 283 | make_map(i32, i32, IntIntMap, IntList, IntList); 284 | make_map(f32, i32, FloatIntMap, FloatList, IntList); 285 | make_map(i32, f32, IntFloatMap, IntList, FloatList); 286 | make_map(f32, f32, FloatFloatMap, FloatList, FloatList); 287 | make_map(i32, bool, IntBoolMap, IntList, BoolList); 288 | make_map(bool, i32, BoolIntMap, BoolList, IntList); 289 | make_map(f32, bool, FloatBoolMap, FloatList, BoolList); 290 | make_map(bool, f32, BoolFloatMap, BoolList, FloatList); 291 | make_map(bool, bool, BoolBoolMap, BoolList, BoolList); 292 | 293 | test { 294 | mut arena: Arena = Arena.create(1024); 295 | 296 | val int_map: ref IntIntMap = IntIntMap.create(addr(arena), 10); 297 | 298 | IntIntMap.add(int_map, addr(arena), 1, 100); 299 | IntIntMap.add(int_map, addr(arena), 2, 200); 300 | IntIntMap.add(int_map, addr(arena), 3, 300); 301 | 302 | assert(IntIntMap.get(int_map, 1) == 100, "IntIntMap should return 100 for key 1"); 303 | assert(IntIntMap.get(int_map, 2) == 200, "IntIntMap should return 200 for key 2"); 304 | assert(IntIntMap.get(int_map, 3) == 300, "IntIntMap should return 300 for key 3"); 305 | assert(IntIntMap.contains(int_map, 1), "IntIntMap should contain key 1"); 306 | assert(IntIntMap.contains(int_map, 2), "IntIntMap should contain key 2"); 307 | assert(!IntIntMap.contains(int_map, 999), "IntIntMap should not contain key 999"); 308 | assert(IntIntMap.size(int_map) == 3, "IntIntMap size should be 3"); 309 | 310 | val str_int_map: ref StringIntMap = StringIntMap.create(addr(arena), 10); 311 | 312 | StringIntMap.add(str_int_map, addr(arena), str("foo"), 42); 313 | StringIntMap.add(str_int_map, addr(arena), str("bar"), 99); 314 | StringIntMap.add(str_int_map, addr(arena), str("baz"), 77); 315 | 316 | assert(StringIntMap.get(str_int_map, str("foo")) == 42, "StringIntMap should return 42 for key 'foo'"); 317 | assert(StringIntMap.get(str_int_map, str("bar")) == 99, "StringIntMap should return 99 for key 'bar'"); 318 | assert(StringIntMap.get(str_int_map, str("baz")) == 77, "StringIntMap should return 77 for key 'baz'"); 319 | assert(StringIntMap.contains(str_int_map, str("foo")), "StringIntMap should contain key 'foo'"); 320 | assert(!StringIntMap.contains(str_int_map, str("missing")), "StringIntMap should not contain key 'missing'"); 321 | assert(StringIntMap.size(str_int_map) == 3, "StringIntMap size should be 3"); 322 | 323 | val float_map: ref FloatIntMap = FloatIntMap.create(addr(arena), 10); 324 | 325 | FloatIntMap.add(float_map, addr(arena), cast[f32](3.14), 314); 326 | FloatIntMap.add(float_map, addr(arena), cast[f32](2.71), 271); 327 | 328 | assert(FloatIntMap.get(float_map, 3.14) == 314, "FloatIntMap should return 314 for key 3.14"); 329 | assert(FloatIntMap.get(float_map, 2.71) == 271, "FloatIntMap should return 271 for key 2.71"); 330 | assert(FloatIntMap.contains(float_map, 3.14), "FloatIntMap should contain key 3.14"); 331 | assert(!FloatIntMap.contains(float_map, 1.23), "FloatIntMap should not contain key 1.23"); 332 | assert(FloatIntMap.size(float_map) == 2, "FloatIntMap size should be 2"); 333 | } 334 | --------------------------------------------------------------------------------