181 lines
6.5 KiB
Text
181 lines
6.5 KiB
Text
/// 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 := "jc: 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 := "jc: 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("jc: 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 := "jc: 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 := "jc: 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
|
|
|
|
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
|
|
|
|
|
|
#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;
|
|
};
|