/// JcMajor is the current major version of this library. /// /// Major versions are guaranteed to have stable apis /// for their duration. JcMajor :: 0; /// JcMinor is the current minor version of this library. /// /// Minor versions denote bug fixes, additions, or improvements /// that do not affect api stability. JcMinor :: 1; // @note(judah): we can't use range_of here because a compiler bug? S8Min :: #run min_of(s8); /// -128 (-0x80) S8Max :: #run max_of(s8); /// 127 (0x7f) S16Min :: #run min_of(s16); /// -32768 (-0x8000) S16Max :: #run max_of(s16); /// 32767 (0x7f_ff) S32Min :: #run min_of(s32); /// -2147483648 (-0x8000_0000) S32Max :: #run max_of(s32); /// 2147483647 (0x7fff_ffff) S64Min :: #run min_of(s64); /// -9223372036854775808 (-0x80000000_00000000) S64Max :: #run max_of(s64); /// 9223372036854775807 (0x7fffffff_ffffffff) U8Min :: #run min_of(u8); /// 0 (0x00) U8Max :: #run max_of(u8); /// 255 (0xff) U16Min :: #run min_of(u16); /// 0 (0x00_00) U16Max :: #run max_of(u16); /// 65535 (0xff_ff) U32Min :: #run min_of(u32); /// 0 (0x0000_0000) U32Max :: #run max_of(u32); /// 4294967295 (0xffff_ffff) U64Min :: #run min_of(u64); /// 0 (0x00000000_00000000) U64Max :: #run max_of(u64); /// 18446744073709551615 (0xffffffff_ffffffff) Float32Min :: #run min_of(float32); /// 1.17549e-38 (0h0080_0000) Float32Max :: #run max_of(float32); /// 3.40282e+38 (0h7f7fffff) Float64Min :: #run min_of(float64); /// 2.22507e-308 (0h00100000_00000000) Float64Max :: #run max_of(float64); /// 1.79769e+308 (0h7fefffff_ffffffff) /// m0 is a 0-size marker type. /// /// It allows specific offsets within a type to be marked which is useful for (de)serialization. /// /// MyType :: struct { /// do_not_serialize_1: *void; /// /// _start: m0; // Has the same offset as serialize_1 /// serialize_1: [32]u8; /// serialize_2: u64; /// serialize_3: bool; /// serialize_4: float32; /// _end: m0; // Has the same offset as serialize_4 /// /// do_not_serialize_2: [..]int; /// } /// /// value := MyType.{}; /// start := *value + offset_of(value, #code _start); /// end := *value + offset_of(value, #code _end); /// WriteToDisk(data = start, count = end - start); /// m0 :: #type void; b8 :: enum u8 { false_ :: (0 != 0).(u8); true_ :: (0 == 0).(u8); }; /// b8 is an 8-bit boolean. b16 :: enum u16 { false_ :: (0 != 0).(u16); true_ :: (0 == 0).(u16); }; /// b16 is a 16-bit boolean. b32 :: enum u32 { false_ :: (0 != 0).(u32); true_ :: (0 == 0).(u32); }; /// b32 is a 32-bit boolean. b64 :: enum u64 { false_ :: (0 != 0).(u64); true_ :: (0 == 0).(u64); }; /// b64 is a 64-bit boolean. /// Panic displays the given message and crashes the program. /// /// Note: Defers will not run when Panic is called. Panic :: (message := "runtime panic", loc := #caller_location) #expand #no_debug { #if DebugBuild { WriteStderrLocation(loc); WriteStderrString(": "); } WriteStderrString(message, "\n"); Trap(); } /// Unreachable displays the given message and causes an execution trap. /// /// Note: Defers will not run when Unreachable is called. Unreachable :: (message := "unreachable code hit", loc := #caller_location) #expand #no_debug { trap :: #ifx DebugBuild then DebugTrap else Trap; #if DebugBuild { WriteStderrLocation(loc); WriteStderrString(": "); } WriteStderrString(message, "\n"); trap(); } /// CompileError displays the given message and stops compilation. /// /// Note: By default, the error is reported at the callsite. CompileError :: (message: string, loc := #caller_location) #expand #no_debug #compile_time { if #compile_time { compiler_report(message, loc, .ERROR); } else { Panic("CompileError can only be called at compile-time", loc = loc); } } // @todo(judah): these should be different! /// Trap causes an execution trap. Trap :: () #expand #no_debug { debug_break(); // Provided by Runtime_Support } /// DebugTrap causes an execution trap that grabs the attention of a debugger. DebugTrap :: () #expand #no_debug { debug_break(); // Provided by Runtime_Support } #if DebugBuild { /// Assert causes a debug break if the given condition is false. Assert :: (cond: bool, message := "condition was false", loc := #caller_location) #expand #no_debug { // @note(judah): We only need to do this to route into the context's builtin assertion handling. if cond || context.handling_assertion_failure return; context.handling_assertion_failure = true; should_trap := context.assertion_failed(loc, message); context.handling_assertion_failure = false; if should_trap { DebugTrap(); } } /// AssertCallsite works identically to Assert, except that it expects a /// Source_Code_Location (called 'loc') to exist in the calling scope. /// /// MyProc :: (loc := #caller_location) { /// AssertCallsite(false); // 'loc' is passed implicitly /// Assert(false, loc = loc); // equivalent /// } /// AssertCallsite :: (cond: bool, message := "condition was false") #expand #no_debug { Assert(cond, message, loc = `loc); } } else { // @note(judah): these need to be separate declarations so we can use #discard. // otherwise, the compiler will generate instructions to setup the call when assertions are disabled. Assert :: (#discard cond: bool, #discard message := "", #discard loc := #caller_location) #expand #no_debug {} AssertCallsite :: (#discard cond: bool, #discard message := "") #expand #no_debug {} } #scope_module WriteString :: write_strings; @jc.nodocs // Provided by Runtime_Support WriteNumber :: write_number; @jc.nodocs // Provided by Runtime_Support // @note(judah): This is a direct copy of Runtime_Support's write_loc since it's not exported WriteStderrLocation :: (loc: Source_Code_Location) { WriteStderrString(loc.fully_pathed_filename, ":"); WriteStderrNumber(loc.line_number); WriteStderrString(","); WriteStderrNumber(loc.character_number); } @jc.nodocs #scope_file DebugBuild :: #run -> bool { // @note(judah): there's not really a good way to detect opt level/build type, // so just check if debug info is being emitted. #import "Compiler"; opts := get_build_options(); return opts.emit_debug_info != .NONE; }; WriteStderrString :: #bake_arguments write_strings(to_standard_error = true); // Provided by Runtime_Support WriteStderrNumber :: #bake_arguments write_number(to_standard_error = true); // Provided by Runtime_Support