Merge branch 'master' into windows-llvm-11.1.0

This commit is contained in:
gingerBill
2023-05-02 12:07:04 +01:00
53 changed files with 1387 additions and 55 deletions

View File

@@ -11,7 +11,7 @@
<img src="https://img.shields.io/badge/platforms-Windows%20|%20Linux%20|%20macOS-green.svg">
</a>
<br>
<a href="https://discord.gg/odinlang">
<a href="https://discord.com/invite/sVBPHEv">
<img src="https://img.shields.io/discord/568138951836172421?logo=discord">
</a>
<a href="https://github.com/odin-lang/odin/actions">

View File

@@ -157,7 +157,7 @@ run_demo() {
}
have_which() {
if ! [ -x "$(command -v which)" ]; then
if ! command -v which > /dev/null 2>&1 ; then
panic "Could not find \`which\`"
fi
}

View File

@@ -2,25 +2,25 @@ package bufio
import "core:io"
// Loadahead_Reader provides io lookahead.
// Lookahead_Reader provides io lookahead.
// This is useful for tokenizers/parsers.
// Loadahead_Reader is similar to bufio.Reader, but unlike bufio.Reader, Loadahead_Reader's buffer size
// Lookahead_Reader is similar to bufio.Reader, but unlike bufio.Reader, Lookahead_Reader's buffer size
// will EXACTLY match the specified size, whereas bufio.Reader's buffer size may differ from the specified size.
// This makes sure that the buffer will not be accidentally read beyond the expected size.
Loadahead_Reader :: struct {
Lookahead_Reader :: struct {
r: io.Reader,
buf: []byte,
n: int,
}
lookahead_reader_init :: proc(lr: ^Loadahead_Reader, r: io.Reader, buf: []byte) -> ^Loadahead_Reader {
lookahead_reader_init :: proc(lr: ^Lookahead_Reader, r: io.Reader, buf: []byte) -> ^Lookahead_Reader {
lr.r = r
lr.buf = buf
lr.n = 0
return lr
}
lookahead_reader_buffer :: proc(lr: ^Loadahead_Reader) -> []byte {
lookahead_reader_buffer :: proc(lr: ^Lookahead_Reader) -> []byte {
return lr.buf[:lr.n]
}
@@ -28,7 +28,7 @@ lookahead_reader_buffer :: proc(lr: ^Loadahead_Reader) -> []byte {
// lookahead_reader_peek returns a slice of the Lookahead_Reader which holds n bytes
// If the Lookahead_Reader cannot hold enough bytes, it will read from the underlying reader to populate the rest.
// NOTE: The returned buffer is not a copy of the underlying buffer
lookahead_reader_peek :: proc(lr: ^Loadahead_Reader, n: int) -> ([]byte, io.Error) {
lookahead_reader_peek :: proc(lr: ^Lookahead_Reader, n: int) -> ([]byte, io.Error) {
switch {
case n < 0:
return nil, .Negative_Read
@@ -58,13 +58,13 @@ lookahead_reader_peek :: proc(lr: ^Loadahead_Reader, n: int) -> ([]byte, io.Erro
// lookahead_reader_peek_all returns a slice of the Lookahead_Reader populating the full buffer
// If the Lookahead_Reader cannot hold enough bytes, it will read from the underlying reader to populate the rest.
// NOTE: The returned buffer is not a copy of the underlying buffer
lookahead_reader_peek_all :: proc(lr: ^Loadahead_Reader) -> ([]byte, io.Error) {
lookahead_reader_peek_all :: proc(lr: ^Lookahead_Reader) -> ([]byte, io.Error) {
return lookahead_reader_peek(lr, len(lr.buf))
}
// lookahead_reader_consume drops the first n populated bytes from the Lookahead_Reader.
lookahead_reader_consume :: proc(lr: ^Loadahead_Reader, n: int) -> io.Error {
lookahead_reader_consume :: proc(lr: ^Lookahead_Reader, n: int) -> io.Error {
switch {
case n == 0:
return nil
@@ -78,6 +78,6 @@ lookahead_reader_consume :: proc(lr: ^Loadahead_Reader, n: int) -> io.Error {
return nil
}
lookahead_reader_consume_all :: proc(lr: ^Loadahead_Reader) -> io.Error {
lookahead_reader_consume_all :: proc(lr: ^Lookahead_Reader) -> io.Error {
return lookahead_reader_consume(lr, lr.n)
}

View File

@@ -227,6 +227,14 @@ writer_to_stream :: proc(b: ^Writer) -> (s: io.Stream) {
return
}
// writer_to_stream converts a Writer into an io.Stream
writer_to_writer :: proc(b: ^Writer) -> (s: io.Writer) {
s.stream_data = b
s.stream_vtable = &_writer_vtable
return
}
@(private)

View File

@@ -441,7 +441,7 @@ opt_write_start :: proc(w: io.Writer, opt: ^Marshal_Options, c: byte) -> (err: i
return
}
// insert comma seperation and write indentations
// insert comma separation and write indentations
opt_write_iteration :: proc(w: io.Writer, opt: ^Marshal_Options, iteration: int) -> (err: io.Error) {
switch opt.spec {
case .JSON, .JSON5:
@@ -461,7 +461,7 @@ opt_write_iteration :: proc(w: io.Writer, opt: ^Marshal_Options, iteration: int)
if opt.pretty {
io.write_byte(w, '\n') or_return
} else {
// comma seperation necessary for non pretty output!
// comma separation necessary for non pretty output!
io.write_string(w, ", ") or_return
}
}

View File

@@ -4,29 +4,59 @@ package fmt
import "core:runtime"
import "core:os"
import "core:io"
import "core:bufio"
// fprint formats using the default print settings and writes to fd
fprint :: proc(fd: os.Handle, args: ..any, sep := " ") -> int {
w := io.to_writer(os.stream_from_handle(fd))
buf: [1024]byte
b: bufio.Writer
defer bufio.writer_flush(&b)
bufio.writer_init_with_buf(&b, {os.stream_from_handle(fd)}, buf[:])
w := bufio.writer_to_writer(&b)
return wprint(w=w, args=args, sep=sep)
}
// fprintln formats using the default print settings and writes to fd
fprintln :: proc(fd: os.Handle, args: ..any, sep := " ") -> int {
w := io.to_writer(os.stream_from_handle(fd))
buf: [1024]byte
b: bufio.Writer
defer bufio.writer_flush(&b)
bufio.writer_init_with_buf(&b, {os.stream_from_handle(fd)}, buf[:])
w := bufio.writer_to_writer(&b)
return wprintln(w=w, args=args, sep=sep)
}
// fprintf formats according to the specified format string and writes to fd
fprintf :: proc(fd: os.Handle, fmt: string, args: ..any) -> int {
w := io.to_writer(os.stream_from_handle(fd))
buf: [1024]byte
b: bufio.Writer
defer bufio.writer_flush(&b)
bufio.writer_init_with_buf(&b, {os.stream_from_handle(fd)}, buf[:])
w := bufio.writer_to_writer(&b)
return wprintf(w, fmt, ..args)
}
fprint_type :: proc(fd: os.Handle, info: ^runtime.Type_Info) -> (n: int, err: io.Error) {
w := io.to_writer(os.stream_from_handle(fd))
buf: [1024]byte
b: bufio.Writer
defer bufio.writer_flush(&b)
bufio.writer_init_with_buf(&b, {os.stream_from_handle(fd)}, buf[:])
w := bufio.writer_to_writer(&b)
return wprint_type(w, info)
}
fprint_typeid :: proc(fd: os.Handle, id: typeid) -> (n: int, err: io.Error) {
w := io.to_writer(os.stream_from_handle(fd))
buf: [1024]byte
b: bufio.Writer
defer bufio.writer_flush(&b)
bufio.writer_init_with_buf(&b, {os.stream_from_handle(fd)}, buf[:])
w := bufio.writer_to_writer(&b)
return wprint_typeid(w, id)
}

View File

@@ -353,14 +353,14 @@ internal_int_is_prime :: proc(a: ^Int, miller_rabin_trials := int(-1), miller_ra
// Run the Miller-Rabin test with base 2 for the BPSW test.
internal_set(b, 2) or_return
if !internal_int_prime_miller_rabin(a, b) or_return { return }
if !(internal_int_prime_miller_rabin(a, b) or_return) { return }
// Rumours have it that Mathematica does a second M-R test with base 3.
// Other rumours have it that their strong L-S test is slightly different.
// It does not hurt, though, beside a bit of extra runtime.
b.digit[0] += 1
if !internal_int_prime_miller_rabin(a, b) or_return { return }
if !(internal_int_prime_miller_rabin(a, b) or_return) { return }
// Both, the Frobenius-Underwood test and the the Lucas-Selfridge test are quite
// slow so if speed is an issue, set `USE_MILLER_RABIN_ONLY` to use M-R tests with
@@ -369,9 +369,9 @@ internal_int_is_prime :: proc(a: ^Int, miller_rabin_trials := int(-1), miller_ra
if !miller_rabin_only {
if miller_rabin_trials >= 0 {
when MATH_BIG_USE_FROBENIUS_TEST {
if !internal_int_prime_frobenius_underwood(a) or_return { return }
if !(internal_int_prime_frobenius_underwood(a) or_return) { return }
} else {
if !internal_int_prime_strong_lucas_selfridge(a) or_return { return }
if !(internal_int_prime_strong_lucas_selfridge(a) or_return) { return }
}
}
}
@@ -410,7 +410,7 @@ internal_int_is_prime :: proc(a: ^Int, miller_rabin_trials := int(-1), miller_ra
// We did bases 2 and 3 already, skip them
for ix := 2; ix < p_max; ix += 1 {
internal_set(b, _private_prime_table[ix])
if !internal_int_prime_miller_rabin(a, b) or_return { return }
if !(internal_int_prime_miller_rabin(a, b) or_return) { return }
}
} else if miller_rabin_trials > 0 {
// Perform `miller_rabin_trials` M-R tests with random bases between 3 and "a".
@@ -490,7 +490,7 @@ internal_int_is_prime :: proc(a: ^Int, miller_rabin_trials := int(-1), miller_ra
ix -= 1
continue
}
if !internal_int_prime_miller_rabin(a, b) or_return { return }
if !(internal_int_prime_miller_rabin(a, b) or_return) { return }
}
}

View File

@@ -3,20 +3,21 @@ package linalg
import "core:builtin"
import "core:math"
radians :: proc(degrees: $T) -> (out: T) where IS_NUMERIC(ELEM_TYPE(T)) {
to_radians :: proc(degrees: $T) -> (out: T) where IS_NUMERIC(ELEM_TYPE(T)) {
when IS_ARRAY(T) {
for i in 0..<len(T) {
out[i] = degrees * RAD_PER_DEG
out[i] = degrees[i] * RAD_PER_DEG
}
} else {
out = degrees * RAD_PER_DEG
}
return
}
degrees :: proc(radians: $T) -> (out: T) where IS_NUMERIC(ELEM_TYPE(T)) {
to_degrees :: proc(radians: $T) -> (out: T) where IS_NUMERIC(ELEM_TYPE(T)) {
when IS_ARRAY(T) {
for i in 0..<len(T) {
out[i] = radians * DEG_PER_RAD
out[i] = radians[i] * DEG_PER_RAD
}
} else {
out = radians * DEG_PER_RAD

View File

@@ -563,7 +563,7 @@ write_type_writer :: proc(w: io.Writer, ti: ^Type_Info, n_written: ^int = nil) -
case .None: // Ignore
case .Fixed:
io.write_string(w, "#soa[", &n) or_return
io.write_i64(w, i64(info.soa_len), 10 &n) or_return
io.write_i64(w, i64(info.soa_len), 10) or_return
io.write_byte(w, ']', &n) or_return
write_type(w, info.soa_base_type, &n) or_return
return

View File

@@ -71,7 +71,32 @@ Returns:
builder_make_len_cap :: proc(len, cap: int, allocator := context.allocator) -> (res: Builder, err: mem.Allocator_Error) #optional_allocator_error {
return Builder{buf=make([dynamic]byte, len, cap, allocator) or_return }, nil
}
// overload simple `builder_make_*` with or without len / cap parameters
/*
Produces a String Builder
*Allocates Using Provided Allocator*
Example:
import "core:fmt"
import "core:strings"
builder_make_example :: proc() {
sb := strings.builder_make()
strings.write_byte(&sb, 'a')
strings.write_string(&sb, " slice of ")
strings.write_f64(&sb, 3.14,'g',true) // See `fmt.fmt_float` byte codes
strings.write_string(&sb, " is ")
strings.write_int(&sb, 180)
strings.write_rune(&sb,'°')
the_string :=strings.to_string(sb)
fmt.println(the_string)
}
Output:
a slice of +3.14 is 180°
*/
builder_make :: proc{
builder_make_none,
builder_make_len,

View File

@@ -263,7 +263,7 @@ compare :: proc(lhs, rhs: string) -> (result: int) {
return mem.compare(transmute([]byte)lhs, transmute([]byte)rhs)
}
/*
Returns the byte offset of the rune `r` in the string `s`, -1 when not found
Checks if rune `r` in the string `s`
Inputs:
- s: The input string

View File

@@ -38,6 +38,7 @@ foreign user32 {
DestroyWindow :: proc(hWnd: HWND) -> BOOL ---
ShowWindow :: proc(hWnd: HWND, nCmdShow: c_int) -> BOOL ---
IsWindow :: proc(hWnd: HWND) -> BOOL ---
BringWindowToTop :: proc(hWnd: HWND) -> BOOL ---
GetTopWindow :: proc(hWnd: HWND) -> HWND ---
SetForegroundWindow :: proc(hWnd: HWND) -> BOOL ---

View File

@@ -1688,6 +1688,8 @@ gb_internal bool check_unary_op(CheckerContext *c, Operand *o, Token op) {
if (is_type_integer(type)) {
error_line("\tSuggestion: Did you mean to use the bitwise not operator '~'?\n");
}
} else {
o->type = t_untyped_bool;
}
break;

View File

@@ -378,6 +378,17 @@ gb_internal void add_polymorphic_record_entity(CheckerContext *ctx, Ast *node, T
rw_mutex_unlock(&ctx->info->gen_types_mutex);
}
bool check_constant_parameter_value(Type *type, Ast *expr) {
if (!is_type_constant_type(type)) {
gbString str = type_to_string(type);
defer (gb_string_free(str));
error(expr, "A parameter must be a valid constant type, got %s", str);
return true;
}
return false;
}
gb_internal Type *check_record_polymorphic_params(CheckerContext *ctx, Ast *polymorphic_params,
bool *is_polymorphic_,
Ast *node, Array<Operand> *poly_operands) {
@@ -477,10 +488,8 @@ gb_internal Type *check_record_polymorphic_params(CheckerContext *ctx, Ast *poly
type = t_invalid;
}
if (!is_type_param && !is_type_constant_type(type)) {
gbString str = type_to_string(type);
error(params[i], "A parameter must be a valid constant type, got %s", str);
gb_string_free(str);
if (!is_type_param && check_constant_parameter_value(type, params[i])) {
// failed
}
Scope *scope = ctx->scope;
@@ -1757,10 +1766,8 @@ gb_internal Type *check_get_params(CheckerContext *ctx, Scope *scope, Ast *_para
p->flags &= ~FieldFlag_by_ptr;
}
if (!is_type_constant_type(type) && !is_type_polymorphic(type)) {
gbString str = type_to_string(type);
error(params[i], "A parameter must be a valid constant type, got %s", str);
gb_string_free(str);
if (!is_type_polymorphic(type) && check_constant_parameter_value(type, params[i])) {
// failed
}
param = alloc_entity_const_param(scope, name->Ident.token, type, poly_const, is_type_polymorphic(type));

View File

@@ -436,6 +436,32 @@ gb_internal void syntax_error_va(TokenPos const &pos, TokenPos end, char const *
}
}
gb_internal void syntax_error_with_verbose_va(TokenPos const &pos, TokenPos end, char const *fmt, va_list va) {
global_error_collector.count.fetch_add(1);
mutex_lock(&global_error_collector.mutex);
// NOTE(bill): Duplicate error, skip it
if (pos.line == 0) {
error_out_coloured("Syntax_Error: ", TerminalStyle_Normal, TerminalColour_Red);
error_out_va(fmt, va);
error_out("\n");
} else if (global_error_collector.prev != pos) {
global_error_collector.prev = pos;
error_out_pos(pos);
if (has_ansi_terminal_colours()) {
error_out_coloured("Syntax_Error: ", TerminalStyle_Normal, TerminalColour_Red);
}
error_out_va(fmt, va);
error_out("\n");
show_error_on_line(pos, end);
}
mutex_unlock(&global_error_collector.mutex);
if (global_error_collector.count > MAX_ERROR_COLLECTOR_COUNT()) {
gb_exit(1);
}
}
gb_internal void syntax_warning_va(TokenPos const &pos, TokenPos end, char const *fmt, va_list va) {
if (global_warnings_as_errors()) {
syntax_error_va(pos, end, fmt, va);
@@ -515,6 +541,14 @@ gb_internal void syntax_warning(Token const &token, char const *fmt, ...) {
va_end(va);
}
gb_internal void syntax_error_with_verbose(TokenPos pos, TokenPos end, char const *fmt, ...) {
va_list va;
va_start(va, fmt);
syntax_error_with_verbose_va(pos, end, fmt, va);
va_end(va);
}
gb_internal void compiler_error(char const *fmt, ...) {
va_list va;

View File

@@ -514,6 +514,9 @@ gb_internal bool lb_is_matrix_simdable(Type *t) {
// it's not aligned well enough to use the vector instructions
return false;
}
if ((mt->Matrix.row_count & 1) ^ (mt->Matrix.column_count & 1)) {
return false;
}
if (elem->kind == Type_Basic) {
switch (elem->Basic.kind) {
@@ -2833,7 +2836,7 @@ gb_internal lbValue lb_make_soa_pointer(lbProcedure *p, Type *type, lbValue cons
lbValue ptr = lb_emit_struct_ep(p, v.addr, 0);
lbValue idx = lb_emit_struct_ep(p, v.addr, 1);
lb_emit_store(p, ptr, addr);
lb_emit_store(p, idx, index);
lb_emit_store(p, idx, lb_emit_conv(p, index, t_int));
return lb_addr_load(p, v);
}

View File

@@ -418,6 +418,25 @@ gb_internal void error(Ast *node, char const *fmt, ...) {
}
}
gb_internal void syntax_error_with_verbose(Ast *node, char const *fmt, ...) {
Token token = {};
TokenPos end_pos = {};
if (node != nullptr) {
token = ast_token(node);
end_pos = ast_end_pos(node);
}
va_list va;
va_start(va, fmt);
syntax_error_with_verbose_va(token.pos, end_pos, fmt, va);
va_end(va);
if (node != nullptr && node->file_id != 0) {
AstFile *f = node->thread_safe_file();
f->error_count += 1;
}
}
gb_internal void error_no_newline(Ast *node, char const *fmt, ...) {
Token token = {};
if (node != nullptr) {
@@ -496,11 +515,17 @@ gb_internal Ast *ast_tag_expr(AstFile *f, Token token, Token name, Ast *expr) {
gb_internal Ast *ast_unary_expr(AstFile *f, Token op, Ast *expr) {
Ast *result = alloc_ast_node(f, Ast_UnaryExpr);
if (expr && expr->kind == Ast_OrReturnExpr) {
syntax_error_with_verbose(expr, "'or_return' within an unary expression not wrapped in parentheses (...)");
}
result->UnaryExpr.op = op;
result->UnaryExpr.expr = expr;
return result;
}
gb_internal Ast *ast_binary_expr(AstFile *f, Token op, Ast *left, Ast *right) {
Ast *result = alloc_ast_node(f, Ast_BinaryExpr);
@@ -513,6 +538,13 @@ gb_internal Ast *ast_binary_expr(AstFile *f, Token op, Ast *left, Ast *right) {
right = ast_bad_expr(f, op, op);
}
if (left->kind == Ast_OrReturnExpr) {
syntax_error_with_verbose(left, "'or_return' within a binary expression not wrapped in parentheses (...)");
}
if (right->kind == Ast_OrReturnExpr) {
syntax_error_with_verbose(right, "'or_return' within a binary expression not wrapped in parentheses (...)");
}
result->BinaryExpr.op = op;
result->BinaryExpr.left = left;
result->BinaryExpr.right = right;
@@ -2765,6 +2797,12 @@ gb_internal Ast *parse_call_expr(AstFile *f, Ast *operand) {
return call;
}
gb_internal void parse_check_or_return(Ast *operand, char const *msg) {
if (operand && operand->kind == Ast_OrReturnExpr) {
syntax_error_with_verbose(operand, "'or_return' use within %s is not wrapped in parentheses (...)", msg);
}
}
gb_internal Ast *parse_atom_expr(AstFile *f, Ast *operand, bool lhs) {
if (operand == nullptr) {
if (f->allow_type) return nullptr;
@@ -2778,6 +2816,7 @@ gb_internal Ast *parse_atom_expr(AstFile *f, Ast *operand, bool lhs) {
while (loop) {
switch (f->curr_token.kind) {
case Token_OpenParen:
parse_check_or_return(operand, "call expression");
operand = parse_call_expr(f, operand);
break;
@@ -2785,12 +2824,11 @@ gb_internal Ast *parse_atom_expr(AstFile *f, Ast *operand, bool lhs) {
Token token = advance_token(f);
switch (f->curr_token.kind) {
case Token_Ident:
parse_check_or_return(operand, "selector expression");
operand = ast_selector_expr(f, token, operand, parse_ident(f));
break;
// case Token_Integer:
// operand = ast_selector_expr(f, token, operand, parse_expr(f, lhs));
// break;
case Token_OpenParen: {
parse_check_or_return(operand, "type assertion");
Token open = expect_token(f, Token_OpenParen);
Ast *type = parse_type(f);
Token close = expect_token(f, Token_CloseParen);
@@ -2798,6 +2836,7 @@ gb_internal Ast *parse_atom_expr(AstFile *f, Ast *operand, bool lhs) {
} break;
case Token_Question: {
parse_check_or_return(operand, ".? based type assertion");
Token question = expect_token(f, Token_Question);
Ast *type = ast_unary_expr(f, question, nullptr);
operand = ast_type_assertion(f, operand, token, type);
@@ -2813,6 +2852,7 @@ gb_internal Ast *parse_atom_expr(AstFile *f, Ast *operand, bool lhs) {
} break;
case Token_ArrowRight: {
parse_check_or_return(operand, "-> based call expression");
Token token = advance_token(f);
operand = ast_selector_expr(f, token, operand, parse_ident(f));
@@ -2870,11 +2910,14 @@ gb_internal Ast *parse_atom_expr(AstFile *f, Ast *operand, bool lhs) {
if (indices[0] == nullptr || indices[1] == nullptr) {
syntax_error(open, "Matrix index expressions require both row and column indices");
}
parse_check_or_return(operand, "matrix index expression");
operand = ast_matrix_index_expr(f, operand, open, close, interval, indices[0], indices[1]);
} else {
parse_check_or_return(operand, "slice expression");
operand = ast_slice_expr(f, operand, open, close, interval, indices[0], indices[1]);
}
} else {
parse_check_or_return(operand, "index expression");
operand = ast_index_expr(f, operand, indices[0], open, close);
}
@@ -2882,6 +2925,7 @@ gb_internal Ast *parse_atom_expr(AstFile *f, Ast *operand, bool lhs) {
} break;
case Token_Pointer: // Deference
parse_check_or_return(operand, "dereference");
operand = ast_deref_expr(f, operand, expect_token(f, Token_Pointer));
break;

View File

@@ -27,4 +27,34 @@ Notification_object :: proc(self: ^Notification) -> ^Object {
@(objc_type=Notification, objc_name="userInfo")
Notification_userInfo :: proc(self: ^Notification) -> ^Dictionary {
return msgSend(^Dictionary, self, "userInfo")
}
NotificationName :: ^String
@(objc_class="NSNotificationCenter")
NotificationCenter :: struct{using _: Object}
@(objc_type=NotificationCenter, objc_name="alloc", objc_is_class_method=true)
NotificationCenter_alloc :: proc() -> ^NotificationCenter {
return msgSend(^NotificationCenter, NotificationCenter, "alloc")
}
@(objc_type=NotificationCenter, objc_name="init")
NotificationCenter_init :: proc(self: ^NotificationCenter) -> ^NotificationCenter {
return msgSend(^NotificationCenter, self, "init")
}
@(objc_type=NotificationCenter, objc_name="defaultCenter", objc_is_class_method=true)
NotificationCenter_defaultCenter :: proc() -> ^NotificationCenter {
return msgSend(^NotificationCenter, NotificationCenter, "defaultCenter")
}
@(objc_type=NotificationCenter, objc_name="addObserver")
NotificationCenter_addObserverName :: proc(self: ^NotificationCenter, name: NotificationName, pObj: ^Object, pQueue: rawptr, block: ^Block) -> ^Object {
return msgSend(^Object, self, "addObserverName:object:queue:block:", name, pObj, pQueue, block)
}
@(objc_type=NotificationCenter, objc_name="removeObserver")
NotificationCenter_removeObserver :: proc(self: ^NotificationCenter, pObserver: ^Object) {
msgSend(nil, self, "removeObserver:", pObserver)
}

File diff suppressed because it is too large Load Diff

View File

@@ -17,6 +17,14 @@ AccelerationStructureInstanceOption :: enum u32 {
NonOpaque = 3,
}
AccelerationStructureRefitOptions :: distinct bit_set[AccelerationStructureRefitOption; NS.UInteger]
AccelerationStructureRefitOption :: enum NS.UInteger {
VertexData = 0,
PerPrimitiveData = 1,
}
MotionBorderMode :: enum u32 {
Clamp = 0,
Vanish = 1,
@@ -148,6 +156,21 @@ BinaryArchiveError :: enum NS.UInteger {
InvalidFile = 1,
UnexpectedElement = 2,
CompilationFailure = 3,
InternalError = 4,
}
BindingType :: enum NS.Integer {
Buffer = 0,
ThreadgroupMemory = 1,
Texture = 2,
Sampler = 3,
ImageblockData = 16,
Imageblock = 17,
VisibleFunctionTable = 24,
PrimitiveAccelerationStructure = 25,
InstanceAccelerationStructure = 26,
IntersectionFunctionTable = 27,
ObjectPayload = 34,
}
BlitOptionFlag :: enum NS.UInteger {
@@ -171,15 +194,16 @@ CaptureDestination :: enum NS.Integer {
CommandBufferStatus :: enum NS.UInteger {
NotEnqueued = 0,
Enqueued = 1,
Committed = 2,
Scheduled = 3,
Completed = 4,
Error = 5,
Enqueued = 1,
Committed = 2,
Scheduled = 3,
Completed = 4,
Error = 5,
}
CommandBufferError :: enum NS.UInteger {
None = 0,
Internal = 1,
Timeout = 2,
PageFault = 3,
AccessRevoked = 4,
@@ -232,6 +256,7 @@ BarrierScope :: distinct bit_set[BarrierScopeFlag; NS.UInteger]
CounterSampleBufferError :: enum NS.Integer {
OutOfMemory = 0,
Invalid = 1,
Internal = 2,
}
CompareFunction :: enum NS.UInteger {
@@ -312,6 +337,13 @@ GPUFamily :: enum NS.Integer {
Common3 = 3003,
MacCatalyst1 = 4001,
MacCatalyst2 = 4002,
Metal3 = 5001,
}
SparsePageSize :: enum NS.Integer {
Size16 = 101,
Size64 = 102,
Size256 = 103,
}
DeviceLocation :: enum NS.UInteger {
@@ -409,6 +441,9 @@ FunctionType :: enum NS.UInteger {
Kernel = 3,
Visible = 5,
Intersection = 6,
Mesh = 7,
Object = 8,
}
@@ -421,15 +456,22 @@ LanguageVersion :: enum NS.UInteger {
Version2_2 = 131074,
Version2_3 = 131075,
Version2_4 = 131076,
Version3_0 = 196608,
}
LibraryType :: enum NS.Integer {
Executable = 0,
Dynamic = 1,
Dynamic = 1,
}
LibraryOptimizationLevel :: enum NS.Integer {
Default = 0,
Size = 1,
}
LibraryError :: enum NS.UInteger {
Unsupported = 1,
Internal = 2,
CompileFailure = 3,
CompileWarning = 4,
FunctionNotFound = 5,
@@ -624,6 +666,8 @@ RenderStage :: enum NS.UInteger {
Vertex = 0,
Fragment = 1,
Tile = 2,
Object = 3,
Mesh = 4,
}
RenderStages :: distinct bit_set[RenderStage; NS.UInteger]
@@ -861,6 +905,42 @@ IndexType :: enum NS.UInteger {
UInt32 = 1,
}
IOPriority :: enum NS.Integer {
High = 0,
Normal = 1,
Low = 2,
}
IOCommandQueueType :: enum NS.Integer {
Concurrent = 0,
Serial = 1,
}
IOError :: enum NS.Integer {
URLInvalid = 1,
Internal = 2,
}
IOStatus :: enum NS.Integer {
Pending = 0,
Cancelled = 1,
Error = 2,
Complete = 3,
}
IOCompressionMethod :: enum NS.Integer {
Zlib = 0,
LZFSE = 1,
LZ4 = 2,
LZMA = 3,
LZBitmap = 4,
}
IOCompressionStatus :: enum NS.Integer {
Complete = 0,
Error = 1,
}
StepFunction :: enum NS.UInteger {
Constant = 0,
PerVertex = 1,

View File

@@ -4,9 +4,11 @@ import NS "vendor:darwin/Foundation"
foreign import "system:Metal.framework"
CommonCounter :: ^NS.String
CommonCounterSet :: ^NS.String
CommonCounter :: ^NS.String
CommonCounterSet :: ^NS.String
DeviceNotificationName :: ^NS.String
ErrorUserInfoKey :: ^NS.ErrorUserInfoKey
ErrorDomain :: ^NS.ErrorDomain
foreign Metal {
@(linkage="weak") CommonCounterTimestamp: CommonCounter
@@ -36,4 +38,12 @@ foreign Metal {
@(linkage="weak") DeviceWasAddedNotification: DeviceNotificationName
@(linkage="weak") DeviceRemovalRequestedNotification: DeviceNotificationName
@(linkage="weak") DeviceWasRemovedNotification: DeviceNotificationName
}
foreign Metal {
@(linkage="weak") CommandBufferEncoderInfoErrorKey: ErrorUserInfoKey
}
foreign Metal {
@(linkage="weak") IOErrorDomain: ErrorDomain
}

View File

@@ -1,6 +1,7 @@
package objc_Metal
import NS "vendor:darwin/Foundation"
import "core:c"
@(require)
foreign import "system:Metal.framework"
@@ -11,6 +12,12 @@ foreign Metal {
CopyAllDevicesWithObserver :: proc(observer: ^id, handler: DeviceNotificationHandler) -> ^NS.Array ---
CreateSystemDefaultDevice :: proc() -> ^Device ---
RemoveDeviceObserver :: proc(observer: id) ---
IOCompressionContextDefaultChunkSize :: proc() -> c.size_t ---
IOCreateCompressionContext :: proc(path: cstring, type: IOCompressionMethod, chuckSize: c.size_t) -> rawptr ---
IOCompressionContextAppendData :: proc(ctx: rawptr, data: rawptr, size: c.size_t) ---
IOFlushAndDestroyCompressionContext :: proc(ctx: rawptr) -> IOCompressionStatus ---
}

View File

@@ -133,6 +133,8 @@ Region :: struct {
SamplePosition :: distinct [2]f32
ResourceID :: distinct u64
ScissorRect :: struct {
x: NS.Integer,
y: NS.Integer,

View File

@@ -56,6 +56,17 @@ MetalLayer_setFramebufferOnly :: proc(self: ^MetalLayer, ok: NS.BOOL) {
msgSend(nil, self, "setFramebufferOnly:", ok)
}
@(objc_type=MetalLayer, objc_name="drawableSize")
MetalLayer_drawableSize :: proc(self: ^MetalLayer) -> NS.Size {
return msgSend(NS.Size, self, "drawableSize")
}
@(objc_type=MetalLayer, objc_name="setDrawableSize")
MetalLayer_setDrawableSize :: proc(self: ^MetalLayer, drawableSize: NS.Size) {
msgSend(nil, self, "setDrawableSize:", drawableSize)
}
@(objc_type=MetalLayer, objc_name="frame")
MetalLayer_frame :: proc(self: ^MetalLayer) -> NS.Rect {
return msgSend(NS.Rect, self, "frame")

View File

@@ -26,13 +26,11 @@ import "core:c"
import "core:intrinsics"
when ODIN_OS == .Windows {
foreign import _lib "SDL2.lib"
foreign import lib "SDL2.lib"
} else {
foreign import _lib "system:SDL2"
foreign import lib "system:SDL2"
}
lib :: _lib
version :: struct {
major: u8, /**< major version */
minor: u8, /**< minor version */
@@ -47,6 +45,7 @@ PATCHLEVEL :: 16
foreign lib {
GetVersion :: proc(ver: ^version) ---
GetRevision :: proc() -> cstring ---
}
InitFlag :: enum u32 {

View File

@@ -2,6 +2,12 @@ package sdl2
import "core:c"
when ODIN_OS == .Windows {
foreign import lib "SDL2.lib"
} else {
foreign import lib "system:SDL2"
}
/**
* \brief Audio format flags.
*

View File

@@ -2,6 +2,12 @@ package sdl2
import "core:c"
when ODIN_OS == .Windows {
foreign import lib "SDL2.lib"
} else {
foreign import lib "system:SDL2"
}
/**
* \brief The blend mode used in SDL_RenderCopy() and drawing operations.
*/

View File

@@ -2,6 +2,12 @@ package sdl2
import "core:c"
when ODIN_OS == .Windows {
foreign import lib "SDL2.lib"
} else {
foreign import lib "system:SDL2"
}
/* This is a guess for the cacheline size used for padding.
* Most x86 processors have a 64 byte cache line.
* The 64-bit PowerPC processors have a 128 byte cache line.

View File

@@ -2,6 +2,12 @@ package sdl2
import "core:c"
when ODIN_OS == .Windows {
foreign import lib "SDL2.lib"
} else {
foreign import lib "system:SDL2"
}
RELEASED :: 0
PRESSED :: 1

View File

@@ -2,6 +2,12 @@ package sdl2
import "core:c"
when ODIN_OS == .Windows {
foreign import lib "SDL2.lib"
} else {
foreign import lib "system:SDL2"
}
GameController :: struct {}
GameControllerType :: enum c.int {

View File

@@ -2,6 +2,12 @@ package sdl2
import "core:c"
when ODIN_OS == .Windows {
foreign import lib "SDL2.lib"
} else {
foreign import lib "system:SDL2"
}
// Gesture
GestureID :: distinct i64

View File

@@ -2,6 +2,12 @@ package sdl2
import "core:c"
when ODIN_OS == .Windows {
foreign import lib "SDL2.lib"
} else {
foreign import lib "system:SDL2"
}
HINT_ACCELEROMETER_AS_JOYSTICK :: "SDL_ACCELEROMETER_AS_JOYSTICK"
HINT_ALLOW_ALT_TAB_WHILE_GRABBED :: "SDL_ALLOW_ALT_TAB_WHILE_GRABBED"
HINT_ALLOW_TOPMOST :: "SDL_ALLOW_TOPMOST"

View File

@@ -2,6 +2,12 @@ package sdl2
import "core:c"
when ODIN_OS == .Windows {
foreign import lib "SDL2.lib"
} else {
foreign import lib "system:SDL2"
}
Joystick :: struct {}
JoystickGUID :: struct {

View File

@@ -2,6 +2,12 @@ package sdl2
import "core:c"
when ODIN_OS == .Windows {
foreign import lib "SDL2.lib"
} else {
foreign import lib "system:SDL2"
}
Keysym :: struct {
scancode: Scancode, /**< SDL physical key code - see ::SDL_Scancode for details */
sym: Keycode, /**< SDL virtual key code - see ::SDL_Keycode for details */

View File

@@ -1,5 +1,6 @@
package sdl2
SCANCODE_MASK :: 1<<30
SCANCODE_TO_KEYCODE :: #force_inline proc "c" (X: Scancode) -> Keycode {
return Keycode(i32(X) | SCANCODE_MASK)

View File

@@ -2,6 +2,12 @@ package sdl2
import "core:c"
when ODIN_OS == .Windows {
foreign import lib "SDL2.lib"
} else {
foreign import lib "system:SDL2"
}
MAX_LOG_MESSAGE :: 4096
LogCategory :: enum c.int {

View File

@@ -2,6 +2,12 @@ package sdl2
import "core:c"
when ODIN_OS == .Windows {
foreign import lib "SDL2.lib"
} else {
foreign import lib "system:SDL2"
}
MessageBoxFlag :: enum u32 {
_ = 0,
ERROR = 4, /**< error dialog */

View File

@@ -2,6 +2,12 @@ package sdl2
import "core:c"
when ODIN_OS == .Windows {
foreign import lib "SDL2.lib"
} else {
foreign import lib "system:SDL2"
}
MetalView :: distinct rawptr
@(default_calling_convention="c", link_prefix="SDL_")

View File

@@ -2,6 +2,12 @@ package sdl2
import "core:c"
when ODIN_OS == .Windows {
foreign import lib "SDL2.lib"
} else {
foreign import lib "system:SDL2"
}
Cursor :: struct {}
BUTTON :: #force_inline proc "c" (X: c.int) -> c.int { return 1 << u32(X-1) }

View File

@@ -2,6 +2,12 @@ package sdl2
import "core:c"
when ODIN_OS == .Windows {
foreign import lib "SDL2.lib"
} else {
foreign import lib "system:SDL2"
}
MUTEX_TIMEDOUT :: 1
MUTEX_MAXWAIT :: ~u32(0)

View File

@@ -2,6 +2,12 @@ package sdl2
import "core:c"
when ODIN_OS == .Windows {
foreign import lib "SDL2.lib"
} else {
foreign import lib "system:SDL2"
}
ALPHA_OPAQUE :: 255
ALPHA_TRANSPARENT :: 0

View File

@@ -2,6 +2,12 @@ package sdl2
import "core:c"
when ODIN_OS == .Windows {
foreign import lib "SDL2.lib"
} else {
foreign import lib "system:SDL2"
}
Point :: struct {
x: c.int,
y: c.int,

View File

@@ -2,6 +2,12 @@ package sdl2
import "core:c"
when ODIN_OS == .Windows {
foreign import lib "SDL2.lib"
} else {
foreign import lib "system:SDL2"
}
RendererFlag :: enum u32 {
SOFTWARE = 0, /**< The renderer is a software fallback */
ACCELERATED = 1, /**< The renderer uses hardware acceleration */

View File

@@ -2,6 +2,12 @@ package sdl2
import "core:c"
when ODIN_OS == .Windows {
foreign import lib "SDL2.lib"
} else {
foreign import lib "system:SDL2"
}
/* RWops Types */
RWOPS_UNKNOWN :: 0 /**< Unknown stream type */
RWOPS_WINFILE :: 1 /**< Win32 file */

View File

@@ -5,6 +5,12 @@ import "core:intrinsics"
import "core:runtime"
_, _ :: intrinsics, runtime
when ODIN_OS == .Windows {
foreign import lib "SDL2.lib"
} else {
foreign import lib "system:SDL2"
}
bool :: distinct b32
#assert(size_of(bool) == size_of(c.int))

View File

@@ -2,6 +2,12 @@ package sdl2
import "core:c"
when ODIN_OS == .Windows {
foreign import lib "SDL2.lib"
} else {
foreign import lib "system:SDL2"
}
SWSURFACE :: 0 /**< Just here for compatibility */
PREALLOC :: 0x00000001 /**< Surface uses preallocated memory */
RLEACCEL :: 0x00000002 /**< Surface is RLE encoded */

View File

@@ -2,6 +2,12 @@ package sdl2
import "core:c"
when ODIN_OS == .Windows {
foreign import lib "SDL2.lib"
} else {
foreign import lib "system:SDL2"
}
// General
@(default_calling_convention="c", link_prefix="SDL_")
foreign lib {

View File

@@ -2,6 +2,12 @@ package sdl2
import "core:c"
when ODIN_OS == .Windows {
foreign import lib "SDL2.lib"
} else {
foreign import lib "system:SDL2"
}
SYSWM_TYPE :: enum c.int {
UNKNOWN,
WINDOWS,

View File

@@ -2,6 +2,12 @@ package sdl2
import "core:c"
when ODIN_OS == .Windows {
foreign import lib "SDL2.lib"
} else {
foreign import lib "system:SDL2"
}
Thread :: struct {}
threadID :: distinct c.ulong

View File

@@ -2,6 +2,12 @@ package sdl2
import "core:c"
when ODIN_OS == .Windows {
foreign import lib "SDL2.lib"
} else {
foreign import lib "system:SDL2"
}
TimerCallback :: proc "c" (interval: u32, param: rawptr) -> u32
TimerID :: distinct c.int

View File

@@ -2,6 +2,12 @@ package sdl2
import "core:c"
when ODIN_OS == .Windows {
foreign import lib "SDL2.lib"
} else {
foreign import lib "system:SDL2"
}
TouchID :: distinct i64
FingerID :: distinct i64

View File

@@ -2,6 +2,12 @@ package sdl2
import "core:c"
when ODIN_OS == .Windows {
foreign import lib "SDL2.lib"
} else {
foreign import lib "system:SDL2"
}
DisplayMode :: struct {
format: u32, /**< pixel format */
w: c.int, /**< width, in screen coordinates */

View File

@@ -3,6 +3,12 @@ package sdl2
import "core:c"
import vk "vendor:vulkan"
when ODIN_OS == .Windows {
foreign import lib "SDL2.lib"
} else {
foreign import lib "system:SDL2"
}
VkInstance :: vk.Instance
VkSurfaceKHR :: vk.SurfaceKHR