start moving numbers to oop

This commit is contained in:
2024-07-09 14:05:21 +01:00
parent 3761070e82
commit 7c23db80d4
11 changed files with 333 additions and 242 deletions

View File

@@ -40,38 +40,28 @@ func parseAbs(code UNPARSEcode, index int, codelines []UNPARSEcode) (any, bool,
} }
func runAbs(x ABS, stack stack, stacklevel int) (any, ArErr) { func runAbs(x ABS, stack stack, stacklevel int) (any, ArErr) {
resp, err := runVal(x.body, stack, stacklevel+1) value, err := runVal(x, stack, stacklevel+1)
if err.EXISTS { if err.EXISTS {
return nil, err return nil, err
} }
if typeof(resp) != "number" { switch value := value.(type) {
return nil, ArErr{TYPE: "Runtime Error", case ArObject:
message: fmt.Sprintf("abs expected number, got %s", typeof(resp)), if Callable, ok := value.obj["__abs__"]; ok {
EXISTS: true, return runCall(call{
Callable: Callable,
Args: []any{},
Code: x.code,
Line: x.line,
Path: x.path,
}, stack, stacklevel)
} }
} }
return abs(resp.(number)), ArErr{} return nil, ArErr{
"TypeError",
fmt.Sprint("abs() not supported on ", typeof(value)),
x.line,
x.path,
x.code,
true,
}
} }
func abs(x number) number {
if x.Sign() < 0 {
return x.Neg(x)
}
return x
}
var ArAbs = builtinFunc{"abs", func(args ...any) (any, ArErr) {
if len(args) != 1 {
return nil, ArErr{TYPE: "Runtime Error",
message: fmt.Sprintf("abs expected 1 argument, got %d", len(args)),
EXISTS: true,
}
}
if typeof(args[0]) != "number" {
return nil, ArErr{TYPE: "Runtime Error",
message: fmt.Sprintf("abs expected number, got %s", typeof(args[0])),
EXISTS: true,
}
}
return abs(args[0].(number)), ArErr{}
}}

View File

