forked from: basic 4 function calculator
forked from basic 4 function calculator (diff: 117)
ActionScript3 source code
/**
* Copyright ohisama ( http://wonderfl.net/user/ohisama )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/ehTo
*/
// forked from codeonwort's basic 4 function calculator
package
{
import flash.ui.Keyboard;
import flash.events.KeyboardEvent;
import flash.text.TextField;
import flash.display.Sprite;
public class Main extends Sprite
{
private var prompt : TextField, result : TextField
private var input : TextField, output : TextField
private var tokenizer : Tokenizer
public function Main()
{
prompt = label("> ", 0, 0)
input = new TextField
input.type = "input"
input.x = prompt.width
input.width = stage.stageWidth - prompt.width - 5
input.height = prompt.height
input.border = true
//input.borderColor = 0xff0000
input.text = "3*3"
input.addEventListener("keyDown", input_keyDown)
addChild(input)
result = label("= ", 0, prompt.height + 5)
output = new TextField
output.autoSize = "left"
output.width = stage.stageWidth - prompt.width - 5
output.x = result.width
output.y = result.y
addChild(output)
}
private function label(lbl : String, x : Number, y : Number) : TextField
{
var t : TextField = new TextField
t.autoSize = "left"
t.x = x
t.y = y
t.text = lbl
addChild(t)
return t
}
private function input_keyDown(e : KeyboardEvent) : void
{
if (e.keyCode == Keyboard.ENTER)
{
try
{
tokenizer = new Tokenizer(new Expr(input.text))
output.text = expression().toString()
}
catch(err : Error)
{
output.text = err.message
}
}
}
private function expression() : Number
{
var left : Number = term()
var t : Token
while (tokenizer.isEmpty() == false)
{
t = tokenizer.get()
switch (t.kind)
{
case '+' :
left += term()
break
case '-' :
left -= term()
break
default:
tokenizer.putback(t)
return left
}
}
return left
}
private function term() : Number
{
var left : Number = primary()
var t : Token
while (tokenizer.isEmpty() == false)
{
t = tokenizer.get()
switch (t.kind)
{
case '*' :
left *= primary()
break
case '/' :
var d : Number = primary()
if (d == 0) throw new Error("division by 0")
left /= d
break
default :
tokenizer.putback(t)
return left
}
}
return left
}
private function primary() : Number
{
var t : Token = tokenizer.get()
switch (t.kind)
{
case '(' :
var d : Number = expression()
t = tokenizer.get()
if (t.kind != ')') throw new Error("err")
return d
case Token.NUM :
return t.value
case '+' :
return primary()
case '-' :
return -primary()
default :
throw new Error("err")
}
}
}
}
class Expr
{
private var str : String
public function Expr(s : String)
{
str = ""
for (var i : int = 0; i < s.length; i++)
{
if (s.charAt(i) != " ") str += s.charAt(i)
}
}
public function get() : String
{
var ch : String = str.charAt(0)
str = str.substr(1)
return ch
}
public function putback(ch : String) : void
{
str = ch + str
}
public function isEmpty() : Boolean
{
return str.length == 0
}
}
class Token
{
public static const NUM : String = 'n'
public var kind : String
public var value : Number
public function Token(k : String, v : Number = NaN)
{
kind = k
value = v
}
}
class Tokenizer
{
private var full : Boolean = false
private var buffer : Vector.<Token>
private var expr : Expr
public function Tokenizer(e : Expr)
{
expr = e
buffer = new Vector.<Token>
var char : String
var tok : Token
lbl : while (expr.isEmpty() == false)
{
char = expr.get()
switch (char)
{
case '(' :
case ')' :
case '+' :
case '-' :
case '*' :
case '/' :
tok = new Token(char)
break
case '.' :
case '0' :
case '1' :
case '2' :
case '3' :
case '4' :
case '5' :
case '6' :
case '7' :
case '8' :
case '9' :
expr.putback(char)
tok = new Token(Token.NUM, getNumber())
break
default :
throw new Error("invalid token")
}
buffer.unshift(tok)
}
}
public function get() : Token
{
if (buffer.length != 0)
{
return buffer.pop()
}
throw new Error("buffer is empty")
}
public function isEmpty() : Boolean
{
return buffer.length == 0
}
private function getNumber() : Number
{
var str : String = ""
var ch : String
lbl : while (true)
{
ch = expr.get()
switch (ch)
{
case '.' :
case '0' :
case '1' :
case '2' :
case '3' :
case '4' :
case '5' :
case '6' :
case '7' :
case '8' :
case '9' :
str += ch
break
default :
expr.putback(ch)
break lbl
}
}
var n : Number = Number(str)
if (isNaN(n)) throw new Error("invalid number representation")
return n
}
public function putback(t : Token) : void
{
buffer.push(t)
}
}