libxr  1.0
Want to be the best embedded framework
Loading...
Searching...
No Matches
printf_frontend_lowering_field.hpp
1#pragma once
2
6namespace SourceSyntax
7{
8namespace FieldSelection
9{
16[[nodiscard]] consteval FormatType SelectFormatType(const Conversion& conversion,
17 FormatArgumentRule rule)
18{
19 if (conversion.length == Length::LongDouble)
20 {
21 if (conversion.type == ValueKind::FloatFixed)
22 {
23 return FormatType::LongDoubleFixed;
24 }
25 if (conversion.type == ValueKind::FloatScientific)
26 {
27 return FormatType::LongDoubleScientific;
28 }
29 if (conversion.type == ValueKind::FloatGeneral)
30 {
31 return FormatType::LongDoubleGeneral;
32 }
33 }
34
35 if (conversion.type == ValueKind::Signed)
36 {
37 return RuleUses64BitStorage(rule) ? FormatType::Signed64 : FormatType::Signed32;
38 }
39 if (conversion.type == ValueKind::Unsigned)
40 {
41 return RuleUses64BitStorage(rule) ? FormatType::Unsigned64
42 : FormatType::Unsigned32;
43 }
44 if (conversion.type == ValueKind::Binary)
45 {
46 return RuleUses64BitStorage(rule) ? FormatType::Binary64 : FormatType::Binary32;
47 }
48 if (conversion.type == ValueKind::Octal)
49 {
50 return RuleUses64BitStorage(rule) ? FormatType::Octal64 : FormatType::Octal32;
51 }
52 if (conversion.type == ValueKind::HexLower)
53 {
54 return RuleUses64BitStorage(rule) ? FormatType::HexLower64
55 : FormatType::HexLower32;
56 }
57 if (conversion.type == ValueKind::HexUpper)
58 {
59 return RuleUses64BitStorage(rule) ? FormatType::HexUpper64
60 : FormatType::HexUpper32;
61 }
62
63 switch (conversion.type)
64 {
65 case ValueKind::Pointer:
66 return FormatType::Pointer;
67 case ValueKind::Character:
68 return FormatType::Character;
69 case ValueKind::String:
70 return FormatType::String;
71 case ValueKind::FloatFixed:
72 return UsesDoubleFloatStorage() ? FormatType::DoubleFixed
73 : FormatType::FloatFixed;
74 case ValueKind::FloatScientific:
75 return UsesDoubleFloatStorage() ? FormatType::DoubleScientific
76 : FormatType::FloatScientific;
77 case ValueKind::FloatGeneral:
78 return UsesDoubleFloatStorage() ? FormatType::DoubleGeneral
79 : FormatType::FloatGeneral;
80 case ValueKind::None:
81 case ValueKind::Signed:
82 case ValueKind::Unsigned:
83 case ValueKind::Binary:
84 case ValueKind::Octal:
85 case ValueKind::HexLower:
86 case ValueKind::HexUpper:
87 return FormatType::End;
88 }
89
90 return FormatType::End;
91}
92
99[[nodiscard]] consteval FormatPackKind SelectPackKind(FormatType type)
100{
101 switch (type)
102 {
103 case FormatType::Signed32:
104 return FormatPackKind::I32;
105 case FormatType::Signed64:
106 return FormatPackKind::I64;
107 case FormatType::Unsigned32:
108 case FormatType::Binary32:
109 case FormatType::Octal32:
110 case FormatType::HexLower32:
111 case FormatType::HexUpper32:
112 return FormatPackKind::U32;
113 case FormatType::Unsigned64:
114 case FormatType::Binary64:
115 case FormatType::Octal64:
116 case FormatType::HexLower64:
117 case FormatType::HexUpper64:
118 return FormatPackKind::U64;
119 case FormatType::Pointer:
120 return FormatPackKind::Pointer;
121 case FormatType::Character:
122 return FormatPackKind::Character;
123 case FormatType::String:
124 return FormatPackKind::StringView;
125 case FormatType::FloatFixed:
126 case FormatType::FloatScientific:
127 case FormatType::FloatGeneral:
128 return FormatPackKind::F32;
129 case FormatType::DoubleFixed:
130 case FormatType::DoubleScientific:
131 case FormatType::DoubleGeneral:
132 return FormatPackKind::F64;
133 case FormatType::LongDoubleFixed:
134 case FormatType::LongDoubleScientific:
135 case FormatType::LongDoubleGeneral:
136 return FormatPackKind::LongDouble;
137 case FormatType::End:
138 case FormatType::TextInline:
139 case FormatType::TextRef:
140 case FormatType::TextSpace:
141 return FormatPackKind::U32;
142 }
143
144 return FormatPackKind::U32;
145}
146
153[[nodiscard]] consteval FormatArgumentRule SelectArgumentRule(const Conversion& conversion)
154{
155 if (conversion.type == ValueKind::Signed)
156 {
157 return RuleFromTable(signed_rules, conversion.length);
158 }
159
160 if (IsUnsignedType(conversion.type))
161 {
162 return RuleFromTable(unsigned_rules, conversion.length);
163 }
164
165 switch (conversion.type)
166 {
167 case ValueKind::Pointer:
168 return FormatArgumentRule::Pointer;
169 case ValueKind::Character:
170 return FormatArgumentRule::Character;
171 case ValueKind::String:
172 return FormatArgumentRule::String;
173 case ValueKind::FloatFixed:
174 case ValueKind::FloatScientific:
175 case ValueKind::FloatGeneral:
176 return (conversion.length == Length::LongDouble)
177 ? FormatArgumentRule::LongDouble
178 : FormatArgumentRule::Float;
179 case ValueKind::None:
180 case ValueKind::Signed:
181 case ValueKind::Unsigned:
182 case ValueKind::Binary:
183 case ValueKind::Octal:
184 case ValueKind::HexLower:
185 case ValueKind::HexUpper:
186 break;
187 }
188
189 return FormatArgumentRule::None;
190}
191
199[[nodiscard]] consteval Error ValidateConversion(const Conversion& conversion)
200{
201 if ((conversion.type == ValueKind::FloatFixed ||
202 conversion.type == ValueKind::FloatScientific ||
203 conversion.type == ValueKind::FloatGeneral) &&
204 conversion.has_precision &&
205 conversion.precision > Config::max_float_precision)
206 {
207 return Error::FloatPrecisionLimitExceeded;
208 }
209
210 if ((conversion.type == ValueKind::Signed || IsUnsignedType(conversion.type)) &&
211 RuleUses64BitStorage(SelectArgumentRule(conversion)) &&
212 !Config::enable_integer_64bit)
213 {
214 return Error::InvalidLength;
215 }
216
217 return Error::None;
218}
219
226[[nodiscard]] consteval FormatField BuildFormatField(const Conversion& conversion)
227{
228 auto rule = SelectArgumentRule(conversion);
229 auto type = SelectFormatType(conversion, rule);
230 return FormatField{
231 .type = type,
232 .pack = SelectPackKind(type),
233 .rule = rule,
234 .flags = conversion.FlagsByte(),
235 .width = conversion.width,
236 .precision = conversion.PrecisionByte(),
237 };
238}
239} // namespace FieldSelection
240} // namespace SourceSyntax
Error
brace 风格 format 前端的编译期失败类别。 / Compile-time failure categories for the brace-style format frontend.
printf 降级阶段共享的描述表与策略辅助函数 / Shared descriptor-table and policy helpers for printf lowering
单个 printf 转换在降为共享格式前的解析结果 / One parsed printf conversion before lowering into the shared format
ValueKind type
semantic conversion category / 转换项归一化后的语义类别
constexpr uint8_t FlagsByte() const
将前端解析出的标志位打包成共享的 FormatFlag 字节 / Pack the parsed frontend flags into the shared FormatFlag byte
Length length
parsed length modifier / 已解析的长度修饰符
uint8_t width
parsed field width / 已解析的字段宽度
constexpr uint8_t PrecisionByte() const
返回共享精度字节;若未显式指定精度则为 0xFF / Return the shared precision byte, or 0xFF when precision is absent
uint8_t precision
parsed precision value / 已解析的精度值
bool has_precision
whether precision was explicitly provided / 是否显式提供了精度