Skip to content

Commit

Permalink
string::new_struct_to_str and io::struct_to_format to dump struct…
Browse files Browse the repository at this point in the history
… data. `io::print` will now print structs.
  • Loading branch information
lerno committed Oct 26, 2024
1 parent cc6a24c commit 4be08ee
Show file tree
Hide file tree
Showing 6 changed files with 62 additions and 9 deletions.
2 changes: 1 addition & 1 deletion lib/std/core/runtime.c3
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
module std::core::runtime;
import libc, std::time, std::io, std::sort;

struct ReflectedParam @if(!$defined(ReflectedParam))
struct ReflectedParam (Printable) @if(!$defined(ReflectedParam))
{
String name;
typeid type;
Expand Down
12 changes: 12 additions & 0 deletions lib/std/core/string.c3
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
module std::core::string;
import std::ascii;
import std::io;

distinct String @if(!$defined(String)) = inline char[];
distinct ZString = inline char*;
Expand Down Expand Up @@ -749,4 +750,15 @@ fn String! Splitter.next(&self)
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());
45 changes: 39 additions & 6 deletions lib/std/io/formatter.c3
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,45 @@ fault PrintFault
def OutputFn = fn void!(void* buffer, char c);
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...)
{
return self.vprintf(format, args) @inline;
Expand Down Expand Up @@ -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);
return self.out_substr(arg.type.names[i]);
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>");
case UNION:
return self.out_substr("<union>");
Expand Down
8 changes: 7 additions & 1 deletion lib/std/io/io.c3
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,13 @@ macro usz! fprint(out, x)
$if $assignable(x, String):
return out.write((String)x);
$else
return fprintf(out, "%s", x);
$if is_struct_with_default_print($Type):
Formatter formatter;
formatter.init(&out_putstream_fn, &&(OutStream)out);
return struct_to_format(x, &formatter, false);
$else
return fprintf(out, "%s", x);
$endif
$endif
$endswitch
}
Expand Down
2 changes: 2 additions & 0 deletions releasenotes.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@
- Adding constants to the Json AST #1540
- Adding info to the globals inside Json AST #1541
- 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
- `Unsupported int[*] $x = { 1, 2, 3, 4 }` #1489.
Expand Down
2 changes: 1 addition & 1 deletion test/test_suite/debug_symbols/defer_macro.c3t
Original file line number Diff line number Diff line change
Expand Up @@ -680,7 +680,7 @@ no_match: ; preds = %compare
!90 = !DIFile(filename: "io.c3"
!91 = !DILocation(line: 42, column: 7, scope: !78)
!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
!95 = !DILocation
!96 = !DILocation
Expand Down

0 comments on commit 4be08ee

Please sign in to comment.