import State
import io
import structures_lib

type StateType = {
    addDigit(_:Number)->Void
    doOp(_:String)->Void
    enter->Void
    clear->Void
    pop->Void
    exchange->Void}

var calcState:StateType is readable := State.new

var istream is readable:= io.input

print "Type in a valid entry and hit return to \"press button\""

print "Valid entries: 0 1 2 3 4 5 6 7 8 9 + - \ * clear pop exch enter quit"

// return next string entered (equivalent to pressing button)
method getEntry->String is confidential{
    var str := ""
    var nxt := istream.next
    while{nxt != "\n"} do {
        str := str ++ nxt
        nxt := istream.next
    }
    return str
}

// processes entries as they're entered
method calculate->Boolean is confidential{
    var entry := getEntry
    var ret:Boolean := false
    if(entry.size == 1) then{
        if((entry.ord <= 57) && (entry.ord >= 48)) then{
            calcState.addDigit(entry.asNumber)
        }
        else{
            if((entry == "/") || (entry == "*") || (entry == "+") || (entry == "-")) then{
                calcState.doOp(entry)
            }
            else{print "Error: invalid character"}
        }
    }
    else{
        if(entry == "enter") then {calcState.enter}
        else {if(entry == "pop") then {calcState.pop}
              else{if(entry == "clear") then {calcState.clear}
                   else {if(entry == "exch") then {calcState.exchange}
                         else {if(entry == "quit") then {return true}
                              else{print "Not a valid command"}}}}}
    }
    return ret
}

var done:Boolean is readable := false

// calculator runs until user enter "quit"
// exits with error at eof
while{!istream.eof && !done} do {done := calculate}