Reputation: 5
I have been attempting develop a functioning calculator in xcode 9(in vain for now, it seems) but I will need to -somehow- convert a string into code text file. Here's my view controler file(apologies for the extraordinarily sloppy and disorganised code...):
import UIKit
class ViewController: UIViewController {
var calculation_string : String = ""
var displayed = "0"
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
@IBOutlet weak var calc_display: UILabel!
@IBAction func button_pressed(_ sender: UIButton) {
calc_display.text = "asdf"
print(sender.tag)
calculation_string = calculation_string + String(identify(btn_tag: sender.tag))
print(calculation_string)
print(identify(btn_tag: sender.tag))
}
//1-receive and identify the data submitted.
//2-append the string used for calculations from either end; or delete it alltogether depending on the button pressed.
//display on the display area.
func identify(btn_tag: Int) -> String {
if btn_tag == 1 {
return "1"
}
if btn_tag == 2 {
return "2"
}
if btn_tag == 3 {
return "3"
}
if btn_tag == 4 {
return "4"
}
if btn_tag == 5 {
return "5"
}
if btn_tag == 6 {
return "6"
}
if btn_tag == 7 {
return "7"
}
if btn_tag == 8 {
return "8"
}
if btn_tag == 9 {
return "9"
}
if btn_tag == 10 {
return "0"
}
if btn_tag == 11 {
return "."
}
if btn_tag == 13 {
return "+"
}
if btn_tag == 14 {
return "-"
}
if btn_tag == 15 {
return "*"
}
if btn_tag == 16 {
return "/"
}
if btn_tag == 17 {
return "*(0.01)"
}
else {
return ""
}
}
func change_sign() {
calculation_string = "-(" + calculation_string + ")"
}
func equals() {
//makes the value displayed equal to the calculation string
//or returns 'error' if the statement makes no sense or is erroneous.
}
func reset() {
calculation_string = ""
}
}
I will need to convert this 'calculation_string' variable into code, so I can perform calculations and then display it with the 'displayed' variable. Does anyone know how to do this?
I would be equally happy if anyone would consider evaluating and criticising my code, as well as suggest other valid approaches. Once again, apologies for the sloppiness of the code-in-progress.
cheers!
Upvotes: 0
Views: 171
Reputation: 299275
Swift does not have an eval
function like Lisp. You can't create a bunch of Swift code as a string and then execute it at runtime. Instead you need to parse the string yourself and evaluate it.
This isn't trivial, but Nick Lockwood has created a very nice library called Expression that does it. You don't have to use that library, but it's a very good introduction to how to solve the problem. It's about 1500 lines of Swift, and you can work through how it tokenizes and evaluates strings in a pretty straightforward way. (It has some performance optimizations, and it would probably be easier to understand without that, but I still expect you can work your way through with a little work.)
If you want to build this kind of thing from scratch, it is common to first explore building an RPN (Reverse Polish Notation) calculator. This is a stack-based calculator, and is generally much easier to implement than an "infix" calculator. Instead of 1 + 2
you would enter 1 2 +
, and the +
always consumes the last two values on the stack. If you're trying to get into parsers and evaluators, RPN is a great place to start. It's just a lot simpler to implement.
There is also the built-in NSExpression
that will do this for you and is built-in, but it's a pain to work with in Swift, and I don't really recommend it, unless you just need something very quick.
Upvotes: 1
Reputation: 534950
You may be looking for NSExpression, which is available because you have imported Foundation and/or UIKit. There is quite a bit of discussion of calculators built on NSExpression on Stack Overflow already; for example:
NSExpression Calculator in Swift
Upvotes: 0