// 7. hét – Postfix kifejezés kiértékelése veremmel
// Futtatás: go run ./h07/postfix
package main

import (
	"fmt"
	"strconv"
	"strings"
)

func evaluate(expr string, trace bool) (float64, error) {
	var st []float64
	for _, t := range strings.Fields(expr) {
		switch t {
		case "+", "-", "*", "/":
			if len(st) < 2 {
				return 0, fmt.Errorf("hibás kifejezés: kevés operandus a(z) %q előtt", t)
			}
			b, a := st[len(st)-1], st[len(st)-2] // előbb a JOBB oldali operandus jön ki!
			st = st[:len(st)-2]
			var r float64
			switch t {
			case "+":
				r = a + b
			case "-":
				r = a - b
			case "*":
				r = a * b
			default:
				r = a / b
			}
			st = append(st, r)
		default:
			v, err := strconv.ParseFloat(t, 64)
			if err != nil {
				return 0, fmt.Errorf("ismeretlen token: %q", t)
			}
			st = append(st, v)
		}
		if trace {
			fmt.Printf("  %-4s verem (alulról): %v\n", t, st)
		}
	}
	if len(st) != 1 {
		return 0, fmt.Errorf("hibás kifejezés")
	}
	return st[0], nil
}

func main() {
	fmt.Println("3 4 + 2 *  (= (3 + 4) * 2)")
	r, _ := evaluate("3 4 + 2 *", true)
	fmt.Println("eredmény:", r)

	fmt.Println("\n1 2 + 3 4 * - 9 /")
	r, _ = evaluate("1 2 + 3 4 * - 9 /", true)
	fmt.Println("eredmény:", r)

	if _, err := evaluate("1 +", false); err != nil {
		fmt.Println("\nHiba:", err)
	}
}
