| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115 |
- package main
- import (
- "fmt"
- "math"
- "math/rand"
- "strconv"
- )
- func opAdd(val1, val2 value) value {
- num1, num2 := toNumber(val1.val), toNumber(val2.val)
- return value{val: strconv.FormatFloat(num1+num2, 'g', -1, 64)}
- }
- func opSub(val1, val2 value) value {
- num1, num2 := toNumber(val1.val), toNumber(val2.val)
- return value{val: strconv.FormatFloat(num1-num2, 'g', -1, 64)}
- }
- func opMul(val1, val2 value) value {
- num1, num2 := toNumber(val1.val), toNumber(val2.val)
- return value{val: strconv.FormatFloat(num1*num2, 'g', -1, 64)}
- }
- func opDiv(val1, val2 value) value {
- num1, num2 := toNumber(val1.val), toNumber(val2.val)
- if num2 == 0 {
- panic(fmt.Errorf("div: %s (%s / %s)", errDivisionByZero, val1.val, val2.val))
- }
- return value{val: strconv.FormatFloat(num1/num2, 'g', -1, 64)}
- }
- func opMod(val1, val2 value) value {
- num1, num2 := toNumber(val1.val), toNumber(val2.val)
- if num2 == 0 {
- panic(fmt.Errorf("mod: %s (%s %% %s)", errDivisionByZero, val1.val, val2.val))
- }
- return value{val: strconv.FormatFloat(math.Mod(num1, num2), 'g', -1, 64)}
- }
- func opEq(val1, val2 value) value {
- if isNumber(val1.val) && isNumber(val2.val) {
- num1, num2 := toNumber(val1.val), toNumber(val2.val)
- return value{val: strconv.FormatBool(num1 == num2)}
- }
- if isBool(val1.val) && isBool(val2.val) {
- b1, b2 := toBool(val1.val), toBool(val2.val)
- return value{val: strconv.FormatBool(b1 == b2)}
- }
- if isWord(val1.val) && isWord(val2.val) {
- return value{val: strconv.FormatBool(val1.val == val2.val)}
- }
- panic(fmt.Errorf("eq: %s (%s, %s)", errIllegalOperandType, val1.val, val2.val))
- }
- func opGt(val1, val2 value) value {
- if isNumber(val1.val) && isNumber(val2.val) {
- num1, num2 := toNumber(val1.val), toNumber(val2.val)
- return value{val: strconv.FormatBool(num1 > num2)}
- }
- if isBool(val1.val) && isBool(val2.val) {
- b1, b2 := toBool(val1.val), toBool(val2.val)
- return value{val: strconv.FormatBool(b1 || !b2)}
- }
- if isWord(val1.val) && isWord(val2.val) {
- return value{val: strconv.FormatBool(val1.val > val2.val)}
- }
- panic(fmt.Errorf("gt: %s (%s, %s)", errIllegalOperandType, val1.val, val2.val))
- }
- func opLt(val1, val2 value) value {
- if isNumber(val1.val) && isNumber(val2.val) {
- num1, num2 := toNumber(val1.val), toNumber(val2.val)
- return value{val: strconv.FormatBool(num1 < num2)}
- }
- if isBool(val1.val) && isBool(val2.val) {
- b1, b2 := toBool(val1.val), toBool(val2.val)
- return value{val: strconv.FormatBool(!b1 || b2)}
- }
- if isWord(val1.val) && isWord(val2.val) {
- return value{val: strconv.FormatBool(val1.val < val2.val)}
- }
- panic(fmt.Errorf("lt: %s (%s, %s)", errIllegalOperandType, val1.val, val2.val))
- }
- func opAnd(val1, val2 value) value {
- b1, b2 := toBool(val1.val), toBool(val2.val)
- return value{val: strconv.FormatBool(b1 && b2)}
- }
- func opOr(val1, val2 value) value {
- b1, b2 := toBool(val1.val), toBool(val2.val)
- return value{val: strconv.FormatBool(b1 || b2)}
- }
- func opNot(val1 value) value {
- b1 := toBool(val1.val)
- return value{val: strconv.FormatBool(!b1)}
- }
- func opRandom(val1 value) value {
- return value{val: strconv.FormatFloat(toNumber(val1.val)*rand.Float64(), 'g', -1, 64)}
- }
- func opInt(val1 value) value {
- return value{val: strconv.FormatFloat(math.Floor(toNumber(val1.val)), 'g', -1, 64)}
- }
- func opSqrt(val1 value) value {
- num1 := toNumber(val1.val)
- if num1 < 0 {
- panic(fmt.Errorf("sqrt: %s (%s)", errNegativeSquareRoot, val1.val))
- }
- return value{val: strconv.FormatFloat(math.Sqrt(num1), 'g', -1, 64)}
- }
|