@@ -238,7 +238,7 @@ struct WatParser {
238238 var inlineElement : ElementDecl ?
239239 let isMemory64 = try expectAddressSpaceType ( )
240240
241- if let refType = try maybeRefType ( ) {
241+ if let refType = try takeRefType ( ) {
242242 guard try parser. takeParenBlockStart ( " elem " ) else {
243243 throw WatParserError ( " expected elem " , location: parser. lexer. location ( ) )
244244 }
@@ -373,7 +373,7 @@ struct WatParser {
373373 // | funcidx* (iff the tableuse is omitted)
374374 let indices : ElementDecl . Indices
375375 let type : ReferenceType
376- if let refType = try maybeRefType ( ) {
376+ if let refType = try takeRefType ( ) {
377377 indices = . elementExprList( parser. lexer)
378378 type = refType
379379 } else if try parser. takeKeyword ( " func " ) || table == nil {
@@ -606,70 +606,56 @@ struct WatParser {
606606 }
607607
608608 mutating func valueType( ) throws -> ValueType {
609- if try parser. peek ( . leftParen) != nil {
610- return try _referenceValueType ( )
609+ if try parser. takeKeyword ( " i32 " ) {
610+ return . i32
611+ } else if try parser. takeKeyword ( " i64 " ) {
612+ return . i64
613+ } else if try parser. takeKeyword ( " f32 " ) {
614+ return . f32
615+ } else if try parser. takeKeyword ( " f64 " ) {
616+ return . f64
617+ } else if let refType = try takeRefType ( ) {
618+ return . ref( refType)
611619 } else {
612- return try _valueType ( )
613- }
614- }
615-
616- // must consume right paren
617- mutating func _referenceValueType( ) throws -> ValueType {
618- var isNullable = false
619- _ = try parser. takeParenBlockStart ( " ref " )
620- if try parser. peekKeyword ( ) == " null " {
621- _ = try parser. takeKeyword ( " null " )
622- isNullable = true
623- }
624-
625- if try parser. takeId ( ) != nil {
626- _ = try parser. take ( . rightParen)
627- return . ref( refType ( keyword: " func " , isNullable: isNullable) !)
628- }
629-
630- let keyword = try parser. expectKeyword ( )
631- _ = try parser. take ( . rightParen)
632- if let refType = refType ( keyword: keyword, isNullable: isNullable) { return . ref( refType) }
633- throw WatParserError ( " unexpected value type \( keyword) " , location: parser. lexer. location ( ) )
634- }
635-
636- mutating func _valueType( ) throws -> ValueType {
637- let keyword = try parser. expectKeyword ( )
638- switch keyword {
639- case " i32 " : return . i32
640- case " i64 " : return . i64
641- case " f32 " : return . f32
642- case " f64 " : return . f64
643- default :
644- if let refType = refType ( keyword: keyword, isNullable: true ) { return . ref( refType) }
645- throw WatParserError ( " unexpected value type \( keyword) " , location: parser. lexer. location ( ) )
646- }
647- }
648-
649- mutating func refType( keyword: String , isNullable: Bool ) -> ReferenceType ? {
650- switch keyword {
651- case " funcref " : return . funcRef
652- case " externref " : return . externRef
653- case " func " : return ReferenceType ( isNullable: isNullable, heapType: . funcRef)
654- case " extern " : return ReferenceType ( isNullable: isNullable, heapType: . funcRef)
655- default : return nil
620+ throw WatParserError ( " expected value type " , location: parser. lexer. location ( ) )
656621 }
657622 }
658623
659624 mutating func refType( ) throws -> ReferenceType {
660- let keyword = try parser. expectKeyword ( )
661- guard let refType = refType ( keyword: keyword, isNullable: true ) else {
662- throw WatParserError ( " unexpected ref type \( keyword) " , location: parser. lexer. location ( ) )
625+ guard let refType = try takeRefType ( ) else {
626+ throw WatParserError ( " expected reference type " , location: parser. lexer. location ( ) )
663627 }
664628 return refType
665629 }
666630
667- mutating func maybeRefType( ) throws -> ReferenceType ? {
631+ /// Parse a reference type tokens if the head tokens seems like so.
632+ mutating func takeRefType( ) throws -> ReferenceType ? {
633+ // Check abbreviations first
634+ // https://webassembly.github.io/function-references/core/text/types.html#abbreviations
668635 if try parser. takeKeyword ( " funcref " ) {
669636 return . funcRef
670637 } else if try parser. takeKeyword ( " externref " ) {
671638 return . externRef
639+ } else if try parser. takeParenBlockStart ( " ref " ) {
640+ let isNullable = try parser. takeKeyword ( " null " )
641+ let heapType = try heapType ( )
642+ try parser. expect ( . rightParen)
643+ return ReferenceType ( isNullable: isNullable, heapType: heapType)
672644 }
673645 return nil
674646 }
647+
648+ /// > Note:
649+ /// <https://webassembly.github.io/function-references/core/text/types.html#heap-types>
650+ mutating func heapType( ) throws -> HeapType {
651+ if try parser. takeKeyword ( " func " ) {
652+ return . abstract( . funcRef)
653+ } else if try parser. takeKeyword ( " extern " ) {
654+ return . abstract( . externRef)
655+ } else if try parser. takeIndexOrId ( ) != nil {
656+ // TODO: Implement (ref $t)
657+ throw WatParserError ( " concrete heap type is not supported yet " , location: parser. lexer. location ( ) )
658+ }
659+ throw WatParserError ( " expected heap type " , location: parser. lexer. location ( ) )
660+ }
675661}
0 commit comments