Skip to content

Instantly share code, notes, and snippets.

@zonble
Created August 5, 2019 15:53
Show Gist options
  • Save zonble/2011f4c50effe339d0329888a1e10bd4 to your computer and use it in GitHub Desktop.
Save zonble/2011f4c50effe339d0329888a1e10bd4 to your computer and use it in GitHub Desktop.
enum Token {
case num(Int)
case op(String)
}
func tokenize(_ s: String) -> [Token] {
let scanner = Scanner(string: s)
scanner.charactersToBeSkipped = CharacterSet.whitespaces
var tokens = [Token]()
while !scanner.isAtEnd {
if let c = scanner.scanCharacters(from: CharacterSet(charactersIn: "+-*/")) {
tokens.append(.op(String(c)))
}
else if let int = scanner.scanInt() {
tokens.append(.num(int))
}
}
return tokens
}
enum MyError : Error {
case invalidToken
}
func calc(_ tokens: [Token]) throws -> Int {
if tokens.count == 0 {
return 0
}
guard case let .num(x) = tokens[0] else {
throw MyError.invalidToken
}
var v = x
var currentToken: Token = tokens[0]
for token in tokens[1...] {
switch token {
case .num(let i):
switch currentToken {
case .num(_):
throw MyError.invalidToken
case .op(let c):
switch c {
case "+":
v += i
case "-":
v -= i
case "*":
v *= i
case "/":
v /= i
default:
throw MyError.invalidToken
}
currentToken = token
}
case .op(_):
switch currentToken {
case .op(_):
throw MyError.invalidToken
case .num(_):
currentToken = token
}
break
}
}
return v
}
//let t = tokenize("1 / 1 * 2 + 100 - 80")
let t = tokenize("1 + 100 * 200")
print(t)
t
do {
let result = try calc(t)
result
} catch {
error
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment