Parser.swift (1872B)
1 // 2 // Parser.swift 3 // damus 4 // 5 // Created by William Casarin on 2022-05-04. 6 // 7 8 import Foundation 9 10 class Parser { 11 var pos: Int 12 var str: String 13 14 init(pos: Int, str: String) { 15 self.pos = pos 16 self.str = str 17 } 18 } 19 20 func consume_until(_ p: Parser, match: (Character) -> Bool, end_ok: Bool = false) -> Bool { 21 let sub = substring(p.str, start: p.pos, end: p.str.count) 22 let start = p.pos 23 24 for c in sub { 25 if match(c) { 26 return true 27 } 28 p.pos += 1 29 } 30 31 if end_ok { 32 return true 33 } 34 35 p.pos = start 36 return false 37 } 38 39 func substring(_ s: String, start: Int, end: Int) -> Substring { 40 let ind = s.index(s.startIndex, offsetBy: start) 41 let end = s.index(s.startIndex, offsetBy: end) 42 return s[ind..<end] 43 } 44 45 46 func parse_str(_ p: Parser, _ s: String) -> Bool { 47 if p.pos + s.count > p.str.count { 48 return false 49 } 50 let sub = substring(p.str, start: p.pos, end: p.pos + s.count) 51 if sub == s { 52 p.pos += s.count 53 return true 54 } 55 return false 56 } 57 58 func parse_char(_ p: Parser, _ c: Character) -> Bool { 59 if p.pos >= p.str.count { 60 return false 61 } 62 63 let ind = p.str.index(p.str.startIndex, offsetBy: p.pos) 64 65 if p.str[ind] == c { 66 p.pos += 1 67 return true 68 } 69 70 return false 71 } 72 73 func parse_hex_char(_ p: Parser) -> Character? { 74 let ind = p.str.index(p.str.startIndex, offsetBy: p.pos) 75 76 // Check that we're within the bounds of p.str's length 77 if p.pos >= p.str.count { 78 return nil 79 } 80 81 82 if let c = p.str[ind].unicodeScalars.first { 83 // hex chars 84 let d = c.value 85 if (d >= 48 && d <= 57) || (d >= 97 && d <= 102) || (d >= 65 && d <= 70) { 86 p.pos += 1 87 return p.str[ind] 88 } 89 } 90 91 return nil 92 }