2
1
Fork 0
pr3-ws202526/go/04-design-pattern/main.go

82 lines
1.9 KiB
Go

package main
import (
"fmt"
"os"
"gitty.informatik.hs-mannheim.de/steger/pr3-code/go/04-design-pattern/patterns"
)
type ConstValueCalculator float64
func NewConstValueCalculator(valueString string) *ConstValueCalculator {
var value float64
if _, err := fmt.Sscanf(valueString, "%f", &value); err != nil {
return nil
}
cvc := ConstValueCalculator(value)
return &cvc
}
func (c ConstValueCalculator) Calc() float64 {
return float64(c)
}
/*
parses the expression and builds a binary calculation tree. Returns the tree, the remaining expression after parsing, and an error
example Input:
1. [2] => 2
2. [+ 2 3] => 5
3. [* 2 3] => 6
4. [+ * 2 3 4] == [+ 6 4] => 10
*/
func buildBinaryCalculationTree(expression []string) (patterns.Calculator, []string, error) {
if len(expression) == 0 {
return nil, nil, fmt.Errorf("empty argument")
}
//1. attempt: try a composite calculator from an operator
composite := patterns.NewCompositeCalculatorFromOperator(expression[0])
if composite != nil {
expression = expression[1:]
for i := 0; i < 2; i++ {
arg, remaining, err := buildBinaryCalculationTree(expression)
if err != nil {
return nil, nil, err
}
expression = remaining
composite.Add(arg)
}
return composite, expression, nil
}
//2. attempt: try a const value calculator from a value
constValue := NewConstValueCalculator(expression[0])
if constValue != nil {
return constValue, expression[1:], nil
}
//3. failure, no valid symbol
return nil, nil, fmt.Errorf("invalid symbol: %s", expression[0])
}
// run for example with go run . + "*" 2 2 4
// note the "*" because * would otherwise expand
func main() {
calc, remainingArgs, err := buildBinaryCalculationTree(os.Args[1:])
if err != nil {
fmt.Println(err)
return
}
if len(remainingArgs) != 0 {
fmt.Println("Invalid Input - remaining arguments", remainingArgs)
return
}
fmt.Println(calc.Calc())
}