// Copyright (c) 2024 Celestino Amoroso (celestino.amoroso@gmail.com). // All rights reserved. // operand-fraction.go package expr //https://www.youmath.it/lezioni/algebra-elementare/lezioni-di-algebra-e-aritmetica-per-scuole-medie/553-dalle-frazioni-a-numeri-decimali.html import ( "errors" "fmt" ) // -------- fraction term func newFractionTerm(tk *Token) *term { return &term{ tk: *tk, parent: nil, children: make([]*term, 0, 2), position: posInfix, priority: priFraction, evalFunc: evalFraction, } } // -------- eval func func evalFraction(ctx ExprContext, opTerm *term) (v any, err error) { var numValue, denValue any var num, den int64 var ok bool if numValue, denValue, err = opTerm.evalInfix(ctx); err != nil { return } if num, ok = numValue.(int64); !ok { err = fmt.Errorf("numerator must be integer, got %T (%v)", numValue, numValue) return } if den, ok = denValue.(int64); !ok { err = fmt.Errorf("denominator must be integer, got %T (%v)", denValue, denValue) return } if den == 0 { err = errors.New("division by zero") return } if den < 0 { den = -den num = -num } g := gcd(num, den) num = num / g den = den / g if den == 1 { v = num } else { v = &FractionType{num, den} } return } // init func init() { registerTermConstructor(SymVertBar, newFractionTerm) // registerTermConstructor(SymColon, newFractionTerm) }