| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102 |
- package main
- import (
- "fmt"
- "math"
- "math/rand"
- )
- func opAdd(val1, val2 value) value {
- return value{tp: typeNumber, num: toNumber(val1) + toNumber(val2)}
- }
- func opSub(val1, val2 value) value {
- return value{tp: typeNumber, num: toNumber(val1) - toNumber(val2)}
- }
- func opMul(val1, val2 value) value {
- return value{tp: typeNumber, num: toNumber(val1) * toNumber(val2)}
- }
- func opDiv(val1, val2 value) value {
- num1, num2 := toNumber(val1), toNumber(val2)
- if num2 == 0 {
- panic(fmt.Errorf("div: %s (%f / %f)", errDivisionByZero, num1, num2))
- }
- return value{tp: typeNumber, num: num1 / num2}
- }
- func opMod(val1, val2 value) value {
- num1, num2 := toNumber(val1), toNumber(val2)
- if num2 == 0 {
- panic(fmt.Errorf("mod: %s (%f %% %f)", errDivisionByZero, num1, num2))
- }
- return value{tp: typeNumber, num: math.Mod(num1, num2)}
- }
- func opEq(val1, val2 value) value {
- if isNumber(val1) && isNumber(val2) {
- return value{tp: typeBool, b: toNumber(val1) == toNumber(val2)}
- }
- if isBool(val1) && isBool(val2) {
- return value{tp: typeBool, b: toBool(val1) == toBool(val2)}
- }
- if isWord(val1) && isWord(val2) {
- return value{tp: typeBool, b: escapeWord(val1.word) == escapeWord(val2.word)}
- }
- panic(fmt.Errorf("eq: %s", errIllegalOperandType))
- }
- func opGt(val1, val2 value) value {
- if isNumber(val1) && isNumber(val2) {
- return value{tp: typeBool, b: toNumber(val1) > toNumber(val2)}
- }
- if isBool(val1) && isBool(val2) {
- return value{tp: typeBool, b: toBool(val1) || !toBool(val2)}
- }
- if isWord(val1) && isWord(val2) {
- return value{tp: typeBool, b: escapeWord(val1.word) > escapeWord(val2.word)}
- }
- panic(fmt.Errorf("gt: %s", errIllegalOperandType))
- }
- func opLt(val1, val2 value) value {
- if isNumber(val1) && isNumber(val2) {
- return value{tp: typeBool, b: toNumber(val1) < toNumber(val2)}
- }
- if isBool(val1) && isBool(val2) {
- return value{tp: typeBool, b: !toBool(val1) || toBool(val2)}
- }
- if isWord(val1) && isWord(val2) {
- return value{tp: typeBool, b: escapeWord(val1.word) < escapeWord(val2.word)}
- }
- panic(fmt.Errorf("lt: %s", errIllegalOperandType))
- }
- func opAnd(val1, val2 value) value {
- return value{tp: typeBool, b: toBool(val1) && toBool(val2)}
- }
- func opOr(val1, val2 value) value {
- return value{tp: typeBool, b: toBool(val1) || toBool(val2)}
- }
- func opNot(val1 value) value {
- return value{tp: typeBool, b: !toBool(val1)}
- }
- func opRandom(val1 value) value {
- return value{tp: typeNumber, num: toNumber(val1) * rand.Float64()}
- }
- func opInt(val1 value) value {
- return value{tp: typeNumber, num: math.Floor(toNumber(val1))}
- }
- func opSqrt(val1 value) value {
- num1 := toNumber(val1)
- if num1 < 0 {
- panic(fmt.Errorf("sqrt: %s (%f)", errNegativeSquareRoot, num1))
- }
- return value{tp: typeNumber, num: math.Sqrt(num1)}
- }
|