abs and modify operations so they are opp

This commit is contained in:
2023-03-26 21:42:44 +01:00
parent c6c608ad91
commit 364afa630d
11 changed files with 656 additions and 185 deletions

2
go.mod
View File

@@ -1,4 +1,4 @@
module wbell.dev/m/v2 module argon.wbell.dev
go 1.19 go 1.19

77
src/abs.go Normal file
View File

@@ -0,0 +1,77 @@
package main
import (
"fmt"
"strings"
)
var AbsCompiled = makeRegex(`( *)\|(.|\n)+\|( *)`)
type ABS struct {
body any
code string
line int
path string
}
func isAbs(code UNPARSEcode) bool {
return AbsCompiled.MatchString(code.code)
}
func parseAbs(code UNPARSEcode, index int, codelines []UNPARSEcode) (any, bool, ArErr, int) {
trimmed := strings.TrimSpace(code.code)
trimmed = trimmed[1 : len(trimmed)-1]
val, worked, err, i := translateVal(UNPARSEcode{
trimmed,
code.realcode,
code.line,
code.path,
}, index, codelines, 0)
if !worked {
return nil, false, err, 0
}
return ABS{
val,
code.realcode,
code.line,
code.path,
}, true, ArErr{}, i
}
func runAbs(x ABS, stack stack, stacklevel int) (any, ArErr) {
resp, err := runVal(x.body, stack, stacklevel+1)
if err.EXISTS {
return nil, err
}
if typeof(resp) != "number" {
return nil, ArErr{TYPE: "Runtime Error",
message: fmt.Sprintf("abs expected number, got %s", typeof(resp)),
EXISTS: true,
}
}
return abs(resp.(number)), ArErr{}
}
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

@@ -533,6 +533,36 @@ func ArArray(arr []any) ArObject {
return ArArray(newarr), ArErr{} return ArArray(newarr), ArErr{}
}, },
} }
val.obj["__Equal__"] = builtinFunc{
"__LessThanEqual__",
func(args ...any) (any, ArErr) {
if len(args) != 1 {
return nil, ArErr{
TYPE: "TypeError",
message: "missing argument",
EXISTS: true,
}
}
if typeof(args[0]) != "array" {
return false, ArErr{}
}
if len(arr) != len(args[0].(ArObject).obj["__value__"].([]any)) {
return false, ArErr{}
}
for i, v := range arr {
res, err := runOperation(operationType{
operation: 8,
values: []any{v, args[0].(ArObject).obj["__value__"].([]any)[i]},
}, stack{}, 0)
if err.EXISTS {
return nil, err
}
if anyToBool(res) {
return false, ArErr{}
}
}
return true, ArErr{}
}}
return val return val
} }

View File

@@ -10,6 +10,9 @@ type builtinFunc struct {
} }
func ArgonString(args ...any) (any, ArErr) { func ArgonString(args ...any) (any, ArErr) {
if len(args) == 0 {
return ArString(""), ArErr{}
}
return ArString(anyToArgon(args[0], true, false, 3, 0, false, 0)), ArErr{} return ArString(anyToArgon(args[0], true, false, 3, 0, false, 0)), ArErr{}
} }

View File

