mirror of
https://github.com/c3lang/c3c.git
synced 2026-02-27 03:51:18 +00:00
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:
@@ -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;
|
||||
|
||||
@@ -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*;
|
||||
@@ -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());
|
||||
@@ -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;
|
||||
@@ -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>");
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user