mirror of
https://github.com/Open-Argon/argon-v3.git
synced 2025-12-06 08:56:07 +00:00
abs and modify operations so they are opp
This commit is contained in:
77
src/abs.go
Normal file
77
src/abs.go
Normal 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{}
|
||||
}}
|
||||
30
src/array.go
30
src/array.go
@@ -533,6 +533,36 @@ func ArArray(arr []any) ArObject {
|
||||
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
|
||||
}
|
||||
|
||||
|
||||
@@ -10,6 +10,9 @@ type builtinFunc struct {
|
||||
}
|
||||
|
||||
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{}
|
||||
}
|
||||
|
||||
|
||||
@@ -145,6 +145,7 @@ func makeGlobal() ArObject {
|
||||
vars.obj["arccot"] = ArArccot
|
||||
vars.obj["todeg"] = ArToDeg
|
||||
vars.obj["torad"] = ArToRad
|
||||
vars.obj["abs"] = ArAbs
|
||||
vars.obj["dir"] = builtinFunc{"dir", func(a ...any) (any, ArErr) {
|
||||
fmt.Println(a)
|
||||
if len(a) == 0 {
|
||||
|
||||
@@ -7,6 +7,13 @@ import (
|
||||
|
||||
var mapCompiled = makeRegex(`( *)\{(((( *).+( *):( *).+( *))|(` + spacelessVariable + `))(( *)\,(( *).+( *):( *).+( *))|(` + spacelessVariable + `)))*\}( *)`)
|
||||
|
||||
type createMap struct {
|
||||
body anymap
|
||||
code string
|
||||
line int
|
||||
path string
|
||||
}
|
||||
|
||||
func isMap(code UNPARSEcode) bool {
|
||||
return mapCompiled.MatchString(code.code)
|
||||
}
|
||||
|
||||
@@ -4,7 +4,6 @@ import (
|
||||
"fmt"
|
||||
"math"
|
||||
"reflect"
|
||||
"strings"
|
||||
)
|
||||
|
||||
var operations = [][]string{
|
||||
@@ -121,7 +120,6 @@ func compareValues(o operationType, stack stack, stacklevel int) (bool, ArErr) {
|
||||
stack,
|
||||
stacklevel+1,
|
||||
)
|
||||
resp = ArValidToAny(resp)
|
||||
if err.EXISTS {
|
||||
return false, err
|
||||
}
|
||||
@@ -139,6 +137,21 @@ func compareValues(o operationType, stack stack, stacklevel int) (bool, ArErr) {
|
||||
case 4:
|
||||
if isAnyNumber(resp) && isAnyNumber(resp2) {
|
||||
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{
|
||||
"Runtime Error",
|
||||
@@ -151,6 +164,21 @@ func compareValues(o operationType, stack stack, stacklevel int) (bool, ArErr) {
|
||||
case 5:
|
||||
if isAnyNumber(resp) && isAnyNumber(resp2) {
|
||||
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{
|
||||
"Runtime Error",
|
||||
@@ -163,6 +191,21 @@ func compareValues(o operationType, stack stack, stacklevel int) (bool, ArErr) {
|
||||
case 6:
|
||||
if isAnyNumber(resp) && isAnyNumber(resp2) {
|
||||
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{
|
||||
"Runtime Error",
|
||||
@@ -175,6 +218,21 @@ func compareValues(o operationType, stack stack, stacklevel int) (bool, ArErr) {
|
||||
case 7:
|
||||
if isAnyNumber(resp) && isAnyNumber(resp2) {
|
||||
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{
|
||||
"Runtime Error",
|
||||
@@ -185,9 +243,9 @@ func compareValues(o operationType, stack stack, stacklevel int) (bool, ArErr) {
|
||||
true,
|
||||
}
|
||||
case 8:
|
||||
return !equals(resp, resp2), ArErr{}
|
||||
return notequals(resp, resp2, o, stack, stacklevel)
|
||||
case 9:
|
||||
return equals(resp, resp2), ArErr{}
|
||||
return equals(resp, resp2, o, stack, stacklevel)
|
||||
default:
|
||||
return false, ArErr{
|
||||
"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(
|
||||
o.values[0],
|
||||
stack,
|
||||
stacklevel+1,
|
||||
)
|
||||
resp = ArValidToAny(resp)
|
||||
if err.EXISTS {
|
||||
return nil, err
|
||||
}
|
||||
if !isAnyNumber(resp) {
|
||||
return nil, ArErr{
|
||||
"Runtime Error",
|
||||
"Cannot subtract from type '" + typeof(resp) + "'",
|
||||
o.line,
|
||||
o.path,
|
||||
o.code,
|
||||
true,
|
||||
output := resp
|
||||
if isAnyNumber(resp) {
|
||||
output = newNumber().Set(resp.(number))
|
||||
}
|
||||
}
|
||||
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" {
|
||||
output = output.Sub(output, resp.(number))
|
||||
} else {
|
||||
if typeof(output) == "number" && typeof(resp) == "number" {
|
||||
output = output.(number).Sub(output.(number), resp.(number))
|
||||
continue
|
||||
} else if x, ok := output.(ArObject); ok {
|
||||
if y, ok := x.obj["__Subtract__"]; 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 subtract type '" + typeof(resp) + "'",
|
||||
"Cannot subtract type '" + typeof(resp) + "' from type '" + typeof(output) + "'",
|
||||
o.line,
|
||||
o.path,
|
||||
o.code,
|
||||
true,
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
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(
|
||||
o.values[0],
|
||||
stack,
|
||||
stacklevel+1,
|
||||
)
|
||||
resp = ArValidToAny(resp)
|
||||
if err.EXISTS {
|
||||
return nil, err
|
||||
}
|
||||
if !isAnyNumber(resp) {
|
||||
return nil, ArErr{
|
||||
"Runtime Error",
|
||||
"Cannot divide from type '" + typeof(resp) + "'",
|
||||
o.line,
|
||||
o.path,
|
||||
o.code,
|
||||
true,
|
||||
output := resp
|
||||
if isAnyNumber(resp) {
|
||||
output = newNumber().Set(resp.(number))
|
||||
}
|
||||
}
|
||||
output := newNumber().Set(resp.(number))
|
||||
for i := 1; i < len(o.values); i++ {
|
||||
resp, err := runVal(
|
||||
o.values[i],
|
||||
@@ -280,9 +337,26 @@ func calcDivide(o operationType, stack stack, stacklevel int) (number, ArErr) {
|
||||
if err.EXISTS {
|
||||
return nil, err
|
||||
}
|
||||
if typeof(resp) == "number" {
|
||||
output = output.Quo(output, resp.(number))
|
||||
} else {
|
||||
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["__Divide__"]; 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) + "'",
|
||||
@@ -292,7 +366,6 @@ func calcDivide(o operationType, stack stack, stacklevel int) (number, ArErr) {
|
||||
true,
|
||||
}
|
||||
}
|
||||
}
|
||||
return output, ArErr{}
|
||||
}
|
||||
|
||||
@@ -303,14 +376,11 @@ func calcAdd(o operationType, stack stack, stacklevel int) (any, ArErr) {
|
||||
stack,
|
||||
stacklevel+1,
|
||||
)
|
||||
resp = ArValidToAny(resp)
|
||||
if err.EXISTS {
|
||||
return nil, err
|
||||
}
|
||||
var output any = resp
|
||||
if typeof(output) != "number" {
|
||||
output = anyToArgon(resp, false, true, 3, 0, false, 0)
|
||||
} else {
|
||||
if typeof(output) == "number" {
|
||||
output = newNumber().Set(output.(number))
|
||||
}
|
||||
for i := 1; i < len(o.values); i++ {
|
||||
@@ -319,21 +389,39 @@ func calcAdd(o operationType, stack stack, stacklevel int) (any, ArErr) {
|
||||
stack,
|
||||
stacklevel+1,
|
||||
)
|
||||
resp = ArValidToAny(resp)
|
||||
if err.EXISTS {
|
||||
return nil, err
|
||||
}
|
||||
if typeof(output) == "number" && typeof(resp) == "string" {
|
||||
output = anyToArgon(output, false, true, 3, 0, false, 0)
|
||||
}
|
||||
if typeof(output) == "number" {
|
||||
if typeof(output) == "number" && typeof(resp) == "number" {
|
||||
output = output.(number).Add(output.(number), resp.(number))
|
||||
} else {
|
||||
output = output.(string) + anyToArgon(resp, false, true, 3, 0, false, 0)
|
||||
continue
|
||||
} 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 AnyToArValid(output), ArErr{}
|
||||
}
|
||||
return nil, ArErr{
|
||||
"Runtime Error",
|
||||
"Cannot add type '" + typeof(resp) + "' to type '" + typeof(output) + "'",
|
||||
o.line,
|
||||
o.path,
|
||||
o.code,
|
||||
true,
|
||||
}
|
||||
}
|
||||
return (output), 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,
|
||||
stacklevel+1,
|
||||
)
|
||||
resp = ArValidToAny(resp)
|
||||
if err.EXISTS {
|
||||
return nil, err
|
||||
}
|
||||
var output any = resp
|
||||
if typeof(output) != "number" {
|
||||
output = anyToArgon(resp, false, true, 3, 0, false, 0)
|
||||
} else {
|
||||
output = newNumber().Set(output.(number))
|
||||
if isAnyNumber(resp) {
|
||||
output = newNumber().Set(resp.(number))
|
||||
}
|
||||
for i := 1; i < len(o.values); i++ {
|
||||
resp, err := runVal(
|
||||
@@ -359,19 +444,29 @@ func calcMul(o operationType, stack stack, stacklevel int) (any, ArErr) {
|
||||
stack,
|
||||
stacklevel+1,
|
||||
)
|
||||
resp = ArValidToAny(resp)
|
||||
if err.EXISTS {
|
||||
return nil, err
|
||||
}
|
||||
if typeof(output) == "number" && typeof(resp) == "string" {
|
||||
output = anyToArgon(output, false, true, 3, 0, false, 0)
|
||||
}
|
||||
if typeof(output) == "number" {
|
||||
if typeof(output) == "number" && typeof(resp) == "number" {
|
||||
output = output.(number).Mul(output.(number), resp.(number))
|
||||
} else if typeof(resp) == "number" {
|
||||
n, _ := resp.(number).Float64()
|
||||
output = strings.Repeat(output.(string), int(n))
|
||||
} else {
|
||||
continue
|
||||
} else if x, ok := output.(ArObject); ok {
|
||||
if y, ok := x.obj["__Multiply__"]; 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 multiply type '" + typeof(resp) + "'",
|
||||
@@ -380,7 +475,7 @@ func calcMul(o operationType, stack stack, stacklevel int) (any, ArErr) {
|
||||
o.code,
|
||||
true,
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
return output, ArErr{}
|
||||
}
|
||||
@@ -425,7 +520,7 @@ func calcOr(o operationType, stack stack, stacklevel int) (any, ArErr) {
|
||||
return output, ArErr{}
|
||||
}
|
||||
|
||||
func stringInSlice(a any, list []any) bool {
|
||||
func InSlice(a any, list []any) bool {
|
||||
for _, b := range list {
|
||||
if b == a {
|
||||
return true
|
||||
@@ -433,8 +528,7 @@ func stringInSlice(a any, list []any) bool {
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func calcIn(o operationType, stack stack, stacklevel int) (bool, ArErr) {
|
||||
func calcNotIn(o operationType, stack stack, stacklevel int) (any, ArErr) {
|
||||
if len(o.values) != 2 {
|
||||
return false, ArErr{
|
||||
"Runtime Error",
|
||||
@@ -460,21 +554,21 @@ func calcIn(o operationType, stack stack, stacklevel int) (bool, ArErr) {
|
||||
stack,
|
||||
stacklevel+1,
|
||||
)
|
||||
resp2 = ArValidToAny(resp2)
|
||||
if err.EXISTS {
|
||||
return false, err
|
||||
}
|
||||
|
||||
switch x := resp2.(type) {
|
||||
case string:
|
||||
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:
|
||||
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) + "'",
|
||||
@@ -483,19 +577,102 @@ func calcIn(o operationType, stack stack, stacklevel int) (bool, ArErr) {
|
||||
o.code,
|
||||
true,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func equals(a any, b any) bool {
|
||||
func calcIn(o operationType, stack stack, stacklevel int) (any, ArErr) {
|
||||
if len(o.values) != 2 {
|
||||
return false, ArErr{
|
||||
"Runtime Error",
|
||||
"Invalid number of arguments for 'not in'",
|
||||
o.line,
|
||||
o.path,
|
||||
o.code,
|
||||
true,
|
||||
}
|
||||
}
|
||||
resp, err := runVal(
|
||||
o.values[0],
|
||||
stack,
|
||||
stacklevel+1,
|
||||
)
|
||||
if err.EXISTS {
|
||||
return false, err
|
||||
}
|
||||
|
||||
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
|
||||
} else if typeof(a) == "string" || typeof(b) == "string" {
|
||||
return anyToArgon(a, false, false, 3, 0, false, 0) == anyToArgon(b, false, false, 3, 0, false, 0)
|
||||
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 reflect.DeepEqual(a, b)
|
||||
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(
|
||||
o.values[0],
|
||||
stack,
|
||||
@@ -505,17 +682,10 @@ func calcMod(o operationType, stack stack, stacklevel int) (number, ArErr) {
|
||||
if err.EXISTS {
|
||||
return nil, err
|
||||
}
|
||||
if !isAnyNumber(resp) {
|
||||
return nil, ArErr{
|
||||
"Runtime Error",
|
||||
"Cannot calculate modulus from type '" + typeof(resp) + "'",
|
||||
o.line,
|
||||
o.path,
|
||||
o.code,
|
||||
true,
|
||||
output := resp
|
||||
if isAnyNumber(resp) {
|
||||
output = newNumber().Set(resp.(number))
|
||||
}
|
||||
}
|
||||
output := newNumber().Set(resp.(number))
|
||||
for i := 1; i < len(o.values); i++ {
|
||||
resp, err := runVal(
|
||||
o.values[i],
|
||||
@@ -526,11 +696,26 @@ func calcMod(o operationType, stack stack, stacklevel int) (number, ArErr) {
|
||||
if err.EXISTS {
|
||||
return nil, err
|
||||
}
|
||||
if typeof(resp) == "number" {
|
||||
n1, _ := output.Float64()
|
||||
n2, _ := resp.(number).Float64()
|
||||
output = newNumber().SetFloat64(math.Mod(n1, n2))
|
||||
} else {
|
||||
if typeof(resp) == "number" && typeof(output) == "number" {
|
||||
output = floor(newNumber().Quo(resp.(number), output.(number)))
|
||||
continue
|
||||
} else if x, ok := output.(ArObject); ok {
|
||||
if y, ok := x.obj["__Modulo__"]; 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 calculate modulus of type '" + typeof(resp) + "'",
|
||||
@@ -540,15 +725,62 @@ func calcMod(o operationType, stack stack, stacklevel int) (number, ArErr) {
|
||||
true,
|
||||
}
|
||||
}
|
||||
}
|
||||
return output, ArErr{}
|
||||
}
|
||||
|
||||
func calcIntDiv(o operationType, stack stack, stacklevel int) (number, ArErr) {
|
||||
resp, err := calcDivide(o, stack, stacklevel+1)
|
||||
x, _ := resp.Float64()
|
||||
resp = newNumber().SetFloat64(math.Trunc(x))
|
||||
return resp, err
|
||||
func calcIntDiv(o operationType, stack stack, stacklevel int) (any, ArErr) {
|
||||
resp, err := runVal(
|
||||
o.values[0],
|
||||
stack,
|
||||
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) {
|
||||
@@ -610,22 +842,10 @@ func runOperation(o operationType, stack stack, stacklevel int) (any, ArErr) {
|
||||
case 1:
|
||||
return calcOr(o, stack, stacklevel+1)
|
||||
case 2:
|
||||
resp, err := calcIn(o, stack, stacklevel+1)
|
||||
resp = !resp
|
||||
return resp, err
|
||||
return calcNotIn(o, stack, stacklevel+1)
|
||||
case 3:
|
||||
return calcIn(o, stack, stacklevel+1)
|
||||
case 4:
|
||||
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:
|
||||
case 4, 5, 6, 7, 8, 9:
|
||||
return compareValues(o, stack, stacklevel+1)
|
||||
case 10:
|
||||
return calcAdd(o, stack, stacklevel+1)
|
||||
|
||||
16
src/run.go
16
src/run.go
@@ -14,8 +14,6 @@ func runVal(line any, stack stack, stacklevel int) (any, ArErr) {
|
||||
stackoverflow = stacklevel >= 10000
|
||||
)
|
||||
switch x := line.(type) {
|
||||
case number:
|
||||
return x, ArErr{}
|
||||
case string:
|
||||
return ArString(x), ArErr{}
|
||||
case call:
|
||||
@@ -191,11 +189,15 @@ func runVal(line any, stack stack, stacklevel int) (any, ArErr) {
|
||||
break
|
||||
}
|
||||
return runImport(x, stack, stacklevel+1)
|
||||
case bool:
|
||||
return x, ArErr{}
|
||||
case nil:
|
||||
return x, ArErr{}
|
||||
case ArObject:
|
||||
case ABS:
|
||||
if stackoverflow {
|
||||
linenum = x.line
|
||||
path = x.path
|
||||
code = x.code
|
||||
break
|
||||
}
|
||||
return runAbs(x, stack, stacklevel+1)
|
||||
case bool, ArObject, number, nil:
|
||||
return x, ArErr{}
|
||||
}
|
||||
if stackoverflow {
|
||||
|
||||
@@ -32,7 +32,7 @@ func quickSort(list []interface{}, getKey func(interface{}) (interface{}, ArErr)
|
||||
EXISTS: true,
|
||||
}
|
||||
}
|
||||
if comp < 0 {
|
||||
if comp {
|
||||
left = append(left, v)
|
||||
} else {
|
||||
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) {
|
||||
if cacheval, ok := cache[index]; ok {
|
||||
key := ArValidToAny(index)
|
||||
if cacheval, ok := cache[key]; ok {
|
||||
return cacheval, ArErr{}
|
||||
}
|
||||
val, err := getKey(index)
|
||||
if err.EXISTS {
|
||||
return nil, err
|
||||
}
|
||||
cache[index] = val
|
||||
cache[key] = val
|
||||
return val, ArErr{}
|
||||
}
|
||||
|
||||
func compare(a, b interface{}) (int, error) {
|
||||
switch x := a.(type) {
|
||||
case string:
|
||||
if _, ok := b.(string); !ok {
|
||||
return 0, fmt.Errorf("cannot compare %T to %T", a, b)
|
||||
func compare(a, b any) (bool, error) {
|
||||
if isAnyNumber(a) && isAnyNumber(b) {
|
||||
return a.(number).Cmp(b.(number)) < 0, nil
|
||||
} else if x, ok := a.(ArObject); ok {
|
||||
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))
|
||||
}
|
||||
|
||||
136
src/string.go
136
src/string.go
@@ -30,8 +30,7 @@ func unquoted(
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
classoutput := (output)
|
||||
return classoutput, nil
|
||||
return output, nil
|
||||
}
|
||||
|
||||
// returns translateString, success, error
|
||||
@@ -256,8 +255,8 @@ func ArString(str string) ArObject {
|
||||
}
|
||||
splitby := a[0].(string)
|
||||
output := []any{}
|
||||
splitted := any(strings.Split(str, splitby))
|
||||
for _, v := range splitted.([]string) {
|
||||
splitted := (strings.Split(str, splitby))
|
||||
for _, v := range splitted {
|
||||
output = append(output, ArString(v))
|
||||
}
|
||||
return output, ArErr{}
|
||||
@@ -412,5 +411,134 @@ func ArString(str string) ArObject {
|
||||
}
|
||||
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
|
||||
}
|
||||
|
||||
@@ -63,6 +63,12 @@ func translateVal(code UNPARSEcode, index int, codelines []UNPARSEcode, isLine 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) {
|
||||
return parseNot(code, index, codelines, isLine)
|
||||
}
|
||||
@@ -80,8 +86,6 @@ func translateVal(code UNPARSEcode, index int, codelines []UNPARSEcode, isLine i
|
||||
}
|
||||
if isNumber(code) {
|
||||
return parseNumber(code)
|
||||
} else if isNegative(code) {
|
||||
return parseNegative(code, index, codelines)
|
||||
} else if isString(code) {
|
||||
return parseString(code)
|
||||
} else if issquareroot(code) {
|
||||
@@ -106,7 +110,9 @@ func translateVal(code UNPARSEcode, index int, codelines []UNPARSEcode, isLine i
|
||||
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)
|
||||
if worked {
|
||||
return resp, worked, err, i
|
||||
|
||||
Reference in New Issue
Block a user