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;
|
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;
|
||||||
|
|||||||
@@ -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());
|
||||||
@@ -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>");
|
||||||
|
|||||||
@@ -122,7 +122,13 @@ macro usz! fprint(out, x)
|
|||||||
$if $assignable(x, String):
|
$if $assignable(x, String):
|
||||||
return out.write((String)x);
|
return out.write((String)x);
|
||||||
$else
|
$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
|
$endif
|
||||||
$endswitch
|
$endswitch
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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.
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
Reference in New Issue
Block a user