string::new_struct_to_str and io::struct_to_format to dump struct data. io::print will now print structs.

This commit is contained in:
Christoffer Lerno
2024-10-26 21:00:07 +02:00
parent cc6a24cf80
commit 4be08ee0bd
6 changed files with 62 additions and 9 deletions

View File

@@ -4,7 +4,7 @@
module std::core::runtime; module std::core::runtime;
import libc, std::time, std::io, std::sort; import libc, std::time, std::io, std::sort;
struct ReflectedParam @if(!$defined(ReflectedParam)) struct ReflectedParam (Printable) @if(!$defined(ReflectedParam))
{ {
String name; String name;
typeid type; typeid type;

View File

@@ -1,5 +1,6 @@
module std::core::string; module std::core::string;
import std::ascii; import std::ascii;
import std::io;
distinct String @if(!$defined(String)) = inline char[]; distinct String @if(!$defined(String)) = inline char[];
distinct ZString = inline char*; distinct ZString = inline char*;
@@ -749,4 +750,15 @@ fn String! Splitter.next(&self)
return remaining; return remaining;
} }
macro String new_struct_to_str(x, Allocator allocator = allocator::heap())
{
DString s;
@stack_mem(512; Allocator mem)
{
s.new_init(allocator: mem);
io::fprint(&s, x)!!;
};
return s.copy_str(allocator);
}
macro String temp_struct_to_str(x) => new_struct_to_str(x, allocator::temp());

View File

@@ -23,6 +23,45 @@ fault PrintFault
def OutputFn = fn void!(void* buffer, char c); def OutputFn = fn void!(void* buffer, char c);
def FloatType = double; def FloatType = double;
macro bool is_struct_with_default_print($Type)
{
return $Type.kindof == STRUCT
&&& !$defined($Type.to_format)
&&& !$defined($Type.to_new_string);
}
<*
Introspect a struct and print it to a formatter
@require @typekind(value) == STRUCT `This macro is only valid on macros`
*>
macro usz! struct_to_format(value, Formatter* f, bool $force_dump)
{
var $Type = $typeof(value);
usz total = f.print("{ ")!;
$foreach ($i, $member : $Type.membersof)
$if $i > 0:
total += f.print(", ")!;
$endif
$if $member.nameof != "":
total += f.printf("%s: ", $member.nameof)!;
$endif
$if ($force_dump &&& $member.typeid.kindof == STRUCT) |||
is_struct_with_default_print($typefrom($member.typeid)):
total += struct_to_format($member.get(value), f, $force_dump)!;
$else
total += f.printf("%s", $member.get(value))!;
$endif
$endforeach
return total + f.print(" }");
}
fn usz! ReflectedParam.to_format(&self, Formatter* f) @dynamic
{
return f.printf("[Parameter '%s']", self.name);
}
fn usz! Formatter.printf(&self, String format, args...) fn usz! Formatter.printf(&self, String format, args...)
{ {
return self.vprintf(format, args) @inline; return self.vprintf(format, args) @inline;
@@ -159,12 +198,6 @@ fn usz! Formatter.out_str(&self, any arg) @private
assert(i < arg.type.names.len, "Illegal enum value found, numerical value was %d.", i); assert(i < arg.type.names.len, "Illegal enum value found, numerical value was %d.", i);
return self.out_substr(arg.type.names[i]); return self.out_substr(arg.type.names[i]);
case STRUCT: case STRUCT:
if (arg.type == ReflectedParam.typeid)
{
ReflectedParam* param = arg.ptr;
return self.out_substr("[Parameter '")
+ self.out_substr(param.name) + self.out_substr("']");
}
return self.out_substr("<struct>"); return self.out_substr("<struct>");
case UNION: case UNION:
return self.out_substr("<union>"); return self.out_substr("<union>");

View File

@@ -121,9 +121,15 @@ macro usz! fprint(out, x)
$default: $default:
$if $assignable(x, String): $if $assignable(x, String):
return out.write((String)x); return out.write((String)x);
$else
$if is_struct_with_default_print($Type):
Formatter formatter;
formatter.init(&out_putstream_fn, &&(OutStream)out);
return struct_to_format(x, &formatter, false);
$else $else
return fprintf(out, "%s", x); return fprintf(out, "%s", x);
$endif $endif
$endif
$endswitch $endswitch
} }

View File

@@ -19,6 +19,8 @@
- Adding constants to the Json AST #1540 - Adding constants to the Json AST #1540
- Adding info to the globals inside Json AST #1541 - Adding info to the globals inside Json AST #1541
- Null-check function pointer invocation #1573. - Null-check function pointer invocation #1573.
- `string::new_struct_to_str` and `io::struct_to_format` to dump struct data.
- `io::print` will now print structs.
### Fixes ### Fixes
- `Unsupported int[*] $x = { 1, 2, 3, 4 }` #1489. - `Unsupported int[*] $x = { 1, 2, 3, 4 }` #1489.

View File

@@ -680,7 +680,7 @@ no_match: ; preds = %compare
!90 = !DIFile(filename: "io.c3" !90 = !DIFile(filename: "io.c3"
!91 = !DILocation(line: 42, column: 7, scope: !78) !91 = !DILocation(line: 42, column: 7, scope: !78)
!92 = !DILocalVariable(name: "len" !92 = !DILocalVariable(name: "len"
!93 = distinct !DISubprogram(name: "fprintn", linkageName: "fprintn", scope: !90, file: !90, line: 166, scopeLine: 166, spFlags: DISPFlagLocalToUnit | DISPFlagDefinition, unit: !5, retainedNodes: !20) !93 = distinct !DISubprogram(name: "fprintn", linkageName: "fprintn", scope: !90
!94 = !DILocation !94 = !DILocation
!95 = !DILocation !95 = !DILocation
!96 = !DILocation !96 = !DILocation