@@ -145,6 +145,7 @@ func makeGlobal() ArObject {
vars.obj["arccot"] = ArArccot vars.obj["arccot"] = ArArccot
vars.obj["todeg"] = ArToDeg vars.obj["todeg"] = ArToDeg
vars.obj["torad"] = ArToRad vars.obj["torad"] = ArToRad
vars.obj["abs"] = ArAbs
vars.obj["dir"] = builtinFunc{"dir", func(a ...any) (any, ArErr) { vars.obj["dir"] = builtinFunc{"dir", func(a ...any) (any, ArErr) {
fmt.Println(a) fmt.Println(a)
if len(a) == 0 { if len(a) == 0 {

View File

@@ -7,6 +7,13 @@ import (
var mapCompiled = makeRegex(`( *)\{(((( *).+( *):( *).+( *))|(` + spacelessVariable + `))(( *)\,(( *).+( *):( *).+( *))|(` + spacelessVariable + `)))*\}( *)`) var mapCompiled = makeRegex(`( *)\{(((( *).+( *):( *).+( *))|(` + spacelessVariable + `))(( *)\,(( *).+( *):( *).+( *))|(` + spacelessVariable + `)))*\}( *)`)
type createMap struct {
body anymap
code string
line int
path string
}
func isMap(code UNPARSEcode) bool { func isMap(code UNPARSEcode) bool {
return mapCompiled.MatchString(code.code) return mapCompiled.MatchString(code.code)
} }

View File

@@ -4,7 +4,6 @@ import (
"fmt" "fmt"
"math" "math"
"reflect" "reflect"
"strings"
) )
var operations = [][]string{ var operations = [][]string{
@@ -121,7 +120,6 @@ func compareValues(o operationType, stack stack, stacklevel int) (bool, ArErr) {
stack, stack,
stacklevel+1, stacklevel+1,
) )
resp = ArValidToAny(resp)
if err.EXISTS { if err.EXISTS {
return false, err return false, err
} }
@@ -139,6 +137,21 @@ func compareValues(o operationType, stack stack, stacklevel int) (bool, ArErr) {
case 4: case 4:
if isAnyNumber(resp) && isAnyNumber(resp2) { if isAnyNumber(resp) && isAnyNumber(resp2) {
return resp.(number).Cmp(resp2.(number)) <= 0, ArErr{} return resp.(number).Cmp(resp2.(number)) <= 0, ArErr{}
} else if x, ok := resp.(ArObject); ok {
if y, ok := x.obj["__LessThanEqual__"]; ok {
val, err := runCall(
call{
y,
[]any{resp2},
o.code,
o.line,
o.path,
}, stack, stacklevel+1)
if err.EXISTS {
return false, err
}
return anyToBool(val), ArErr{}
}
} }
return false, ArErr{ return false, ArErr{
"Runtime Error", "Runtime Error",
@@ -151,6 +164,21 @@ func compareValues(o operationType, stack stack, stacklevel int) (bool, ArErr) {
case 5: case 5:
if isAnyNumber(resp) && isAnyNumber(resp2) { if isAnyNumber(resp) && isAnyNumber(resp2) {
return resp.(number).Cmp(resp2.(number)) >= 0, ArErr{} return resp.(number).Cmp(resp2.(number)) >= 0, ArErr{}
} else if x, ok := resp.(ArObject); ok {
if y, ok := x.obj["__GreaterThanEqual__"]; ok {
val, err := runCall(
call{
y,
[]any{resp2},
o.code,
o.line,
o.path,
}, stack, stacklevel+1)
if err.EXISTS {
return false, err
}
return anyToBool(val), ArErr{}
}
} }
return false, ArErr{ return false, ArErr{
"Runtime Error", "Runtime Error",
@@ -163,6 +191,21 @@ func compareValues(o operationType, stack stack, stacklevel int) (bool, ArErr) {
case 6: case 6:
if isAnyNumber(resp) && isAnyNumber(resp2) { if isAnyNumber(resp) && isAnyNumber(resp2) {
return resp.(number).Cmp(resp2.(number)) < 0, ArErr{} return resp.(number).Cmp(resp2.(number)) < 0, ArErr{}
} else if x, ok := resp.(ArObject); ok {
if y, ok := x.obj["__LessThan__"]; ok {
val, err := runCall(
call{
y,
[]any{resp2},
o.code,
o.line,
o.path,
}, stack, stacklevel+1)
if err.EXISTS {
return false, err
}
return anyToBool(val), ArErr{}
}
} }
return false, ArErr{ return false, ArErr{
"Runtime Error", "Runtime Error",
@@ -175,6 +218,21 @@ func compareValues(o operationType, stack stack, stacklevel int) (bool, ArErr) {
case 7: case 7:
if isAnyNumber(resp) && isAnyNumber(resp2) { if isAnyNumber(resp) && isAnyNumber(resp2) {
return resp.(number).Cmp(resp2.(number)) > 0, ArErr{} return resp.(number).Cmp(resp2.(number)) > 0, ArErr{}
} else if x, ok := resp.(ArObject); ok {
if y, ok := x.obj["__GreaterThan__"]; ok {
val, err := runCall(
call{
y,
[]any{resp2},
o.code,
o.line,
o.path,
}, stack, stacklevel+1)
if err.EXISTS {
return false, err
}
return anyToBool(val), ArErr{}
}
} }
return false, ArErr{ return false, ArErr{
"Runtime Error", "Runtime Error",
@@ -185,9 +243,9 @@ func compareValues(o operationType, stack stack, stacklevel int) (bool, ArErr) {
true, true,
} }
case 8: case 8:
return !equals(resp, resp2), ArErr{} return notequals(resp, resp2, o, stack, stacklevel)
case 9: case 9:
return equals(resp, resp2), ArErr{} return equals(resp, resp2, o, stack, stacklevel)
default: default:
return false, ArErr{ return false, ArErr{
"Runtime Error", "Runtime Error",
@@ -200,76 +258,75 @@ func compareValues(o operationType, stack stack, stacklevel int) (bool, ArErr) {
} }
} }
func calcNegative(o operationType, stack stack, stacklevel int) (number, ArErr) { func calcNegative(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 !isAnyNumber(resp) { output := resp
return nil, ArErr{ if isAnyNumber(resp) {
"Runtime Error", output = newNumber().Set(resp.(number))
"Cannot subtract from 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 typeof(output) == "number" && typeof(resp) == "number" {
output = output.Sub(output, resp.(number)) output = output.(number).Sub(output.(number), resp.(number))
} else { continue
return nil, ArErr{ } else if x, ok := output.(ArObject); ok {
"Runtime Error", if y, ok := x.obj["__Subtract__"]; ok {
"Cannot subtract type '" + typeof(resp) + "'", val, err := runCall(
o.line, call{
o.path, y,
o.code, []any{resp},
true, o.code,
o.line,
o.path,
}, stack, stacklevel+1)
if err.EXISTS {
return nil, err
}
output = val
continue
} }
} }
return nil, ArErr{
"Runtime Error",
"Cannot subtract type '" + typeof(resp) + "' from type '" + typeof(output) + "'",
o.line,
o.path,
o.code,
true,
}
} }
return output, ArErr{} return output, ArErr{}
} }
func calcDivide(o operationType, stack stack, stacklevel int) (number, ArErr) { func calcDivide(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 !isAnyNumber(resp) { output := resp
return nil, ArErr{ if isAnyNumber(resp) {
"Runtime Error", output = newNumber().Set(resp.(number))
"Cannot divide from 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],
@@ -280,18 +337,34 @@ func calcDivide(o operationType, stack stack, stacklevel int) (number, ArErr) {
if err.EXISTS { if err.EXISTS {
return nil, err return nil, err
} }
if typeof(resp) == "number" { if typeof(resp) == "number" && typeof(output) == "number" {
output = output.Quo(output, resp.(number)) output = output.(number).Quo(output.(number), resp.(number))
} else { continue
return nil, ArErr{ } else if x, ok := output.(ArObject); ok {
"Runtime Error", if y, ok := x.obj["__Divide__"]; ok {
"Cannot divide type '" + typeof(resp) + "'", val, err := runCall(
o.line, call{
o.path, y,
o.code, []any{resp},
true, o.code,
o.line,
o.path,
}, stack, stacklevel+1)
if err.EXISTS {
return nil, err
}
output = val
continue
} }
} }
return nil, ArErr{
"Runtime Error",
"Cannot divide type '" + typeof(resp) + "'",
o.line,
o.path,
o.code,
true,
}
} }
return output, ArErr{} return output, ArErr{}
} }
@@ -303,14 +376,11 @@ func calcAdd(o operationType, stack stack, stacklevel int) (any, ArErr) {
stack, stack,
stacklevel+1, stacklevel+1,
) )
resp = ArValidToAny(resp)
if err.EXISTS { if err.EXISTS {
return nil, err return nil, err
} }
var output any = resp var output any = resp
if typeof(output) != "number" { if typeof(output) == "number" {
output = anyToArgon(resp, false, true, 3, 0, false, 0)
} else {
output = newNumber().Set(output.(number)) output = newNumber().Set(output.(number))
} }
for i := 1; i < len(o.values); i++ { for i := 1; i < len(o.values); i++ {
@@ -319,21 +389,39 @@ func calcAdd(o operationType, stack stack, stacklevel int) (any, ArErr) {
stack, stack,
stacklevel+1, stacklevel+1,
) )
resp = ArValidToAny(resp)
if err.EXISTS { if err.EXISTS {
return nil, err return nil, err
} }
if typeof(output) == "number" && typeof(resp) == "string" { if typeof(output) == "number" && typeof(resp) == "number" {
output = anyToArgon(output, false, true, 3, 0, false, 0)
}
if typeof(output) == "number" {
output = output.(number).Add(output.(number), resp.(number)) output = output.(number).Add(output.(number), resp.(number))
} else { continue
output = output.(string) + anyToArgon(resp, false, true, 3, 0, false, 0) } else if x, ok := output.(ArObject); ok {
if y, ok := x.obj["__Add__"]; ok {
val, err := runCall(
call{
y,
[]any{resp},
o.code,
o.line,
o.path,
}, stack, stacklevel+1)
if err.EXISTS {
return nil, err
}
output = val
continue
}
}
return nil, ArErr{
"Runtime Error",
"Cannot add type '" + typeof(resp) + "' to type '" + typeof(output) + "'",
o.line,
o.path,
o.code,
true,
} }
} }
return AnyToArValid(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) {
@@ -343,15 +431,12 @@ func calcMul(o operationType, stack stack, stacklevel int) (any, ArErr) {
stack, stack,
stacklevel+1, stacklevel+1,
) )
resp = ArValidToAny(resp)
if err.EXISTS { if err.EXISTS {
return nil, err return nil, err
} }
var output any = resp var output any = resp
if typeof(output) != "number" { if isAnyNumber(resp) {
output = anyToArgon(resp, false, true, 3, 0, false, 0) output = newNumber().Set(resp.(number))
} else {
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(
@@ -359,28 +444,38 @@ func calcMul(o operationType, stack stack, stacklevel int) (any, ArErr) {
stack, stack,
stacklevel+1, stacklevel+1,
) )
resp = ArValidToAny(resp)
if err.EXISTS { if err.EXISTS {
return nil, err return nil, err
} }
if typeof(output) == "number" && typeof(resp) == "string" { if typeof(output) == "number" && typeof(resp) == "number" {
output = anyToArgon(output, false, true, 3, 0, false, 0)
}
if typeof(output) == "number" {
output = output.(number).Mul(output.(number), resp.(number)) output = output.(number).Mul(output.(number), resp.(number))
} else if typeof(resp) == "number" { continue
n, _ := resp.(number).Float64() } else if x, ok := output.(ArObject); ok {
output = strings.Repeat(output.(string), int(n)) if y, ok := x.obj["__Multiply__"]; ok {
} else { val, err := runCall(
return nil, ArErr{ call{
"Runtime Error", y,
"Cannot multiply type '" + typeof(resp) + "'", []any{resp},
o.line, o.code,
o.path, o.line,
o.code, o.path,
true, }, stack, stacklevel+1)
if err.EXISTS {
return nil, err
}
output = val
continue
} }
} }
return nil, ArErr{
"Runtime Error",
"Cannot multiply type '" + typeof(resp) + "'",
o.line,
o.path,
o.code,
true,
}
} }
return output, ArErr{} return output, ArErr{}
} }
@@ -425,7 +520,7 @@ func calcOr(o operationType, stack stack, stacklevel int) (any, ArErr) {
return output, ArErr{} return output, ArErr{}
} }
func stringInSlice(a any, list []any) bool { func InSlice(a any, list []any) bool {
for _, b := range list { for _, b := range list {
if b == a { if b == a {
return true return true
@@ -433,8 +528,7 @@ func stringInSlice(a any, list []any) bool {
} }
return false return false
} }
func calcNotIn(o operationType, stack stack, stacklevel int) (any, ArErr) {
func calcIn(o operationType, stack stack, stacklevel int) (bool, ArErr) {
if len(o.values) != 2 { if len(o.values) != 2 {
return false, ArErr{ return false, ArErr{
"Runtime Error", "Runtime Error",
@@ -460,42 +554,125 @@ func calcIn(o operationType, stack stack, stacklevel int) (bool, ArErr) {
stack, stack,
stacklevel+1, stacklevel+1,
) )
resp2 = ArValidToAny(resp2)
if err.EXISTS { if err.EXISTS {
return false, err return false, err
} }
if x, ok := resp.(ArObject); ok {
if y, ok := x.obj["__NotContains__"]; ok {
return runCall(
call{
y,
[]any{resp2},
o.code,
o.line,
o.path,
}, stack, stacklevel+1)
}
}
return false, ArErr{
"Runtime Error",
"Cannot check if type '" + typeof(resp) + "' is in type '" + typeof(resp2) + "'",
o.line,
o.path,
o.code,
true,
}
}
switch x := resp2.(type) { func calcIn(o operationType, stack stack, stacklevel int) (any, ArErr) {
case string: if len(o.values) != 2 {
check := anyToArgon(resp, false, true, 3, 0, false, 0)
return strings.Contains(x, check), ArErr{}
case []any:
return stringInSlice(resp, x), ArErr{}
case map[any]any:
_, ok := x[resp]
return ok, ArErr{}
default:
return false, ArErr{ return false, ArErr{
"Runtime Error", "Runtime Error",
"Cannot check if type '" + typeof(resp) + "' is in type '" + typeof(resp2) + "'", "Invalid number of arguments for 'not in'",
o.line, o.line,
o.path, o.path,
o.code, o.code,
true, true,
} }
} }
} resp, err := runVal(
o.values[0],
func equals(a any, b any) bool { stack,
if typeof(a) == "number" && typeof(b) == "number" { stacklevel+1,
return a.(number).Cmp(b.(number)) == 0 )
} else if typeof(a) == "string" || typeof(b) == "string" { if err.EXISTS {
return anyToArgon(a, false, false, 3, 0, false, 0) == anyToArgon(b, false, false, 3, 0, false, 0) return false, err
} }
return reflect.DeepEqual(a, b)
resp2, err := runVal(
o.values[1],
stack,
stacklevel+1,
)
if err.EXISTS {
return false, err
}
if x, ok := resp2.(ArObject); ok {
if y, ok := x.obj["__Contains__"]; ok {
return runCall(
call{
y,
[]any{resp},
o.code,
o.line,
o.path,
}, stack, stacklevel+1)
}
}
return false, ArErr{
"Runtime Error",
"Cannot check if type '" + typeof(resp) + "' is in type '" + typeof(resp2) + "'",
o.line,
o.path,
o.code,
true,
}
}
func notequals(a any, b any, o operationType, stack stack, stacklevel int) (bool, ArErr) {
if typeof(a) == "number" && typeof(b) == "number" {
return a.(number).Cmp(b.(number)) != 0, ArErr{}
} else if x, ok := a.(ArObject); ok {
if y, ok := x.obj["__NotEqual__"]; ok {
val, err := runCall(
call{
y,
[]any{b},
o.code,
o.line,
o.path,
}, stack, stacklevel+1)
if err.EXISTS {
return false, err
}
return !anyToBool(val), ArErr{}
}
}
return !reflect.DeepEqual(a, b), ArErr{}
} }
func calcMod(o operationType, stack stack, stacklevel int) (number, ArErr) { func equals(a any, b any, o operationType, stack stack, stacklevel int) (bool, ArErr) {
if typeof(a) == "number" && typeof(b) == "number" {
return a.(number).Cmp(b.(number)) == 0, ArErr{}
} else if x, ok := a.(ArObject); ok {
if y, ok := x.obj["__Equal__"]; ok {
val, err := runCall(
call{
y,
[]any{b},
o.code,
o.line,
o.path,
}, stack, stacklevel+1)
if err.EXISTS {
return false, err
}
return anyToBool(val), ArErr{}
}
}
return reflect.DeepEqual(a, b), ArErr{}
}
func calcMod(o operationType, stack stack, stacklevel int) (any, ArErr) {
resp, err := runVal( resp, err := runVal(
o.values[0], o.values[0],
stack, stack,
@@ -505,17 +682,10 @@ func calcMod(o operationType, stack stack, stacklevel int) (number, ArErr) {
if err.EXISTS { if err.EXISTS {
return nil, err return nil, err
} }
if !isAnyNumber(resp) { output := resp
return nil, ArErr{ if isAnyNumber(resp) {
"Runtime Error", output = newNumber().Set(resp.(number))
"Cannot calculate modulus from 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],
@@ -526,29 +696,91 @@ func calcMod(o operationType, stack stack, stacklevel int) (number, ArErr) {
if err.EXISTS { if err.EXISTS {
return nil, err return nil, err
} }
if typeof(resp) == "number" { if typeof(resp) == "number" && typeof(output) == "number" {
n1, _ := output.Float64() output = floor(newNumber().Quo(resp.(number), output.(number)))
n2, _ := resp.(number).Float64() continue
output = newNumber().SetFloat64(math.Mod(n1, n2)) } else if x, ok := output.(ArObject); ok {
} else { if y, ok := x.obj["__Modulo__"]; ok {
return nil, ArErr{ val, err := runCall(
"Runtime Error", call{
"Cannot calculate modulus of type '" + typeof(resp) + "'", y,
o.line, []any{resp},
o.path, o.code,
o.code, o.line,
true, o.path,
}, stack, stacklevel+1)
if err.EXISTS {
return nil, err
}
output = val
continue
} }
} }
return nil, ArErr{
"Runtime Error",
"Cannot calculate modulus of type '" + typeof(resp) + "'",
o.line,
o.path,
o.code,
true,
}
} }
return output, ArErr{} return output, ArErr{}
} }
func calcIntDiv(o operationType, stack stack, stacklevel int) (number, ArErr) { func calcIntDiv(o operationType, stack stack, stacklevel int) (any, ArErr) {
resp, err := calcDivide(o, stack, stacklevel+1) resp, err := runVal(
x, _ := resp.Float64() o.values[0],
resp = newNumber().SetFloat64(math.Trunc(x)) stack,
return resp, err stacklevel+1,
)
if err.EXISTS {
return nil, err
}
output := resp
if isAnyNumber(resp) {
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" && typeof(output) == "number" {
output = output.(number).Quo(output.(number), resp.(number))
continue
} else if x, ok := output.(ArObject); ok {
if y, ok := x.obj["__IntDivide__"]; ok {
val, err := runCall(
call{
y,
[]any{resp},
o.code,
o.line,
o.path,
}, stack, stacklevel+1)
if err.EXISTS {
return nil, err
}
output = val
continue
}
}
return nil, ArErr{
"Runtime Error",
"Cannot divide type '" + typeof(resp) + "'",
o.line,
o.path,
o.code,
true,
}
}
return output, ArErr{}
} }
func calcPower(o operationType, stack stack, stacklevel int) (number, ArErr) { func calcPower(o operationType, stack stack, stacklevel int) (number, ArErr) {
@@ -610,22 +842,10 @@ func runOperation(o operationType, stack stack, stacklevel int) (any, ArErr) {
case 1: case 1:
return calcOr(o, stack, stacklevel+1) return calcOr(o, stack, stacklevel+1)
case 2: case 2:
resp, err := calcIn(o, stack, stacklevel+1) return calcNotIn(o, stack, stacklevel+1)
resp = !resp
return resp, err
case 3: case 3:
return calcIn(o, stack, stacklevel+1) return calcIn(o, stack, stacklevel+1)
case 4: case 4, 5, 6, 7, 8, 9:
return compareValues(o, stack, stacklevel+1)
case 5:
return compareValues(o, stack, stacklevel+1)
case 6:
return compareValues(o, stack, stacklevel+1)
case 7:
return compareValues(o, stack, stacklevel+1)
case 8:
return compareValues(o, stack, stacklevel+1)
case 9:
return compareValues(o, stack, stacklevel+1) return compareValues(o, stack, stacklevel+1)
case 10: case 10:
return calcAdd(o, stack, stacklevel+1) return calcAdd(o, stack, stacklevel+1)

View File

@@ -14,8 +14,6 @@ func runVal(line any, stack stack, stacklevel int) (any, ArErr) {
stackoverflow = stacklevel >= 10000 stackoverflow = stacklevel >= 10000
) )
switch x := line.(type) { switch x := line.(type) {
case number:
return x, ArErr{}
case string: case string:
return ArString(x), ArErr{} return ArString(x), ArErr{}
case call: case call:
@@ -191,11 +189,15 @@ func runVal(line any, stack stack, stacklevel int) (any, ArErr) {
break break
} }
return runImport(x, stack, stacklevel+1) return runImport(x, stack, stacklevel+1)
case bool: case ABS:
return x, ArErr{} if stackoverflow {
case nil: linenum = x.line
return x, ArErr{} path = x.path
case ArObject: code = x.code
break
}
return runAbs(x, stack, stacklevel+1)
case bool, ArObject, number, nil:
return x, ArErr{} return x, ArErr{}
} }
if stackoverflow { if stackoverflow {

View File

@@ -32,7 +32,7 @@ func quickSort(list []interface{}, getKey func(interface{}) (interface{}, ArErr)
EXISTS: true, EXISTS: true,
} }
} }
if comp < 0 { if comp {
left = append(left, v) left = append(left, v)
} else { } else {
right = append(right, v) right = append(right, v)
@@ -52,35 +52,32 @@ func quickSort(list []interface{}, getKey func(interface{}) (interface{}, ArErr)
} }
func getkeyCache(getKey func(interface{}) (interface{}, ArErr), index interface{}, cache keyCache) (interface{}, ArErr) { func getkeyCache(getKey func(interface{}) (interface{}, ArErr), index interface{}, cache keyCache) (interface{}, ArErr) {
if cacheval, ok := cache[index]; ok { key := ArValidToAny(index)
if cacheval, ok := cache[key]; ok {
return cacheval, ArErr{} return cacheval, ArErr{}
} }
val, err := getKey(index) val, err := getKey(index)
if err.EXISTS { if err.EXISTS {
return nil, err return nil, err
} }
cache[index] = val cache[key] = val
return val, ArErr{} return val, ArErr{}
} }
func compare(a, b interface{}) (int, error) { func compare(a, b any) (bool, error) {
switch x := a.(type) { if isAnyNumber(a) && isAnyNumber(b) {
case string: return a.(number).Cmp(b.(number)) < 0, nil
if _, ok := b.(string); !ok { } else if x, ok := a.(ArObject); ok {
return 0, fmt.Errorf("cannot compare %T to %T", a, b) if y, ok := x.obj["__LessThan__"]; ok {
resp, err := runCall(
call{
callable: y,
args: []any{b},
}, stack{}, 0)
if !err.EXISTS {
return anyToBool(resp), nil
}
} }
if a == b {
return 0, nil
}
if x < b.(string) {
return -1, nil
}
return 1, nil
case number:
if _, ok := b.(number); !ok {
return 0, fmt.Errorf("cannot compare %T to %T", a, b)
}
return x.Cmp(b.(number)), nil
} }
return 0, fmt.Errorf("cannot compare %T to %T", a, b) return false, fmt.Errorf("cannot compare %s to %s", typeof(a), typeof(b))
} }

View File

@@ -30,8 +30,7 @@ func unquoted(
if err != nil { if err != nil {
return "", err return "", err
} }
classoutput := (output) return output, nil
return classoutput, nil
} }
// returns translateString, success, error // returns translateString, success, error
@@ -256,8 +255,8 @@ func ArString(str string) ArObject {
} }
splitby := a[0].(string) splitby := a[0].(string)
output := []any{} output := []any{}
splitted := any(strings.Split(str, splitby)) splitted := (strings.Split(str, splitby))
for _, v := range splitted.([]string) { for _, v := range splitted {
output = append(output, ArString(v)) output = append(output, ArString(v))
} }
return output, ArErr{} return output, ArErr{}
@@ -412,5 +411,134 @@ func ArString(str string) ArObject {
} }
return strings.TrimRight(str, cutset), ArErr{} return strings.TrimRight(str, cutset), ArErr{}
}} }}
obj.obj["__LessThanEqual__"] = builtinFunc{
"__LessThanOrEqual__",
func(a ...any) (any, ArErr) {
if len(a) != 1 {
return nil, ArErr{"TypeError", "expected 1 argument, got " + fmt.Sprint(len(a)), 0, "", "", true}
}
if typeof(a[0]) != "string" {
return nil, ArErr{"TypeError", "cannot get less than or equal to of type " + typeof(a[0]) + " from string", 0, "", "", true}
}
return str <= a[0].(string), ArErr{}
}}
obj.obj["__LessThan__"] = builtinFunc{
"__LessThan__",
func(a ...any) (any, ArErr) {
if len(a) != 1 {
return nil, ArErr{"TypeError", "expected 1 argument, got " + fmt.Sprint(len(a)), 0, "", "", true}
}
if typeof(a[0]) != "string" {
return nil, ArErr{"TypeError", "cannot get less than of type " + typeof(a[0]) + " from string", 0, "", "", true}
}
return str < a[0].(string), ArErr{}
}}
obj.obj["__GreaterThan__"] = builtinFunc{
"__GreaterThan__",
func(a ...any) (any, ArErr) {
if len(a) != 1 {
return nil, ArErr{"TypeError", "expected 1 argument, got " + fmt.Sprint(len(a)), 0, "", "", true}
}
if typeof(a[0]) != "string" {
return nil, ArErr{"TypeError", "cannot get greater than of type " + typeof(a[0]) + " from string", 0, "", "", true}
}
return str > a[0].(string), ArErr{}
}}
obj.obj["__GreaterThanEqual__"] = builtinFunc{
"__GreaterThanEqual__",
func(a ...any) (any, ArErr) {
if len(a) != 1 {
return nil, ArErr{"TypeError", "expected 1 argument, got " + fmt.Sprint(len(a)), 0, "", "", true}
}
if typeof(a[0]) != "string" {
return nil, ArErr{"TypeError", "cannot get greater than or equal to of type " + typeof(a[0]) + " from string", 0, "", "", true}
}
return str >= a[0].(string), ArErr{}
}}
obj.obj["__Equal__"] = builtinFunc{
"__Equal__",
func(a ...any) (any, ArErr) {
if len(a) != 1 {
return nil, ArErr{"TypeError", "expected 1 argument, got " + fmt.Sprint(len(a)), 0, "", "", true}
}
return str == a[0], ArErr{}
}}
obj.obj["__NotEqual__"] = builtinFunc{
"__NotEqual__",
func(a ...any) (any, ArErr) {
if len(a) != 1 {
return nil, ArErr{"TypeError", "expected 1 argument, got " + fmt.Sprint(len(a)), 0, "", "", true}
}
return str != a[0], ArErr{}
}}
obj.obj["__Add__"] = builtinFunc{
"__Add__",
func(a ...any) (any, ArErr) {
if len(a) != 1 {
return nil, ArErr{"TypeError", "expected 1 argument, got " + fmt.Sprint(len(a)), 0, "", "", true}
}
if typeof(a[0]) != "string" {
return nil, ArErr{"TypeError", "cannot add " + typeof(a[0]) + " to string", 0, "", "", true}
}
return strings.Join([]string{str, a[0].(string)}, ""), ArErr{}
}}
obj.obj["__Multiply__"] = builtinFunc{
"__Multiply__",
func(a ...any) (any, ArErr) {
if len(a) != 1 {
return nil, ArErr{"TypeError", "expected 1 argument, got " + fmt.Sprint(len(a)), 0, "", "", true}
}
if typeof(a[0]) != "number" {
return nil, ArErr{"TypeError", "cannot multiply string by " + typeof(a[0]), 0, "", "", true}
}
n := a[0].(number)
if !n.IsInt() {
return nil, ArErr{"ValueError", "cannot multiply string by float", 0, "", "", true}
}
if n.Sign() < 0 {
return nil, ArErr{"ValueError", "cannot multiply string by negative number", 0, "", "", true}
}
return strings.Repeat(str, int(n.Num().Int64())), ArErr{}
}}
obj.obj["__Contains__"] = builtinFunc{
"__Contains__",
func(a ...any) (any, ArErr) {
if len(a) != 1 {
return nil, ArErr{"TypeError", "expected 1 argument, got " + fmt.Sprint(len(a)), 0, "", "", true}
}
if typeof(a[0]) != "string" {
return nil, ArErr{"TypeError", "cannot check if string contains " + typeof(a[0]), 0, "", "", true}
}
return strings.Contains(str, a[0].(string)), ArErr{}
}}
obj.obj["__Subtract__"] = builtinFunc{
"__Subtract__",
func(a ...any) (any, ArErr) {
if len(a) != 1 {
return nil, ArErr{"TypeError", "expected 1 argument, got " + fmt.Sprint(len(a)), 0, "", "", true}
}
if typeof(a[0]) != "string" {
return nil, ArErr{"TypeError", "cannot subtract " + typeof(a[0]) + " from string", 0, "", "", true}
}
return strings.Replace(str, a[0].(string), "", -1), ArErr{}
}}
obj.obj["__Divide__"] = builtinFunc{
"__Divide__",
func(a ...any) (any, ArErr) {
if len(a) != 1 {
return nil, ArErr{"TypeError", "expected 1 argument, got " + fmt.Sprint(len(a)), 0, "", "", true}
}
if typeof(a[0]) != "string" {
return nil, ArErr{"TypeError", "cannot divide string by " + typeof(a[0]), 0, "", "", true}
}
splitby := a[0].(string)
output := []any{}
splitted := (strings.Split(str, splitby))
for _, v := range splitted {
output = append(output, ArString(v))
}
return ArArray(output), ArErr{}
}}
return obj return obj
} }

View File

@@ -63,6 +63,12 @@ func translateVal(code UNPARSEcode, index int, codelines []UNPARSEcode, isLine i
return resp, worked, err, i return resp, worked, err, i
} }
} }
if isAbs(code) {
resp, worked, err, i = parseAbs(code, index, codelines)
if worked {
return resp, worked, err, i
}
}
if isnot(code) { if isnot(code) {
return parseNot(code, index, codelines, isLine) return parseNot(code, index, codelines, isLine)
} }
@@ -80,8 +86,6 @@ func translateVal(code UNPARSEcode, index int, codelines []UNPARSEcode, isLine i
} }
if isNumber(code) { if isNumber(code) {
return parseNumber(code) return parseNumber(code)
} else if isNegative(code) {
return parseNegative(code, index, codelines)
} else if isString(code) { } else if isString(code) {
return parseString(code) return parseString(code)
} else if issquareroot(code) { } else if issquareroot(code) {
@@ -106,7 +110,9 @@ func translateVal(code UNPARSEcode, index int, codelines []UNPARSEcode, isLine i
return nil, worked, err, step return nil, worked, err, step
} }
} }
if isCall(code) { if isNegative(code) {
return parseNegative(code, index, codelines)
} else if isCall(code) {
resp, worked, err, i = parseCall(code, index, codelines) resp, worked, err, i = parseCall(code, index, codelines)
if worked { if worked {
return resp, worked, err, i return resp, worked, err, i