@@ -169,38 +169,63 @@ Result<NaNKind> nan(Lexer& in) {
169169}
170170
171171Result<ExpectedResult> result (Lexer& in) {
172- Lexer constLexer = in;
173- auto c = const_ (constLexer);
174- // TODO: Generating and discarding errors like this can lead to quadratic
175- // behavior. Optimize this if necessary.
176- if (!c.getErr ()) {
177- in = constLexer;
178- return *c;
179- }
180-
181- // If we failed to parse a constant, we must have either a nan pattern or a
182- // reference.
183- if (in.takeSExprStart (" f32.const" sv)) {
184- auto kind = nan (in);
185- CHECK_ERR (kind);
186- if (!in.takeRParen ()) {
187- return in.err (" expected end of f32.const" );
172+ if (in.takeSExprStart (" v128.const" sv)) {
173+ auto laneTypeChar = in.peekChar ();
174+ if (!laneTypeChar) {
175+ return in.err (" expected vector shape" );
188176 }
189- return NaNResult{*kind, Type::f32 };
190- }
191177
192- if (in.takeSExprStart (" f64.const" sv)) {
193- auto kind = nan (in);
194- CHECK_ERR (kind);
195- if (!in.takeRParen ()) {
196- return in.err (" expected end of f64.const" );
178+ LaneResults::LaneType laneType;
179+ switch (*laneTypeChar) {
180+ case ' f' : {
181+ laneType = LaneResults::LaneType::Float;
182+ break ;
183+ }
184+ case ' i' : {
185+ laneType = LaneResults::LaneType::Int;
186+ break ;
187+ }
188+ default : {
189+ return in.err (" expected vector shape" );
190+ }
197191 }
198- return NaNResult{*kind, Type::f64 };
199- }
200192
201- if (in.takeSExprStart (" v128.const" sv)) {
202- LaneResults lanes;
203- if (in.takeKeyword (" f32x4" sv)) {
193+ LaneResults results (laneType);
194+ auto & lanes = results.lanes ;
195+
196+ if (in.takeKeyword (" i8x16" sv)) {
197+ for (int i = 0 ; i < 16 ; ++i) {
198+ auto int_ = in.takeI8 ();
199+ if (!int_) {
200+ return in.err (" expected i8 immediate" );
201+ }
202+ lanes.push_back (Literal (static_cast <uint32_t >(*int_)));
203+ }
204+ } else if (in.takeKeyword (" i16x8" sv)) {
205+ for (int i = 0 ; i < 8 ; ++i) {
206+ auto int_ = in.takeI16 ();
207+ if (!int_) {
208+ return in.err (" expected i16 immediate" );
209+ }
210+ lanes.push_back (Literal (static_cast <uint32_t >(*int_)));
211+ }
212+ } else if (in.takeKeyword (" i32x4" sv)) {
213+ for (int i = 0 ; i < 4 ; ++i) {
214+ auto int_ = in.takeI32 ();
215+ if (!int_) {
216+ return in.err (" expected i32 immediate" );
217+ }
218+ lanes.push_back (Literal (static_cast <uint32_t >(*int_)));
219+ }
220+ } else if (in.takeKeyword (" i64x2" sv)) {
221+ for (int i = 0 ; i < 2 ; ++i) {
222+ auto int_ = in.takeI64 ();
223+ if (!int_) {
224+ return in.err (" expected i64 immediate" );
225+ }
226+ lanes.push_back (Literal (*int_));
227+ }
228+ } else if (in.takeKeyword (" f32x4" sv)) {
204229 for (int i = 0 ; i < 4 ; ++i) {
205230 if (auto f = in.takeF32 ()) {
206231 lanes.push_back (Literal (*f));
@@ -226,7 +251,36 @@ Result<ExpectedResult> result(Lexer& in) {
226251 if (!in.takeRParen ()) {
227252 return in.err (" expected end of v128.const" );
228253 }
229- return lanes;
254+ return results;
255+ }
256+
257+ Lexer constLexer = in;
258+ auto c = const_ (constLexer);
259+ // TODO: Generating and discarding errors like this can lead to quadratic
260+ // behavior. Optimize this if necessary.
261+ if (!c.getErr ()) {
262+ in = constLexer;
263+ return *c;
264+ }
265+
266+ // If we failed to parse a constant, we must have either a nan pattern or a
267+ // reference.
268+ if (in.takeSExprStart (" f32.const" sv)) {
269+ auto kind = nan (in);
270+ CHECK_ERR (kind);
271+ if (!in.takeRParen ()) {
272+ return in.err (" expected end of f32.const" );
273+ }
274+ return NaNResult{*kind, Type::f32 };
275+ }
276+
277+ if (in.takeSExprStart (" f64.const" sv)) {
278+ auto kind = nan (in);
279+ CHECK_ERR (kind);
280+ if (!in.takeRParen ()) {
281+ return in.err (" expected end of f64.const" );
282+ }
283+ return NaNResult{*kind, Type::f64 };
230284 }
231285
232286 if (in.takeSExprStart (" ref.null" )) {
0 commit comments