libxr  1.0
Want to be the best embedded framework
Loading...
Searching...
No Matches
printf_frontend_binding_field.hpp
1#pragma once
2
7namespace SourceSyntax
8{
9namespace FieldSelection
10{
20[[nodiscard]] consteval FormatType SelectFormatType(const Conversion& conversion,
21 FormatArgumentRule rule)
22{
23 if (conversion.length == Length::LongDouble)
24 {
25 if (conversion.type == ValueKind::FloatFixed)
26 {
27 return FormatType::LongDoubleFixed;
28 }
29 if (conversion.type == ValueKind::FloatScientific)
30 {
31 return FormatType::LongDoubleScientific;
32 }
33 if (conversion.type == ValueKind::FloatGeneral)
34 {
35 return FormatType::LongDoubleGeneral;
36 }
37 }
38
39 if (conversion.type == ValueKind::Signed)
40 {
41 return RuleUses64BitStorage(rule) ? FormatType::Signed64 : FormatType::Signed32;
42 }
43 if (conversion.type == ValueKind::Unsigned)
44 {
45 return RuleUses64BitStorage(rule) ? FormatType::Unsigned64 : FormatType::Unsigned32;
46 }
47 if (conversion.type == ValueKind::Binary)
48 {
49 return RuleUses64BitStorage(rule) ? FormatType::Binary64 : FormatType::Binary32;
50 }
51 if (conversion.type == ValueKind::Octal)
52 {
53 return RuleUses64BitStorage(rule) ? FormatType::Octal64 : FormatType::Octal32;
54 }
55 if (conversion.type == ValueKind::HexLower)
56 {
57 return RuleUses64BitStorage(rule) ? FormatType::HexLower64 : FormatType::HexLower32;
58 }
59 if (conversion.type == ValueKind::HexUpper)
60 {
61 return RuleUses64BitStorage(rule) ? FormatType::HexUpper64 : FormatType::HexUpper32;
62 }
63
64 switch (conversion.type)
65 {
66 case ValueKind::Pointer:
67 return FormatType::Pointer;
68 case ValueKind::Character:
69 return FormatType::Character;
70 case ValueKind::String:
71 return FormatType::String;
72 case ValueKind::FloatFixed:
73 return UsesDoubleFloatStorage() ? FormatType::DoubleFixed : 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
100[[nodiscard]] consteval FormatPackKind SelectPackKind(FormatType type)
101{
102 switch (type)
103 {
104 case FormatType::Signed32:
105 return FormatPackKind::I32;
106 case FormatType::Signed64:
107 return FormatPackKind::I64;
108 case FormatType::Unsigned32:
109 case FormatType::Binary32:
110 case FormatType::Octal32:
111 case FormatType::HexLower32:
112 case FormatType::HexUpper32:
113 return FormatPackKind::U32;
114 case FormatType::Unsigned64:
115 case FormatType::Binary64:
116 case FormatType::Octal64:
117 case FormatType::HexLower64:
118 case FormatType::HexUpper64:
119 return FormatPackKind::U64;
120 case FormatType::Pointer:
121 return FormatPackKind::Pointer;
122 case FormatType::Character:
123 return FormatPackKind::Character;
124 case FormatType::String:
125 return FormatPackKind::StringView;
126 case FormatType::FloatFixed:
127 case FormatType::FloatScientific:
128 case FormatType::FloatGeneral:
129 return FormatPackKind::F32;
130 case FormatType::DoubleFixed:
131 case FormatType::DoubleScientific:
132 case FormatType::DoubleGeneral:
133 return FormatPackKind::F64;
134 case FormatType::LongDoubleFixed:
135 case FormatType::LongDoubleScientific:
136 case FormatType::LongDoubleGeneral:
137 return FormatPackKind::LongDouble;
138 case FormatType::End:
139 case FormatType::TextInline:
140 case FormatType::TextRef:
141 case FormatType::TextSpace:
142 ASSERT(false);
143 return FormatPackKind::U32;
144 }
145
146 ASSERT(false);
147 return FormatPackKind::U32;
148}
149
157[[nodiscard]] consteval FormatArgumentRule SelectArgumentRule(
158 const Conversion& conversion)
159{
160 if (conversion.type == ValueKind::Signed)
161 {
162 return RuleFromTable(signed_rules, conversion.length);
163 }
164
165 if (IsUnsignedType(conversion.type))
166 {
167 return RuleFromTable(unsigned_rules, conversion.length);
168 }
169
170 switch (conversion.type)
171 {
172 case ValueKind::Pointer:
173 return FormatArgumentRule::Pointer;
174 case ValueKind::Character:
175 return FormatArgumentRule::Character;
176 case ValueKind::String:
177 return FormatArgumentRule::String;
178 case ValueKind::FloatFixed:
179 case ValueKind::FloatScientific:
180 case ValueKind::FloatGeneral:
181 return (conversion.length == Length::LongDouble) ? FormatArgumentRule::LongDouble
182 : FormatArgumentRule::Float;
183 case ValueKind::None:
184 case ValueKind::Signed:
185 case ValueKind::Unsigned:
186 case ValueKind::Binary:
187 case ValueKind::Octal:
188 case ValueKind::HexLower:
189 case ValueKind::HexUpper:
190 break;
191 }
192
193 return FormatArgumentRule::None;
194}
195
204[[nodiscard]] consteval Error ValidateConversion(const Conversion& conversion)
205{
206 if ((conversion.type == ValueKind::FloatFixed ||
207 conversion.type == ValueKind::FloatScientific ||
208 conversion.type == ValueKind::FloatGeneral) &&
209 conversion.has_precision && conversion.precision > Config::max_float_precision)
210 {
211 return Error::FloatPrecisionLimitExceeded;
212 }
213
214 if ((conversion.type == ValueKind::Signed || IsUnsignedType(conversion.type)) &&
215 RuleUses64BitStorage(SelectArgumentRule(conversion)) &&
216 !Config::enable_integer_64bit)
217 {
218 return Error::InvalidLength;
219 }
220
221 return Error::None;
222}
223
231[[nodiscard]] consteval FormatField BuildFormatField(const Conversion& conversion)
232{
233 auto rule = SelectArgumentRule(conversion);
234 auto type = SelectFormatType(conversion, rule);
235 return FormatField{
236 .type = type,
237 .pack = SelectPackKind(type),
238 .rule = rule,
239 .flags = conversion.FlagsByte(),
240 .width = conversion.width,
241 .precision = conversion.PrecisionByte(),
242 };
243}
244} // namespace FieldSelection
245} // 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 / 是否显式提供了精度