1+ import std
2+ import cstd
3+ import reflection
4+ import runtime
5+ import strings
6+
7+ def print_val(file: File, value: *, tpe: reflection::Type) -> int {
8+ //cstd::printf("%.*s\n".value, tpe.name.count, tpe.name.data ++ tpe.name.offset)
9+ if not tpe or not value {
10+ return cstd::fprintf(file, "%p".value, value)
11+ } else if tpe == string {
12+ let str = value !*string
13+ cstd::fputs(str.value, file)
14+ return (str.size - 1) !int
15+ } else if tpe == StringSlice {
16+ let slc = value !*StringSlice
17+ if slc.data {
18+ cstd::fwrite(slc.data ++ slc.offset, 1, slc.count, file)
19+ } else {
20+ let val = @slc
21+ for var i in 0..slc.count {
22+ cstd::putc(val(i), file)
23+ }
24+ }
25+ return slc.count !int
26+ } else if tpe == Str {
27+ let str = value !*Str
28+ cstd::fwrite(get_internal_buffer(str), 1, length(@str), file)
29+ return length(@str) !int
30+ } else if tpe == StringBuffer {
31+ fprint(file, to_string(@(value !*StringBuffer)))
32+ } else if tpe == type *char {
33+ return cstd::fprintf(file, "%s".value, @(value !**char))
34+ } else if tpe == size_t {
35+ return cstd::fprintf(file, "%zu".value, @(value !*size_t))
36+ } else if tpe == char {
37+ return cstd::fprintf(file, "%c".value, @(value !*char))
38+ } else if tpe == int8 {
39+ return cstd::fprintf(file, "%hhd".value, @(value !*int8))
40+ } else if tpe == uint8 {
41+ return cstd::fprintf(file, "%hhu".value, @(value !*uint8))
42+ } else if tpe == int16 {
43+ return cstd::fprintf(file, "%hd".value, @(value !*int16))
44+ } else if tpe == uint16 {
45+ return cstd::fprintf(file, "%hu".value, @(value !*uint16))
46+ } else if tpe == int32 {
47+ return cstd::fprintf(file, "%d".value, @(value !*int32))
48+ } else if tpe == uint32 {
49+ return cstd::fprintf(file, "%u".value, @(value !*uint32))
50+ } else if tpe == int64 {
51+ return cstd::fprintf(file, "%ld".value, @(value !*int64))
52+ } else if tpe == uint64 {
53+ return cstd::fprintf(file, "%lu".value, @(value !*uint64))
54+ } else if tpe == float64 {
55+ return cstd::fprintf(file, "%lf".value, @(value !*float64))
56+ } else if tpe == float32 {
57+ return cstd::fprintf(file, "%f".value, @(value !*float32))
58+ } else if tpe == bool {
59+ if @(value !*bool) {
60+ return cstd::fprintf(file, "true".value)
61+ } else {
62+ return cstd::fprintf(file, "false".value)
63+ }
64+ } else if tpe.type == reflection::PointerT {
65+ return cstd::fprintf(file, "%p".value, @(value !**))
66+ } else if tpe.type == reflection::ArrayT {
67+ let artpe = tpe !reflection::ArrayT
68+ let arr = @(value !*[int8])
69+ let size = arr.size
70+ let elements = arr.value
71+ var sum = 0
72+
73+ sum += cstd::fprintf(file, "[".value)
74+ for var i in 0..size {
75+ sum += print_val(file, elements ++ i * artpe.tpe.size, artpe.tpe)
76+ if i < size - 1 {
77+ sum += cstd::fprintf(file, ", ".value)
78+ }
79+ }
80+ sum += cstd::fprintf(file, "]".value)
81+ return sum
82+ } else if tpe.type == reflection::StaticArrayT {
83+ let artpe = tpe !reflection::StaticArrayT
84+ if artpe == char {
85+ return cstd::fprintf(file, "%s".value, value !*char)
86+ }
87+
88+ let size = artpe.length
89+ var sum = 0
90+
91+ sum += cstd::fprintf(file, "[".value)
92+ for var i in 0..size {
93+ sum += print_val(file, value ++ i * artpe.tpe.size, artpe.tpe)
94+ if i < size - 1 {
95+ sum += cstd::fprintf(file, ", ".value)
96+ }
97+ }
98+ sum += cstd::fprintf(file, "]".value)
99+ return sum
100+ } else if tpe.type == reflection::EnumT {
101+ let etpe = tpe !reflection::EnumT
102+ var v: int64 = 0
103+ for var i in 0..etpe.size {
104+ v |= (@((value ++ i) !*byte)) !int64 << (i * 8)
105+ }
106+
107+ var str: Str = "INVALID!!"
108+ for var i in 0..etpe.values.size {
109+ let ev = etpe.values(i)
110+ if ev.value == v {
111+ str = to_str(ev.name)
112+ }
113+ }
114+ return fprint(file, str)
115+ } else if reflection::implements(tpe, type &ToString) {
116+ let r = value !*runtime::Ref
117+ let str = (@r !& !&ToString).to_string()
118+ return fprint(file, str)
119+ } else if reflection::implements(tpe, String) {
120+ let r = value !*runtime::Ref
121+ let str = (@r !& !String).to_str()
122+ return fprint(file, str)
123+ } else if tpe.type == reflection::StructT or tpe.type == reflection::UnionT {
124+ let rect = *(tpe !RecordT)
125+ let members = rect.members
126+ var sum = 0
127+ sum += cstd::fprintf(file, "[".value)
128+ for var i in 0..members.size {
129+ let field = members(i)
130+ sum += fprint(file, field.name.to_str())
131+ sum += cstd::fprintf(file, " = ".value)
132+
133+ sum += print_val(file, value ++ field.offset, field.tpe)
134+ if i < members.size - 1 {
135+ sum += cstd::fprintf(file, ", ".value)
136+ }
137+ }
138+ sum += cstd::fprintf(file, "] !".value)
139+ sum += fprint(file, tpe.name.to_str())
140+ return sum
141+ } else if tpe.type == reflection::ReferenceT {
142+ let reftpe = tpe !reflection::ReferenceT
143+ let ref_tpe = reftpe.tpe
144+ let r = value !*runtime::Ref
145+ return print_val(file, (@r).value, ref_tpe)
146+ }
147+ }
148+
149+ export def fprint(file: File, args: &...) -> int {
150+ var sum = 0
151+ for var i in 0..args.size {
152+ let arg = args(i)
153+ let ref_tpe = arg.type
154+
155+ if ref_tpe {
156+ sum += print_val(file, (*arg) !*, ref_tpe)
157+ } else {
158+ sum += cstd::fprintf(file, "null".value)
159+ }
160+ }
161+ return sum
162+ }
163+
164+ // Optimized version
165+ export def fprint(file: File, str: Str) -> int {
166+ cstd::fwrite(get_internal_buffer(*str), 1, length(str), file)
167+ return length(str) !int
168+ }
169+
170+ export def print(args: &...) -> int {
171+ return fprint(stdout(), args)
172+ }
173+
174+ export def error(args: &...) -> int {
175+ return fprint(stderr(), args)
176+ }
0 commit comments