// 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 ( "fmt" "git.portale-stac.it/go-pkg/expr/kern" ) // -------- 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 kern.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 = opTerm.errDivisionByZero() return } if den < 0 { den = -den num = -num } if num != 0 { if g := kern.Gcd(num, den); g != 1 { num = num / g den = den / g } if den == 1 { v = num } else { // v = &expr.FractionType{num, den} v = kern.NewFraction(num, den) } } else { // v = &FractionType{0, den} v = kern.NewFraction(0, den) } return } // init func init() { // registerTermConstructor(SymVertBar, newFractionTerm) registerTermConstructor(SymColon, newFractionTerm) }