import Foundation
enum Operator: String {
case add = "+"
case subtract = "-"
case multiply = "*"
case divide = "/"
case power = "^"
case squareRoot = "sqrt"
case sine = "sin"
func evaluate(withLeftOperand left: Double, rightOperand: Double) -> Double {
switch self {
case .add:
return left + right
case .subtract:
return left - right
case .multiply:
return left * right
case .divide:
if right == 0 {
fatalError("Division by zero")
}
return left / right
case .power:
return pow(left, right)
case .squareRoot:
if left < 0 {
fatalError("Cannot take square root of a negative number")
}
return sqrt(left)
case .sine:
return sin(left)
}
}
}
typealias Operand = Double
enum Precedence: Int {
case addition = 1
case multiplication = 2
case unary = 3
}
class ExpressionParser {
private var tokens: [String]
private var index = 0
private var operands = ArrayStack<Operand>()
private var operators = ArrayStack<String>()
init(expression: String) {
self.tokens = tokenize(expression)
}
private func tokenize(_ expression: String) -> [String] {
return expression.components(separatedBy: .whitespacesAndNewlines)
}
private func currentToken() -> String {
return tokens[index]
}
private func advance() {
index += 1
}
private func peekIs(character: Character) -> Bool {
return currentToken().first == character
}
private func consumeIs(character: Character) -> Bool {
if peekIs(character: character) {
advance()
return true
}
return false
}
private func error(message: String) -> Never {
fatalError("Parse error: \(message) at index \(index)")
}
private func precedence(ofOperator operator: String) -> Precedence {
switch operator {
case "+", "-":
return Precedence.addition
case "*", "/":
return Precedence.multiplication
default:
return Precedence.unary
}
}
private func shouldApplyOperator(_ operator: String) -> Bool {
if operators.isEmpty {
return true
}
let topOperator = operators.peek()
return precedence(ofOperator: operator) <= precedence(ofOperator: topOperator)
}
private func applyOperator(_ operator: String) {
let rightOperand = operands.pop()
let leftOperand = operands.pop()
let result: Operand
switch operator {
case "+":
result = leftOperand + rightOperand
case "-":
result = leftOperand - rightOperand
case "*":
result = leftOperand * rightOperand
case "/":
if rightOperand == 0 {
error(message: "Division by zero")
}
result = leftOperand / rightOperand
default:
error(message: "Unknown operator")
}
operands.push(result)
}
func parse() -> Operand {
while !tokens.isEmpty {
if let firstCharacter = tokens[index].first {
switch firstCharacter {
case "+", "-", "*", "/":
while !operators.isEmpty && shouldApplyOperator(tokens[index]) {
applyOperator(operators.pop())
}
operators.push(tokens[index])
advance()
case "(":
operators.push(tokens[index])
advance()
case ")":
while !operators.isEmpty && operators.peek() != "(" {
applyOperator(operators.pop())
}
if operators.isEmpty {
error(message: "Mismatched parentheses")
}
operators.pop
advance()
case let digit where digit.isNumber:
var value = 0.0
while index < tokens.count, let character = tokens[index].first, character.isNumber || character == "." {
value = value * 10 + (character as String).doubleValue!
advance()
}
operands.push(value)
default:
error(message: "Unknown token (tokens[index])")
}
} else {
error(message: "Empty token")
}
}
while !operators.isEmpty {
if operators.peek() == "(" {
error(message: "Mismatched parentheses")
}
applyOperator(operators.pop())
}
if operands.count != 1 {
error(message: "Invalid expression")
}
return operands.pop()
}
private class ArrayStack<T> {
private var elements = [T]()
func push(_ element: T) {
elements.append(element)
}
func pop() -> T {
if elements.isEmpty {
fatalError("Stack is empty")
}
return elements.removeLast()
}
func peek() -> T {
if elements.isEmpty {
fatalError("Stack is empty")
}
return elements.last!
}
func isEmpty() -> Bool {
return elements.isEmpty
}
}
}
class ComplexNumber {
var real: Double
var imaginary: Double
init(_ real: Double, _ imaginary: Double) {
self.real = real
self.imaginary = imaginary
}
func +(other: ComplexNumber) -> ComplexNumber {
return ComplexNumber(self.real + other.real, self.imaginary + other.imaginary)
}
func -(other: ComplexNumber) -> ComplexNumber {
return ComplexNumber(self.real - other.real, self.imaginary - other.imaginary)
}
func *(other: ComplexNumber) -> ComplexNumber {
let realPart = self.real * other.real - self.imaginary * other.imaginary
let imaginaryPart = self.real * other.imaginary + self.imaginary * other.real
return ComplexNumber(realPart, imaginaryPart)
}
func /(other: ComplexNumber) -> ComplexNumber {
let denominator = other.real * other.real + other.imaginary * other.imaginary
let realPart = (self.real * other.real + self.imaginary * other.imaginary) / denominator
let imaginaryPart = (self.imaginary * other.real - self.real * other.imaginary) / denominator
return ComplexNumber(realPart, imaginaryPart)
}
func sin() -> Double {
return sin(self.real)
}
override var description: String {
if imaginary >= 0 {
return "\(real)+\(imaginary)i"
} else {
return "\(real)\(imaginary)i"
}
}
}
class BigInteger {
var value: String
}
class Calculator {
private let parser: ExpressionParser
init() {
parser = ExpressionParser()
}
func evaluate(expression: String) -> Double {
let ast = parser.parse(expression)
return parser.evaluate(ast)
}
func evaluateComplex(expression: String) -> ComplexNumber {
}
func evaluateBigInteger(expression: String) -> BigInteger {
}
}
let calculator = Calculator()
let resultBasic = calculator.evaluate("3+5*4")
let resultWithParentheses = calculator.evaluate("1+(3+5)*4")
let complexResult = calculator.evaluateComplex("2+3i * 4-5i")
let bigIntegerResult = calculator.evaluateBigInteger("12345678901234567890 * 98765432109876543210")
print("Basic result: \(resultBasic)")
print("Result with parentheses: \(resultWithParentheses)")
print("Complex result: \(complexResult)")
print("BigInteger result: \(bigIntegerResult)")