forked from steger/pr3-ws202526
82 lines
1.9 KiB
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())
|
|
}
|