From: Brendan Hansen Date: Tue, 1 Nov 2022 03:12:15 +0000 (-0500) Subject: various improvements to any utilities X-Git-Url: https://git.brendanfh.com/?a=commitdiff_plain;h=eb29afdac7069c8db6c4168a60f7a672759b6105;p=onyx.git various improvements to any utilities --- diff --git a/compiler/src/astnodes.c b/compiler/src/astnodes.c index e09c9402..a1c15386 100644 --- a/compiler/src/astnodes.c +++ b/compiler/src/astnodes.c @@ -1188,7 +1188,9 @@ b32 cast_is_legal(Type* from_, Type* to_, char** err_msg) { b32 implicit_cast_to_bool(AstTyped **pnode) { AstTyped *node = *pnode; - if (node->type->kind == Type_Kind_Pointer) { + if ((node->type->kind == Type_Kind_Basic && + node->type->Basic.kind == Basic_Kind_Rawptr) + || (node->type->kind == Type_Kind_Pointer)) { AstNumLit *zero = make_int_literal(context.ast_alloc, 0); zero->type = &basic_types[Basic_Kind_Rawptr]; diff --git a/core/misc/any_utils.onyx b/core/misc/any_utils.onyx index 84b51f7f..53551454 100644 --- a/core/misc/any_utils.onyx +++ b/core/misc/any_utils.onyx @@ -4,10 +4,15 @@ use runtime.info { get_type_info, Type_Info_Pointer, Type_Info_Struct, + Type_Info_Array, + Type_Info_Slice, + Type_Info_Dynamic_Array, get_struct_member } +use core { iter, array } + to_any :: macro (x: ^$T) => any.{x, T}; any_as :: (a: any, $T: type_expr) -> ^T { @@ -15,17 +20,32 @@ any_as :: (a: any, $T: type_expr) -> ^T { return cast(^T) a.data; } -any_deference :: (v: any) -> any { +// Dereference an pointer any. +any_dereference :: (v: any) -> any { t := get_type_info(v.type); if t.kind == .Pointer { p := cast(^Type_Info_Pointer) t; return any.{*cast(^rawptr) v.data, p.to}; } - return .{null, void}; + return v; +} + +// Subscript an array-like any. +any_subscript :: (v: any, index: i32) -> any { + base_ptr, elem_type, count := any_as_array(v); + if index >= count || index < 0 { + return .{ null, void }; + } + + return any.{ + cast(^u8) base_ptr + get_type_info(elem_type).size * index, + elem_type + }; } -any_get_member :: (v: any, member_name: str) -> any { +// Select a member from an any. +any_selector :: (v: any, member_name: str) -> any { t := get_type_info(v.type); if t.kind == .Struct { member := get_struct_member(v.type, member_name); @@ -40,7 +60,7 @@ any_get_member :: (v: any, member_name: str) -> any { any_to_map :: (v: any) -> (Map(str, any), success: bool) { vals := v; if get_type_info(vals.type).kind == .Pointer { - vals = any_deference(vals); + vals = any_dereference(vals); } val_info := cast(^Type_Info_Struct) get_type_info(vals.type); @@ -50,9 +70,57 @@ any_to_map :: (v: any) -> (Map(str, any), success: bool) { out: Map(str, any); for ^ val_info.members { - out->put(it.name, any_get_member(vals, it.name)); + out->put(it.name, any_selector(vals, it.name)); } return out, true; } +// Creates an iterator out of an array-like any. +any_iter :: (arr: any) -> Iterator(any) { + base_ptr, elem_type, count := any_as_array(arr); + if count == 0 { + return .{ null, ((_) => any.{}, false) }; + } + + return iter.generator( + ^.{ + base_ptr = base_ptr, + elem_type = elem_type, + elem_size = get_type_info(elem_type).size, + count = count, + index = 0, + }, + + (ctx: $T) -> (any, bool) { + if ctx.index < ctx.count { + defer ctx.index += 1; + return any.{ cast(^u8) ctx.base_ptr + ctx.elem_size * ctx.index, ctx.elem_type }, true; + } + + return .{}, false; + } + ); +} + + +#local +any_as_array :: (arr: any) -> (rawptr, type_expr, u32) { + info := get_type_info(arr.type); + + switch info.kind { + case .Array { + a := cast(^Type_Info_Array) info; + return arr.data, a.of, a.count; + } + + case .Slice, .Dynamic_Array, .Variadic_Argument { + a := cast(^array.Untyped_Array) arr.data; + return a.data, (cast(^Type_Info_Dynamic_Array) info).of, a.count; + } + + case #default { + return null, void, 0; + } + } +} diff --git a/core/std.onyx b/core/std.onyx index 76e445ca..0b2329a6 100644 --- a/core/std.onyx +++ b/core/std.onyx @@ -21,6 +21,7 @@ package core #load "./string" #load "./string/reader" #load "./string/buffer" +#load "./string/char_utils" #load "./intrinsics/onyx" #load "./intrinsics/wasm" diff --git a/core/string/char_utils.onyx b/core/string/char_utils.onyx new file mode 100644 index 00000000..e66669ef --- /dev/null +++ b/core/string/char_utils.onyx @@ -0,0 +1,18 @@ +package core.string + +#inject u8 { + is_alpha :: (c: u8) -> bool { + return (c >= #char "A" && c <= #char "Z") + || (c >= #char "a" && c <= #char "z"); + } + + is_num :: (c: u8) -> bool { + return (c >= #char "0" && c <= #char "9"); + } + + is_alphanum :: (c: u8) -> bool { + return c->is_alpha() || c->is_num(); + } +} + +