@@ -8,8 +8,6 @@ func anyToBool(x any) bool {
switch x := x.(type) { switch x := x.(type) {
case string: case string:
return x != "" return x != ""
case number:
return x.Cmp(newNumber()) != 0
case bool: case bool:
return x return x
case nil: case nil:

View File

@@ -5,6 +5,8 @@ import (
"fmt" "fmt"
) )
var one = newNumber().SetInt64(1)
func ArByte(Byte byte) ArObject { func ArByte(Byte byte) ArObject {
obj := ArObject{ obj := ArObject{
obj: anymap{ obj: anymap{

View File

@@ -193,7 +193,6 @@ func makeGlobal() ArObject {
vars["todeg"] = ArToDeg vars["todeg"] = ArToDeg
vars["colour"] = ArColour vars["colour"] = ArColour
vars["torad"] = ArToRad vars["torad"] = ArToRad
vars["abs"] = ArAbs
vars["fraction"] = builtinFunc{"fraction", func(a ...any) (any, ArErr) { vars["fraction"] = builtinFunc{"fraction", func(a ...any) (any, ArErr) {
if len(a) == 0 { if len(a) == 0 {
return nil, ArErr{TYPE: "fraction", message: "fraction takes 1 argument", return nil, ArErr{TYPE: "fraction", message: "fraction takes 1 argument",

View File

@@ -35,7 +35,8 @@ func debugInit() {
} }
func debugPrintln(a ...any) { func debugPrintln(a ...any) {
if debug { switch debug {
case true:
__debugPrintsLock.Lock() __debugPrintsLock.Lock()
__debugPrints = append(__debugPrints, a) __debugPrints = append(__debugPrints, a)
__debugPrintsLock.Unlock() __debugPrintsLock.Unlock()

View File

@@ -23,11 +23,6 @@ func isNumber(code UNPARSEcode) bool {
return numberCompile.MatchString(code.code) || binaryCompile.MatchString(code.code) || hexCompile.MatchString(code.code) || octalCompile.MatchString(code.code) return numberCompile.MatchString(code.code) || binaryCompile.MatchString(code.code) || hexCompile.MatchString(code.code) || octalCompile.MatchString(code.code)
} }
func isAnyNumber(x any) bool {
_, ok := x.(number)
return ok
}
// converts a number type to a string // converts a number type to a string
func numberToString(num number, simplify bool) string { func numberToString(num number, simplify bool) string {
if simplify { if simplify {
@@ -51,7 +46,135 @@ func numberToString(num number, simplify bool) string {
} }
// returns translateNumber, success, error // returns translateNumber, success, error
func parseNumber(code UNPARSEcode) (number, bool, ArErr, int) { func parseNumber(code UNPARSEcode) (compiledNumber, bool, ArErr, int) {
output, _ := newNumber().SetString(strings.TrimSpace(code.code)) output, _ := new(big.Rat).SetString(strings.TrimSpace(code.code))
return output, true, ArErr{}, 1 if !output.IsInt() {
return compiledNumber{output}, true, ArErr{}, 1
}
return compiledNumber{output.Num()}, true, ArErr{}, 1
}
type compiledNumber = struct {
value any
}
var _zero = big.NewInt(0)
func Number(number compiledNumber) ArObject {
// copy value to new number
var value any = number.value
val := ArObject{
anymap{
"__name__": "number",
},
}
switch x := value.(type) {
case *big.Rat:
if x.IsInt() {
value = x.Num()
}
case *big.Int:
default:
panic("invalid number type")
}
val.obj["__value__"] = value
switch CurrentNumber := value.(type) {
case *big.Int:
val.obj["__string__"] = builtinFunc{
"__string__",
func(a ...any) (any, ArErr) {
return fmt.Sprint(CurrentNumber), ArErr{}
},
}
val.obj["__repr__"] = builtinFunc{
"__repr__",
func(a ...any) (any, ArErr) {
if len(a) != 1 {
return nil, ArErr{"Type Error", "expected 1 argument, got " + fmt.Sprint(len(a)), 0, "", "", true}
}
if typeof(a[0]) != "boolean" {
return nil, ArErr{"Type Error", "expected boolean, got " + typeof(a[0]), 0, "", "", true}
}
coloured := a[0].(bool)
output := []string{}
if coloured {
output = append(output, "\x1b[34;5;240m")
}
output = append(output, fmt.Sprint(CurrentNumber))
if coloured {
output = append(output, "\x1b[0m")
}
return strings.Join(output, ""), ArErr{}
},
}
val.obj["__Boolean__"] = builtinFunc{
"__Boolean__",
func(a ...any) (any, ArErr) {
return _zero, ArErr{}
},
}
val.obj["__Add__"] = builtinFunc{
"__Add__",
func(a ...any) (any, ArErr) {
if len(a) != 1 {
return nil, ArErr{"Type Error", "expected 1 argument, got " + fmt.Sprint(len(a)), 0, "", "", true}
}
if typeof(a[0]) != "number" {
return nil, ArErr{"Type Error", "expected number, got " + typeof(a[0]), 0, "", "", true}
}
a[0] = ArValidToAny(a[0])
switch ReceivingNumber := a[0].(type) {
case *big.Int:
return Number(compiledNumber{new(big.Int).Add(CurrentNumber, ReceivingNumber)}), ArErr{}
}
return nil, ArErr{"Type Error", "expected number, got " + typeof(a[0]), 0, "", "", true}
},
}
val.obj["__PostAdd__"] = builtinFunc{
"__PostAdd__",
val.obj["__Add__"].(builtinFunc).FUNC,
}
val.obj["__Subtract__"] = builtinFunc{
"__Subtract__",
func(a ...any) (any, ArErr) {
if len(a) != 1 {
return nil, ArErr{"Type Error", "expected 1 argument, got " + fmt.Sprint(len(a)), 0, "", "", true}
}
if typeof(a[0]) != "number" {
return nil, ArErr{"Type Error", "expected number, got " + typeof(a[0]), 0, "", "", true}
}
a[0] = ArValidToAny(a[0])
switch ReceivingNumber := a[0].(type) {
case *big.Int:
return Number(compiledNumber{new(big.Int).Sub(CurrentNumber, ReceivingNumber)}), ArErr{}
}
return nil, ArErr{"Type Error", "expected number, got " + typeof(a[0]), 0, "", "", true}
},
}
val.obj["__PostSubtract__"] = builtinFunc{
"__PostSubtract__",
func(a ...any) (any, ArErr) {
if len(a) != 1 {
return nil, ArErr{"Type Error", "expected 1 argument, got " + fmt.Sprint(len(a)), 0, "", "", true}
}
if typeof(a[0]) != "number" {
return nil, ArErr{"Type Error", "expected number, got " + typeof(a[0]), 0, "", "", true}
}
a[0] = ArValidToAny(a[0])
switch ReceivingNumber := a[0].(type) {
case *big.Int:
return Number(compiledNumber{new(big.Int).Sub(ReceivingNumber, CurrentNumber)}), ArErr{}
}
return nil, ArErr{"Type Error", "expected number, got " + typeof(a[0]), 0, "", "", true}
},
}
case *big.Rat:
panic("not implemented")
}
return val
} }

View File

@@ -2,7 +2,6 @@ package main
import ( import (
"fmt" "fmt"
"math"
"reflect" "reflect"
"strings" "strings"
) )
@@ -27,8 +26,6 @@ var operations = []string{
"^", "^",
} }
var one = newNumber().SetInt64(1)
type operationType struct { type operationType struct {
operation int operation int
values []any values []any
@@ -120,9 +117,7 @@ func compareValues(o operationType, stack stack, stacklevel int) (bool, ArErr) {
} }
switch o.operation { switch o.operation {
case 4: case 4:
if isAnyNumber(resp) && isAnyNumber(resp2) { if x, ok := resp.(ArObject); ok {
return resp.(number).Cmp(resp2.(number)) <= 0, ArErr{}
} else if x, ok := resp.(ArObject); ok {
if y, ok := x.obj["__LessThanEqual__"]; ok { if y, ok := x.obj["__LessThanEqual__"]; ok {
val, err := runCall( val, err := runCall(
call{ call{
@@ -147,9 +142,7 @@ func compareValues(o operationType, stack stack, stacklevel int) (bool, ArErr) {
true, true,
} }
case 5: case 5:
if isAnyNumber(resp) && isAnyNumber(resp2) { if x, ok := resp.(ArObject); ok {
return resp.(number).Cmp(resp2.(number)) >= 0, ArErr{}
} else if x, ok := resp.(ArObject); ok {
if y, ok := x.obj["__GreaterThanEqual__"]; ok { if y, ok := x.obj["__GreaterThanEqual__"]; ok {
val, err := runCall( val, err := runCall(
call{ call{
@@ -174,9 +167,7 @@ func compareValues(o operationType, stack stack, stacklevel int) (bool, ArErr) {
true, true,
} }
case 6: case 6:
if isAnyNumber(resp) && isAnyNumber(resp2) { if x, ok := resp.(ArObject); ok {
return resp.(number).Cmp(resp2.(number)) < 0, ArErr{}
} else if x, ok := resp.(ArObject); ok {
if y, ok := x.obj["__LessThan__"]; ok { if y, ok := x.obj["__LessThan__"]; ok {
val, err := runCall( val, err := runCall(
call{ call{
@@ -201,9 +192,7 @@ func compareValues(o operationType, stack stack, stacklevel int) (bool, ArErr) {
true, true,
} }
case 7: case 7:
if isAnyNumber(resp) && isAnyNumber(resp2) { if x, ok := resp.(ArObject); ok {
return resp.(number).Cmp(resp2.(number)) > 0, ArErr{}
} else if x, ok := resp.(ArObject); ok {
if y, ok := x.obj["__GreaterThan__"]; ok { if y, ok := x.obj["__GreaterThan__"]; ok {
val, err := runCall( val, err := runCall(
call{ call{
@@ -253,9 +242,6 @@ func calcNegative(o operationType, stack stack, stacklevel int) (any, ArErr) {
return nil, err return nil, err
} }
output := resp output := resp
if isAnyNumber(resp) {
output = newNumber().Set(resp.(number))
}
for i := 1; i < len(o.values); i++ { for i := 1; i < len(o.values); i++ {
resp, err := runVal( resp, err := runVal(
o.values[i], o.values[i],
@@ -265,10 +251,7 @@ func calcNegative(o operationType, stack stack, stacklevel int) (any, ArErr) {
if err.EXISTS { if err.EXISTS {
return nil, err return nil, err
} }
if typeof(output) == "number" && typeof(resp) == "number" { if x, ok := output.(ArObject); ok {
output = output.(number).Sub(output.(number), resp.(number))
continue
} else if x, ok := output.(ArObject); ok {
if y, ok := x.obj["__Subtract__"]; ok { if y, ok := x.obj["__Subtract__"]; ok {
val, err := runCall( val, err := runCall(
call{ call{
@@ -309,9 +292,6 @@ func calcDivide(o operationType, stack stack, stacklevel int) (any, ArErr) {
return nil, err return nil, err
} }
output := resp output := resp
if isAnyNumber(resp) {
output = newNumber().Set(resp.(number))
}
for i := 1; i < len(o.values); i++ { for i := 1; i < len(o.values); i++ {
resp, err := runVal( resp, err := runVal(
o.values[i], o.values[i],
@@ -322,20 +302,7 @@ func calcDivide(o operationType, stack stack, stacklevel int) (any, ArErr) {
if err.EXISTS { if err.EXISTS {
return nil, err return nil, err
} }
if typeof(resp) == "number" && typeof(output) == "number" { if x, ok := output.(ArObject); ok {
if resp.(number).Cmp(newNumber().SetInt64(0)) == 0 {
return nil, ArErr{
"Runtime Error",
"Cannot divide by zero",
o.line,
o.path,
o.code,
true,
}
}
output = output.(number).Quo(output.(number), resp.(number))
continue
} else if x, ok := output.(ArObject); ok {
if y, ok := x.obj["__Divide__"]; ok { if y, ok := x.obj["__Divide__"]; ok {
val, err := runCall( val, err := runCall(
call{ call{
@@ -375,9 +342,6 @@ func calcAdd(o operationType, stack stack, stacklevel int) (any, ArErr) {
return nil, err return nil, err
} }
var output any = resp var output any = resp
if typeof(output) == "number" {
output = newNumber().Set(output.(number))
}
for i := 1; i < len(o.values); i++ { for i := 1; i < len(o.values); i++ {
resp, err := runVal( resp, err := runVal(
o.values[i], o.values[i],
@@ -387,10 +351,7 @@ func calcAdd(o operationType, stack stack, stacklevel int) (any, ArErr) {
if err.EXISTS { if err.EXISTS {
return nil, err return nil, err
} }
if typeof(output) == "number" && typeof(resp) == "number" { if x, ok := output.(ArObject); ok {
output = output.(number).Add(output.(number), resp.(number))
continue
} else if x, ok := output.(ArObject); ok {
if y, ok := x.obj["__Add__"]; ok { if y, ok := x.obj["__Add__"]; ok {
val, err := runCall( val, err := runCall(
call{ call{
@@ -400,13 +361,28 @@ func calcAdd(o operationType, stack stack, stacklevel int) (any, ArErr) {
o.line, o.line,
o.path, o.path,
}, stack, stacklevel+1) }, stack, stacklevel+1)
if err.EXISTS { if !err.EXISTS {
return nil, err
}
output = val output = val
continue continue
} }
} }
}
if x, ok := resp.(ArObject); ok {
if y, ok := x.obj["__PostAdd__"]; ok {
val, err := runCall(
call{
y,
[]any{output},
o.code,
o.line,
o.path,
}, stack, stacklevel+1)
if !err.EXISTS {
output = val
continue
}
}
}
return nil, ArErr{ return nil, ArErr{
"Runtime Error", "Runtime Error",
"Cannot add type '" + typeof(resp) + "' to type '" + typeof(output) + "'", "Cannot add type '" + typeof(resp) + "' to type '" + typeof(output) + "'",
@@ -416,7 +392,7 @@ func calcAdd(o operationType, stack stack, stacklevel int) (any, ArErr) {
true, true,
} }
} }
return (output), ArErr{} return output, ArErr{}
} }
func calcMul(o operationType, stack stack, stacklevel int) (any, ArErr) { func calcMul(o operationType, stack stack, stacklevel int) (any, ArErr) {
@@ -430,9 +406,6 @@ func calcMul(o operationType, stack stack, stacklevel int) (any, ArErr) {
return nil, err return nil, err
} }
var output any = resp var output any = resp
if isAnyNumber(resp) {
output = newNumber().Set(resp.(number))
}
for i := 1; i < len(o.values); i++ { for i := 1; i < len(o.values); i++ {
resp, err := runVal( resp, err := runVal(
o.values[i], o.values[i],
@@ -442,10 +415,7 @@ func calcMul(o operationType, stack stack, stacklevel int) (any, ArErr) {
if err.EXISTS { if err.EXISTS {
return nil, err return nil, err
} }
if typeof(output) == "number" && typeof(resp) == "number" { if x, ok := output.(ArObject); ok {
output = output.(number).Mul(output.(number), resp.(number))
continue
} else if x, ok := output.(ArObject); ok {
if y, ok := x.obj["__Multiply__"]; ok { if y, ok := x.obj["__Multiply__"]; ok {
val, err := runCall( val, err := runCall(
call{ call{
@@ -455,13 +425,12 @@ func calcMul(o operationType, stack stack, stacklevel int) (any, ArErr) {
o.line, o.line,
o.path, o.path,
}, stack, stacklevel+1) }, stack, stacklevel+1)
if err.EXISTS { if !err.EXISTS {
return nil, err
}
output = val output = val
continue continue
} }
} }
}
return nil, ArErr{ return nil, ArErr{
"Runtime Error", "Runtime Error",
"Cannot multiply type '" + typeof(resp) + "'", "Cannot multiply type '" + typeof(resp) + "'",
@@ -624,9 +593,7 @@ func calcIn(o operationType, stack stack, stacklevel int) (any, ArErr) {
} }
} }
func notequals(a any, b any, o operationType, stack stack, stacklevel int) (bool, ArErr) { func notequals(a any, b any, o operationType, stack stack, stacklevel int) (bool, ArErr) {
if typeof(a) == "number" && typeof(b) == "number" { if x, ok := a.(ArObject); ok {
return a.(number).Cmp(b.(number)) != 0, ArErr{}
} else if x, ok := a.(ArObject); ok {
if y, ok := x.obj["__NotEqual__"]; ok { if y, ok := x.obj["__NotEqual__"]; ok {
val, err := runCall( val, err := runCall(
call{ call{
@@ -662,9 +629,7 @@ func notequals(a any, b any, o operationType, stack stack, stacklevel int) (bool
func equals(a any, b any, o operationType, stack stack, stacklevel int) (bool, ArErr) { func equals(a any, b any, o operationType, stack stack, stacklevel int) (bool, ArErr) {
debugPrintln("equals", a, b) debugPrintln("equals", a, b)
if typeof(a) == "number" && typeof(b) == "number" { if x, ok := a.(ArObject); ok {
return a.(number).Cmp(b.(number)) == 0, ArErr{}
} else if x, ok := a.(ArObject); ok {
if y, ok := x.obj["__Equal__"]; ok { if y, ok := x.obj["__Equal__"]; ok {
val, err := runCall( val, err := runCall(
call{ call{
@@ -708,9 +673,6 @@ func calcMod(o operationType, stack stack, stacklevel int) (any, ArErr) {
return nil, err return nil, err
} }
output := resp output := resp
if isAnyNumber(resp) {
output = newNumber().Set(resp.(number))
}
for i := 1; i < len(o.values); i++ { for i := 1; i < len(o.values); i++ {
resp, err := runVal( resp, err := runVal(
o.values[i], o.values[i],
@@ -721,14 +683,7 @@ func calcMod(o operationType, stack stack, stacklevel int) (any, ArErr) {
if err.EXISTS { if err.EXISTS {
return nil, err return nil, err
} }
if typeof(resp) == "number" && typeof(output) == "number" { if x, ok := output.(ArObject); ok {
x := newNumber().Set(resp.(number))
x.Quo(output.(number), x)
x = floor(x)
x.Mul(x, resp.(number))
output.(number).Sub(output.(number), x)
continue
} else if x, ok := output.(ArObject); ok {
if y, ok := x.obj["__Modulo__"]; ok { if y, ok := x.obj["__Modulo__"]; ok {
val, err := runCall( val, err := runCall(
call{ call{
@@ -767,9 +722,6 @@ func calcIntDiv(o operationType, stack stack, stacklevel int) (any, ArErr) {
return nil, err return nil, err
} }
output := resp output := resp
if isAnyNumber(resp) {
output = newNumber().Set(resp.(number))
}
for i := 1; i < len(o.values); i++ { for i := 1; i < len(o.values); i++ {
resp, err := runVal( resp, err := runVal(
o.values[i], o.values[i],
@@ -780,10 +732,7 @@ func calcIntDiv(o operationType, stack stack, stacklevel int) (any, ArErr) {
if err.EXISTS { if err.EXISTS {
return nil, err return nil, err
} }
if typeof(resp) == "number" && typeof(output) == "number" { if x, ok := output.(ArObject); ok {
output = floor(output.(number).Quo(output.(number), resp.(number)))
continue
} else if x, ok := output.(ArObject); ok {
if y, ok := x.obj["__IntDivide__"]; ok { if y, ok := x.obj["__IntDivide__"]; ok {
val, err := runCall( val, err := runCall(
call{ call{
@@ -812,93 +761,142 @@ func calcIntDiv(o operationType, stack stack, stacklevel int) (any, ArErr) {
return output, ArErr{} return output, ArErr{}
} }
func calcPower(o operationType, stack stack, stacklevel int) (number, ArErr) { // func calcPower(o operationType, stack stack, stacklevel int) (number, ArErr) {
// resp, err := runVal(
// o.values[0],
// stack,
// stacklevel+1,
// )
// resp = ArValidToAny(resp)
// if err.EXISTS {
// return nil, err
// }
// if typeof(resp) != "number" {
// return nil, ArErr{
// "Runtime Error",
// "Cannot calculate power of type '" + typeof(resp) + "'",
// o.line,
// o.path,
// o.code,
// true,
// }
// }
// output := newNumber().Set(resp.(number))
// for i := 1; i < len(o.values); i++ {
// resp, err := runVal(
// o.values[i],
// stack,
// stacklevel+1,
// )
// resp = ArValidToAny(resp)
// if err.EXISTS {
// return nil, err
// }
// if typeof(resp) == "number" {
// n := newNumber().Set(resp.(number))
// if n.Cmp(newNumber().SetInt64(10)) <= 0 {
// toOut := newNumber().SetInt64(1)
// clone := newNumber().Set(output)
// nAbs := (abs(newNumber().Set(n)))
// j := newNumber()
// for ; j.Cmp(nAbs) < 0; j.Add(j, one) {
// toOut.Mul(toOut, clone)
// }
// nAbs.Sub(nAbs, j)
// if nAbs.Cmp(newNumber()) < 0 {
// j.Sub(j, one)
// n1, _ := toOut.Float64()
// n2, _ := nAbs.Float64()
// calculated := newNumber().SetFloat64(math.Pow(n1, n2))
// if calculated == nil {
// calculated = infinity
// }
// toOut.Mul(toOut, calculated)
// }
// if n.Cmp(newNumber()) < 0 {
// toOut.Quo(newNumber().SetInt64(1), toOut)
// }
// output.Set(toOut)
// } else if n.Cmp(newNumber().SetInt64(1)) != 0 {
// n1, _ := output.Float64()
// n2, _ := n.Float64()
// calculated := newNumber().SetFloat64(math.Pow(n1, n2))
// if calculated == nil {
// calculated = infinity
// }
// output.Mul(output, calculated)
// }
// /*
// n1, _ := output.Float64()
// n2, _ := resp.(number).Float64()
// output = newNumber().SetFloat64(math.Pow(n1, n2))
// if output == nil {
// output = infinity
// }
// */
// } else {
// return nil, ArErr{
// "Runtime Error",
// "Cannot calculate power of type '" + typeof(resp) + "'",
// o.line,
// o.path,
// o.code,
// true,
// }
// }
// }
// return output, ArErr{}
// }
func calcPower(o operationType, stack stack, stacklevel int) (any, ArErr) {
resp, err := runVal( resp, err := runVal(
o.values[0], o.values[0],
stack, stack,
stacklevel+1, stacklevel+1,
) )
resp = ArValidToAny(resp)
if err.EXISTS { if err.EXISTS {
return nil, err return nil, err
} }
if typeof(resp) != "number" { var output any = resp
return nil, ArErr{
"Runtime Error",
"Cannot calculate power of type '" + typeof(resp) + "'",
o.line,
o.path,
o.code,
true,
}
}
output := newNumber().Set(resp.(number))
for i := 1; i < len(o.values); i++ { for i := 1; i < len(o.values); i++ {
resp, err := runVal( resp, err := runVal(
o.values[i], o.values[i],
stack, stack,
stacklevel+1, stacklevel+1,
) )
resp = ArValidToAny(resp)
if err.EXISTS { if err.EXISTS {
return nil, err return nil, err
} }
if typeof(resp) == "number" { if x, ok := output.(ArObject); ok {
n := newNumber().Set(resp.(number)) if y, ok := x.obj["__Power__"]; ok {
if n.Cmp(newNumber().SetInt64(10)) <= 0 { val, err := runCall(
toOut := newNumber().SetInt64(1) call{
clone := newNumber().Set(output) y,
nAbs := (abs(newNumber().Set(n))) []any{resp},
j := newNumber() o.code,
for ; j.Cmp(nAbs) < 0; j.Add(j, one) { o.line,
toOut.Mul(toOut, clone) o.path,
}, stack, stacklevel+1)
if err.EXISTS {
return nil, err
} }
output = val
nAbs.Sub(nAbs, j) continue
if nAbs.Cmp(newNumber()) < 0 {
j.Sub(j, one)
n1, _ := toOut.Float64()
n2, _ := nAbs.Float64()
calculated := newNumber().SetFloat64(math.Pow(n1, n2))
if calculated == nil {
calculated = infinity
} }
toOut.Mul(toOut, calculated)
} }
if n.Cmp(newNumber()) < 0 {
toOut.Quo(newNumber().SetInt64(1), toOut)
}
output.Set(toOut)
} else if n.Cmp(newNumber().SetInt64(1)) != 0 {
n1, _ := output.Float64()
n2, _ := n.Float64()
calculated := newNumber().SetFloat64(math.Pow(n1, n2))
if calculated == nil {
calculated = infinity
}
output.Mul(output, calculated)
}
/*
n1, _ := output.Float64()
n2, _ := resp.(number).Float64()
output = newNumber().SetFloat64(math.Pow(n1, n2))
if output == nil {
output = infinity
}
*/
} else {
return nil, ArErr{ return nil, ArErr{
"Runtime Error", "Runtime Error",
"Cannot calculate power of type '" + typeof(resp) + "'", "Cannot power type '" + typeof(resp) + "' to type '" + typeof(output) + "'",
o.line, o.line,
o.path, o.path,
o.code, o.code,
true, true,
} }
} }
} return (output), ArErr{}
return output, ArErr{}
} }
func runOperation(o operationType, stack stack, stacklevel int) (any, ArErr) { func runOperation(o operationType, stack stack, stacklevel int) (any, ArErr) {

View File

@@ -56,30 +56,30 @@ func runVal(line any, stack stack, stacklevel int) (any, ArErr) {
break break
} }
return setVariableValue(x, stack, stacklevel+1) return setVariableValue(x, stack, stacklevel+1)
case negative: // case negative:
if stackoverflow { // if stackoverflow {
linenum = x.line // linenum = x.line
path = x.path // path = x.path
code = x.code // code = x.code
break // break
} // }
resp, err := runVal(x.VAL, stack, stacklevel+1) // resp, err := runVal(x.VAL, stack, stacklevel+1)
resp = AnyToArValid(resp) // resp = AnyToArValid(resp)
if err.EXISTS { // if err.EXISTS {
return nil, err // return nil, err
} // }
switch y := resp.(type) { // switch y := resp.(type) {
case number: // case compiledNumber:
if !x.sign { // if !x.sign {
return newNumber().Neg(y), ArErr{} // return Number(compiledNumber{new(big.Rat).Neg(y)}), ArErr{}
} // }
return y, ArErr{} // return y, ArErr{}
} // }
return nil, ArErr{ // return nil, ArErr{
TYPE: "Type Error", // TYPE: "Type Error",
message: "cannot negate a non-number", // message: "cannot negate a non-number",
EXISTS: true, // EXISTS: true,
} // }
case operationType: case operationType:
if stackoverflow { if stackoverflow {
linenum = x.line linenum = x.line
@@ -208,7 +208,9 @@ func runVal(line any, stack stack, stacklevel int) (any, ArErr) {
break break
} }
return runTryCatch(x, stack, stacklevel+1) return runTryCatch(x, stack, stacklevel+1)
case bool, ArObject, number, nil, Callable, builtinFunc, anymap: case compiledNumber:
return Number(x), ArErr{}
case bool, ArObject, nil, Callable, builtinFunc, anymap:
return x, ArErr{} return x, ArErr{}
} }
if stackoverflow { if stackoverflow {

View File

@@ -58,9 +58,7 @@ func getkeyCache(getKey func(any) (any, ArErr), key any) (any, ArErr) {
} }
func compare(a, b any) (bool, error) { func compare(a, b any) (bool, error) {
if isAnyNumber(a) && isAnyNumber(b) { if x, ok := a.(ArObject); ok {
return a.(number).Cmp(b.(number)) < 0, nil
} else if x, ok := a.(ArObject); ok {
if y, ok := x.obj["__LessThan__"]; ok { if y, ok := x.obj["__LessThan__"]; ok {
resp, err := runCall( resp, err := runCall(
call{ call{

View File

@@ -2,7 +2,6 @@ package main
import ( import (
"fmt" "fmt"
"math"
"sort" "sort"
"strconv" "strconv"
"strings" "strings"
@@ -40,23 +39,6 @@ func anyToArgon(x any, quote bool, simplify bool, depth int, indent int, colored
} else { } else {
output = append(output, quoted) output = append(output, quoted)
} }
case number:
if colored {
output = append(output, "\x1b[34;5;240m")
}
num, _ := x.Float64()
if math.IsNaN(num) {
output = append(output, "NaN")
} else if math.IsInf(num, 1) {
output = append(output, "infinity")
} else if math.IsInf(num, -1) {
output = append(output, "-infinity")
} else {
output = append(output, numberToString(x, simplify))
}
if colored {
output = append(output, "\x1b[0m")
}
case bool: case bool:
if colored { if colored {
output = append(output, "\x1b[35;5;240m") output = append(output, "\x1b[35;5;240m")
@@ -91,7 +73,7 @@ func anyToArgon(x any, quote bool, simplify bool, depth int, indent int, colored
val, err := runCall( val, err := runCall(
call{ call{
Callable: callable, Callable: callable,
Args: []any{}, Args: []any{colored},
}, },
stack{}, stack{},
0, 0,

View File

@@ -2,8 +2,6 @@ package main
func typeof(val any) string { func typeof(val any) string {
switch x := val.(type) { switch x := val.(type) {
case number:
return "number"
case nil: case nil:
return "null" return "null"
case bool: case bool: