module Main exposing (..) import Html exposing (..) import Html.Attributes exposing (..) import Html.Events exposing (..) import Expr exposing (Expr(..), OpName) import Eval exposing (eval) import Ratio main = Html.beginnerProgram { model = model, update = update, view = view } type alias Model = { result : Result String (List Eval.Value) , expression : String } model : Model model = { result = Ok [] , expression = "" } type Msg = ExpressionTyped String update : Msg -> Model -> Model update msg model = case msg of ExpressionTyped str -> Expr.parse ("(" ++ str ++ ")") -- wrap str in brackets so it's recognized as a group |> Result.andThen (eval >> Result.mapError Eval.prettyPrintError) |> \r -> { model | result = r, expression = str } error : String -> Html a error err = div [class "error"] [text err] stackItem : Eval.Value -> Html a stackItem n = let asString = Eval.prettyPrintValue n minWidth = toString (String.length asString) ++ "em" in div [class "item", style [("min-width", minWidth)]] [text asString] view : Model -> Html Msg view model = let calcOutput = case model.result of Ok stack -> List.reverse stack -- Puts first items at the top, for nicer looks |> List.map stackItem Err outputError -> [error outputError] in div [class "rpncalc"] ( [ div [] calcOutput , input [onInput ExpressionTyped, value model.expression, class "exprinput"] [] ] )