@@ -606,29 +606,59 @@ struct WatParser {
606
606
}
607
607
608
608
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 {
609
637
let keyword = try parser. expectKeyword ( )
610
638
switch keyword {
611
639
case " i32 " : return . i32
612
640
case " i64 " : return . i64
613
641
case " f32 " : return . f32
614
642
case " f64 " : return . f64
615
643
default :
616
- if let refType = refType ( keyword: keyword) { return . ref( refType) }
644
+ if let refType = refType ( keyword: keyword, isNullable : true ) { return . ref( refType) }
617
645
throw WatParserError ( " unexpected value type \( keyword) " , location: parser. lexer. location ( ) )
618
646
}
619
647
}
620
648
621
- mutating func refType( keyword: String ) -> ReferenceType ? {
649
+ mutating func refType( keyword: String , isNullable : Bool ) -> ReferenceType ? {
622
650
switch keyword {
623
651
case " funcref " : return . funcRef
624
652
case " externref " : return . externRef
653
+ case " func " : return isNullable ? . funcRef : . funcRefNonNull
654
+ case " extern " : return isNullable ? . externRef : . externRefNonNull
625
655
default : return nil
626
656
}
627
657
}
628
658
629
659
mutating func refType( ) throws -> ReferenceType {
630
660
let keyword = try parser. expectKeyword ( )
631
- guard let refType = refType ( keyword: keyword) else {
661
+ guard let refType = refType ( keyword: keyword, isNullable : true ) else {
632
662
throw WatParserError ( " unexpected ref type \( keyword) " , location: parser. lexer. location ( ) )
633
663
}
634
664
return refType
0 commit comments