@@ -47,12 +47,12 @@ public enum Keyword: String, CaseIterable {
4747 case `import`
4848}
4949
50- public enum PrefixOperator : Character {
50+ public enum PrefixOperator : String {
5151 case plus = " + "
5252 case minus = " - "
5353}
5454
55- public enum InfixOperator : Character {
55+ public enum InfixOperator : String {
5656 case plus = " + "
5757 case minus = " - "
5858 case times = " * "
@@ -186,6 +186,7 @@ public extension String {
186186private let whitespace = " \t "
187187private let linebreaks = " \n \r \r \n "
188188private let punctuation = " /()[]{} "
189+ private let operators = " +-*/<>=!?&|%^~ "
189190private let letters = " ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz "
190191private let digits = " 0123456789 "
191192private let alphanumerics = digits + letters
@@ -216,7 +217,7 @@ private extension Substring {
216217 if nextIndex != endIndex, self [ nextIndex] == " / " {
217218 removeFirst ( )
218219 removeFirst ( )
219- while let scalar = first, !scalar . isLinebreak {
220+ while let c = first, !c . isLinebreak {
220221 removeFirst ( )
221222 }
222223 }
@@ -256,7 +257,7 @@ private extension Substring {
256257 }
257258
258259 mutating func readOperator( spaceBefore: Bool ) -> TokenType ? {
259- let start = self
260+ var start = self
260261 switch popFirst ( ) {
261262 case " { " : return . lbrace
262263 case " } " : return . rbrace
@@ -268,23 +269,41 @@ private extension Substring {
268269 }
269270 self = start
270271 return nil
271- case let scalar? :
272- if let op = InfixOperator ( rawValue: scalar) {
273- guard let next = first else {
274- // technically postfix, but we don't have those
275- return . infix( op)
276- }
277- if !spaceBefore || next. isWhitespace || next. isLinebreak {
272+ case let c? where operators. contains ( c) :
273+ func toOp( _ string: String ) -> TokenType ? {
274+ if let op = InfixOperator ( rawValue: string) {
275+ guard let next = first else {
276+ // technically postfix, but we don't have those
277+ return . infix( op)
278+ }
279+ if !spaceBefore || next. isWhitespace || next. isLinebreak {
280+ return . infix( op)
281+ }
282+ if let op = PrefixOperator ( rawValue: string) {
283+ return . prefix( op)
284+ }
278285 return . infix( op)
279- }
280- if let op = PrefixOperator ( rawValue: scalar) {
286+ } else if let op = PrefixOperator ( rawValue: string) {
281287 return . prefix( op)
288+ } else {
289+ return nil
282290 }
283- return . infix( op)
284- } else if let op = PrefixOperator ( rawValue: scalar) {
285- return . prefix( op)
286291 }
287- fallthrough
292+ var string = String ( c)
293+ var op = toOp ( string)
294+ if op != nil {
295+ start = self
296+ }
297+ while let c = first, operators. contains ( c) {
298+ removeFirst ( )
299+ string. append ( c)
300+ if let nextOp = toOp ( string) {
301+ op = nextOp
302+ start = self
303+ }
304+ }
305+ self = start
306+ return op
288307 default :
289308 self = start
290309 return nil
0 commit comments