@@ -606,29 +606,59 @@ struct WatParser {
606606 }
607607
608608 mutating func valueType( ) throws -> ValueType {
609+ if try parser. peek ( . leftParen) != nil {
610+ return try _referenceValueType ( )
611+ } 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 {
609637 let keyword = try parser. expectKeyword ( )
610638 switch keyword {
611639 case " i32 " : return . i32
612640 case " i64 " : return . i64
613641 case " f32 " : return . f32
614642 case " f64 " : return . f64
615643 default :
616- if let refType = refType ( keyword: keyword) { return . ref( refType) }
644+ if let refType = refType ( keyword: keyword, isNullable : true ) { return . ref( refType) }
617645 throw WatParserError ( " unexpected value type \( keyword) " , location: parser. lexer. location ( ) )
618646 }
619647 }
620648
621- mutating func refType( keyword: String ) -> ReferenceType ? {
649+ mutating func refType( keyword: String , isNullable : Bool ) -> ReferenceType ? {
622650 switch keyword {
623651 case " funcref " : return . funcRef
624652 case " externref " : return . externRef
653+ case " func " : return isNullable ? . funcRef : . funcRefNonNull
654+ case " extern " : return isNullable ? . externRef : . externRefNonNull
625655 default : return nil
626656 }
627657 }
628658
629659 mutating func refType( ) throws -> ReferenceType {
630660 let keyword = try parser. expectKeyword ( )
631- guard let refType = refType ( keyword: keyword) else {
661+ guard let refType = refType ( keyword: keyword, isNullable : true ) else {
632662 throw WatParserError ( " unexpected ref type \( keyword) " , location: parser. lexer. location ( ) )
633663 }
634664 return refType
0 commit comments