mirror of
https://github.com/Open-Argon/argon-v3.git
synced 2025-12-06 08:56:07 +00:00
begin coverting old code that uses non oop numbers to use oop numbers
This commit is contained in:
129
src/array.go
129
src/array.go
@@ -2,6 +2,7 @@ package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"math/big"
|
||||
"strings"
|
||||
)
|
||||
|
||||
@@ -25,6 +26,48 @@ func ArArray(arr []any) ArObject {
|
||||
"__value__": arr,
|
||||
},
|
||||
}
|
||||
val.obj["__json__"] = builtinFunc{
|
||||
"__json__",
|
||||
func(args ...any) (any, ArErr) {
|
||||
if len(args) != 1 {
|
||||
return "", ArErr{
|
||||
TYPE: "Type Error",
|
||||
message: "expected 1 argument, got " + fmt.Sprint(len(args)),
|
||||
EXISTS: true,
|
||||
}
|
||||
}
|
||||
if typeof(args[0]) != "number" {
|
||||
return "", ArErr{
|
||||
TYPE: "Type Error",
|
||||
message: "expected number, got " + typeof(args[0]),
|
||||
EXISTS: true,
|
||||
}
|
||||
}
|
||||
|
||||
output := []string{}
|
||||
|
||||
level, err := numberToInt64(args[0].(ArObject))
|
||||
if err != nil {
|
||||
return "", ArErr{
|
||||
TYPE: "Runtime Error",
|
||||
message: err.Error(),
|
||||
EXISTS: true,
|
||||
}
|
||||
}
|
||||
for _, value := range arr {
|
||||
str, err := jsonstringify(value, level+1)
|
||||
if err != nil {
|
||||
return "", ArErr{
|
||||
TYPE: "Runtime Error",
|
||||
message: err.Error(),
|
||||
EXISTS: true,
|
||||
}
|
||||
}
|
||||
output = append(output, str)
|
||||
}
|
||||
return "[" + strings.Join(output, ", ") + "]", ArErr{}
|
||||
},
|
||||
}
|
||||
val.obj["__setindex__"] = builtinFunc{
|
||||
"__setindex__",
|
||||
func(a ...any) (any, ArErr) {
|
||||
@@ -42,14 +85,22 @@ func ArArray(arr []any) ArObject {
|
||||
EXISTS: true,
|
||||
}
|
||||
}
|
||||
if !a[0].(number).IsInt() {
|
||||
if !isNumberInt(a[0].(ArObject)) {
|
||||
return nil, ArErr{
|
||||
TYPE: "Type Error",
|
||||
message: "index must be an integer",
|
||||
EXISTS: true,
|
||||
}
|
||||
}
|
||||
num := int(a[0].(number).Num().Int64())
|
||||
num64, err := numberToInt64(a[0].(ArObject))
|
||||
if err != nil {
|
||||
return nil, ArErr{
|
||||
TYPE: "Runtime Error",
|
||||
message: err.Error(),
|
||||
EXISTS: true,
|
||||
}
|
||||
}
|
||||
num := int(num64)
|
||||
if num < 0 || num >= len(arr) {
|
||||
return nil, ArErr{
|
||||
TYPE: "Index Error",
|
||||
@@ -75,7 +126,7 @@ func ArArray(arr []any) ArObject {
|
||||
if typeof(a[0]) == "string" {
|
||||
var name = ArValidToAny(a[0]).(string)
|
||||
if name == "length" {
|
||||
return newNumber().SetInt64(int64(len(arr))), ArErr{}
|
||||
return Number(compiledNumber{big.NewInt(int64(len(arr)))}), ArErr{}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -88,40 +139,64 @@ func ArArray(arr []any) ArObject {
|
||||
{
|
||||
if a[0] == nil {
|
||||
start = 0
|
||||
} else if typeof(a[0]) != "number" || !a[0].(number).IsInt() {
|
||||
} else if typeof(a[0]) != "number" || !isNumberInt(a[0].(ArObject)) {
|
||||
return "", ArErr{
|
||||
TYPE: "Type Error",
|
||||
message: "slice index must be an integer",
|
||||
EXISTS: true,
|
||||
}
|
||||
} else {
|
||||
start = int(a[0].(number).Num().Int64())
|
||||
start64, err := numberToInt64(a[0].(ArObject))
|
||||
if err != nil {
|
||||
return "", ArErr{
|
||||
TYPE: "Runtime Error",
|
||||
message: err.Error(),
|
||||
EXISTS: true,
|
||||
}
|
||||
}
|
||||
start = int(start64)
|
||||
}
|
||||
}
|
||||
if len(a) > 1 {
|
||||
if a[1] == nil {
|
||||
end = len(arr)
|
||||
} else if typeof(a[1]) != "number" || !a[1].(number).IsInt() {
|
||||
} else if typeof(a[1]) != "number" || !isNumberInt(a[1].(ArObject)) {
|
||||
return "", ArErr{
|
||||
TYPE: "Type Error",
|
||||
message: "slice index must be an integer",
|
||||
EXISTS: true,
|
||||
}
|
||||
} else {
|
||||
end = int(a[1].(number).Num().Int64())
|
||||
end64, err := numberToInt64(a[1].(ArObject))
|
||||
if err != nil {
|
||||
return "", ArErr{
|
||||
TYPE: "Runtime Error",
|
||||
message: err.Error(),
|
||||
EXISTS: true,
|
||||
}
|
||||
}
|
||||
end = int(end64)
|
||||
}
|
||||
}
|
||||
if len(a) > 2 {
|
||||
if a[2] == nil {
|
||||
step = 1
|
||||
} else if typeof(a[2]) != "number" || !a[2].(number).IsInt() {
|
||||
} else if typeof(a[2]) != "number" || !isNumberInt(a[2].(ArObject)) {
|
||||
return "", ArErr{
|
||||
TYPE: "Type Error",
|
||||
message: "slice index must be an integer",
|
||||
EXISTS: true,
|
||||
}
|
||||
} else {
|
||||
step = int(a[2].(number).Num().Int64())
|
||||
step64, err := numberToInt64(a[2].(ArObject))
|
||||
if err != nil {
|
||||
return "", ArErr{
|
||||
TYPE: "Runtime Error",
|
||||
message: err.Error(),
|
||||
EXISTS: true,
|
||||
}
|
||||
}
|
||||
step = int(step64)
|
||||
}
|
||||
}
|
||||
var ogStart = start
|
||||
@@ -176,14 +251,22 @@ func ArArray(arr []any) ArObject {
|
||||
EXISTS: true,
|
||||
}
|
||||
}
|
||||
if !args[0].(number).IsInt() {
|
||||
if !isNumberInt(args[0].(ArObject)) {
|
||||
return nil, ArErr{
|
||||
TYPE: "Type Error",
|
||||
message: "argument must be an integer",
|
||||
EXISTS: true,
|
||||
}
|
||||
}
|
||||
num := int(args[0].(number).Num().Int64())
|
||||
num64, err := (numberToInt64(args[0].(ArObject)))
|
||||
if err != nil {
|
||||
return nil, ArErr{
|
||||
TYPE: "Runtime Error",
|
||||
message: err.Error(),
|
||||
EXISTS: true,
|
||||
}
|
||||
}
|
||||
num := int(num64)
|
||||
if num < 0 || num >= len(arr) {
|
||||
return nil, ArErr{
|
||||
TYPE: "Index Error",
|
||||
@@ -227,14 +310,22 @@ func ArArray(arr []any) ArObject {
|
||||
EXISTS: true,
|
||||
}
|
||||
}
|
||||
if !args[0].(number).IsInt() {
|
||||
if !isNumberInt(args[0].(ArObject)) {
|
||||
return nil, ArErr{
|
||||
TYPE: "Type Error",
|
||||
message: "argument must be an integer",
|
||||
EXISTS: true,
|
||||
}
|
||||
}
|
||||
num := int(args[0].(number).Num().Int64())
|
||||
num64, err := numberToInt64(args[0].(ArObject))
|
||||
if err != nil {
|
||||
return nil, ArErr{
|
||||
TYPE: "Runtime Error",
|
||||
message: err.Error(),
|
||||
EXISTS: true,
|
||||
}
|
||||
}
|
||||
num := int(num64)
|
||||
if num < 0 || num > len(arr) {
|
||||
return nil, ArErr{
|
||||
TYPE: "Index Error",
|
||||
@@ -265,14 +356,22 @@ func ArArray(arr []any) ArObject {
|
||||
EXISTS: true,
|
||||
}
|
||||
}
|
||||
if !args[0].(number).IsInt() {
|
||||
if !isNumberInt(args[0].(ArObject)) {
|
||||
return nil, ArErr{
|
||||
TYPE: "Type Error",
|
||||
message: "argument must be an integer",
|
||||
EXISTS: true,
|
||||
}
|
||||
}
|
||||
num := int(args[0].(number).Num().Int64())
|
||||
num64, err := (numberToInt64(args[0].(ArObject)))
|
||||
if err != nil {
|
||||
return nil, ArErr{
|
||||
TYPE: "Runtime Error",
|
||||
message: err.Error(),
|
||||
EXISTS: true,
|
||||
}
|
||||
}
|
||||
num := int(num64)
|
||||
if num < 0 || num >= len(arr) {
|
||||
return nil, ArErr{
|
||||
TYPE: "Index Error",
|
||||
|
||||
@@ -18,7 +18,6 @@ func makeGlobal() ArObject {
|
||||
"server": builtinFunc{"server", ArSocketServer},
|
||||
"client": builtinFunc{"client", ArSocketClient},
|
||||
})
|
||||
vars["infinity"] = infinity
|
||||
vars["eval"] = builtinFunc{"eval", AReval}
|
||||
vars["map"] = builtinFunc{"map", func(a ...any) (any, ArErr) {
|
||||
if len(a) == 0 {
|
||||
|
||||
@@ -28,36 +28,26 @@ func isFactorial(code UNPARSEcode) bool {
|
||||
return factorialCompiled.MatchString(code.code)
|
||||
}
|
||||
|
||||
func fact(n number) number {
|
||||
if n.Cmp(newNumber().SetInt64(1000)) >= 0 {
|
||||
return infinity
|
||||
} else if n.Cmp(newNumber().SetInt64(0)) == -1 {
|
||||
return newNumber().SetInt64(0)
|
||||
} else if n.Cmp(newNumber().SetInt64(0)) == 0 {
|
||||
return newNumber().SetInt64(1)
|
||||
}
|
||||
result := newNumber().SetInt64(1)
|
||||
for i := newNumber().SetInt64(2); i.Cmp(n) <= 0; i.Add(i, newNumber().SetInt64(1)) {
|
||||
result.Mul(result, i)
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
func runFactorial(f factorial, stack stack, stacklevel int) (any, ArErr) {
|
||||
val, err := runVal(f.value, stack, stacklevel+1)
|
||||
if err.EXISTS {
|
||||
return nil, err
|
||||
}
|
||||
switch x := val.(type) {
|
||||
case number:
|
||||
if !x.IsInt() {
|
||||
return nil, ArErr{"Runtime Error", "cannot use factorial on non-integer", f.line, f.path, f.code, true}
|
||||
switch val := val.(type) {
|
||||
case ArObject:
|
||||
if callable, ok := val.obj["__factorial__"]; ok {
|
||||
return runCall(call{
|
||||
Callable: callable,
|
||||
Args: []any{},
|
||||
Code: f.code,
|
||||
Line: f.line,
|
||||
Path: f.path,
|
||||
}, stack, stacklevel)
|
||||
}
|
||||
if x.Cmp(newNumber().SetInt64(0)) == -1 {
|
||||
return nil, ArErr{"Runtime Error", "cannot use factorial on negative number", f.line, f.path, f.code, true}
|
||||
}
|
||||
return fact(x), ArErr{}
|
||||
default:
|
||||
return nil, ArErr{"Runtime Error", "cannot use factorial on non-number of type '" + typeof(val) + "'", f.line, f.path, f.code, true}
|
||||
return nil, ArErr{
|
||||
TYPE: "TypeError",
|
||||
message: "factorial not defined for type",
|
||||
EXISTS: true,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
)
|
||||
|
||||
@@ -51,7 +52,7 @@ func parseForLoop(code UNPARSEcode, index int, codelines []UNPARSEcode) (forLoop
|
||||
innertotalstep += stepstep - 1
|
||||
stepval = stepval_
|
||||
} else {
|
||||
stepval = newNumber().SetInt64(1)
|
||||
stepval = _one_Number
|
||||
}
|
||||
to := strings.TrimSpace(valsplit[0])
|
||||
toval, worked, err, tostep := translateVal(UNPARSEcode{code: to, realcode: code.realcode, line: code.line, path: code.path}, index, codelines, 0)
|
||||
@@ -83,7 +84,7 @@ func runForLoop(loop forLoop, stack stack, stacklevel int) (any, ArErr) {
|
||||
if typeof(fromval) != "number" {
|
||||
return nil, ArErr{"Type Error", "for loop from value must be a number", loop.line, loop.path, loop.code, true}
|
||||
}
|
||||
from := fromval.(number)
|
||||
from := fromval.(ArObject)
|
||||
toval, err := runVal(loop.to, stack, stacklevel+1)
|
||||
if err.EXISTS {
|
||||
return nil, err
|
||||
@@ -91,7 +92,7 @@ func runForLoop(loop forLoop, stack stack, stacklevel int) (any, ArErr) {
|
||||
if typeof(toval) != "number" {
|
||||
return nil, ArErr{"Type Error", "for loop to value must be a number", loop.line, loop.path, loop.code, true}
|
||||
}
|
||||
to := toval.(number)
|
||||
to := toval.(ArObject)
|
||||
stepval, err := runVal(loop.step, stack, stacklevel+1)
|
||||
if err.EXISTS {
|
||||
return nil, err
|
||||
@@ -99,10 +100,28 @@ func runForLoop(loop forLoop, stack stack, stacklevel int) (any, ArErr) {
|
||||
if typeof(stepval) != "number" {
|
||||
return nil, ArErr{"Type Error", "for loop step value must be a number", loop.line, loop.path, loop.code, true}
|
||||
}
|
||||
step := stepval.(number)
|
||||
for i := newNumber().Set(from); i.Cmp(to) == -1; i = i.Add(i, step) {
|
||||
i := from
|
||||
step := stepval.(ArObject)
|
||||
direction_obj, err := CompareObjects(step, _zero_Number)
|
||||
if err.EXISTS {
|
||||
return nil, err
|
||||
}
|
||||
currentDirection_obj, err := CompareObjects(to, i)
|
||||
if err.EXISTS {
|
||||
return nil, err
|
||||
}
|
||||
currentDirection, error := numberToInt64(currentDirection_obj)
|
||||
if error != nil {
|
||||
return nil, ArErr{"Type Error", error.Error(), loop.line, loop.path, loop.code, true}
|
||||
}
|
||||
direction, error := numberToInt64(direction_obj)
|
||||
if error != nil {
|
||||
return nil, ArErr{"Type Error", error.Error(), loop.line, loop.path, loop.code, true}
|
||||
}
|
||||
fmt.Println(currentDirection, direction)
|
||||
for currentDirection == direction {
|
||||
resp, err := runVal(loop.body, append(stack, Map(anymap{
|
||||
loop.variable: newNumber().Set(i),
|
||||
loop.variable: i,
|
||||
})), stacklevel+1)
|
||||
if err.EXISTS {
|
||||
return nil, err
|
||||
@@ -113,7 +132,22 @@ func runForLoop(loop forLoop, stack stack, stacklevel int) (any, ArErr) {
|
||||
case Break:
|
||||
return nil, ArErr{}
|
||||
case Continue:
|
||||
continue
|
||||
}
|
||||
i, err = AddObjects(i, step)
|
||||
if err.EXISTS {
|
||||
return nil, err
|
||||
}
|
||||
currentDirection_obj, err = CompareObjects(to, i)
|
||||
if err.EXISTS {
|
||||
return nil, err
|
||||
}
|
||||
currentDirection, error = numberToInt64(currentDirection_obj)
|
||||
if error != nil {
|
||||
return nil, ArErr{"Type Error", error.Error(), loop.line, loop.path, loop.code, true}
|
||||
}
|
||||
direction, error = numberToInt64(direction_obj)
|
||||
if error != nil {
|
||||
return nil, ArErr{"Type Error", error.Error(), loop.line, loop.path, loop.code, true}
|
||||
}
|
||||
}
|
||||
return nil, ArErr{}
|
||||
|
||||
@@ -22,6 +22,39 @@ type ArMapGet struct {
|
||||
Path string
|
||||
}
|
||||
|
||||
func isObject(val any) bool {
|
||||
if _, ok := val.(ArObject); ok {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func hashableObject(obj ArObject) (string, ArErr) {
|
||||
if callable, ok := obj.obj["__hash__"]; ok {
|
||||
resp, err := runCall(call{
|
||||
Callable: callable,
|
||||
Args: []any{},
|
||||
}, stack{}, 0)
|
||||
if err.EXISTS {
|
||||
return "", err
|
||||
}
|
||||
resp = ArValidToAny(resp)
|
||||
if str, ok := resp.(string); ok {
|
||||
return str, ArErr{}
|
||||
}
|
||||
return "", ArErr{
|
||||
TYPE: "TypeError",
|
||||
EXISTS: true,
|
||||
message: "expected string from __hash__ method, got " + typeof(resp),
|
||||
}
|
||||
}
|
||||
return "", ArErr{
|
||||
TYPE: "TypeError",
|
||||
EXISTS: true,
|
||||
message: "cannot hash object",
|
||||
}
|
||||
}
|
||||
|
||||
func mapGet(r ArMapGet, stack stack, stacklevel int) (any, ArErr) {
|
||||
resp, err := runVal(r.VAL, stack, stacklevel+1)
|
||||
if err.EXISTS {
|
||||
|
||||
71
src/json.go
71
src/json.go
@@ -3,9 +3,8 @@ package main
|
||||
import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"math"
|
||||
"fmt"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
func convertToArgon(obj any) any {
|
||||
@@ -24,7 +23,7 @@ func convertToArgon(obj any) any {
|
||||
case string:
|
||||
return ArString(x)
|
||||
case float64:
|
||||
return newNumber().SetFloat64(x)
|
||||
return Number(compiledNumber{value: newNumber().SetFloat64(x)})
|
||||
case bool:
|
||||
return x
|
||||
case nil:
|
||||
@@ -36,48 +35,43 @@ func convertToArgon(obj any) any {
|
||||
func jsonparse(str string) (any, ArErr) {
|
||||
var jsonMap any
|
||||
var err = json.Unmarshal([]byte(str), &jsonMap)
|
||||
if err != nil {return nil, ArErr{TYPE: "Runtime Error", message: err.Error(), EXISTS: true}}
|
||||
if err != nil {
|
||||
return nil, ArErr{TYPE: "Runtime Error", message: err.Error(), EXISTS: true}
|
||||
}
|
||||
return convertToArgon(jsonMap), ArErr{}
|
||||
}
|
||||
|
||||
func jsonstringify(obj any, level int) (string, error) {
|
||||
func jsonstringify(obj any, level int64) (string, error) {
|
||||
if level > 100 {
|
||||
return "", errors.New("json stringify error: too many levels")
|
||||
}
|
||||
output := []string{}
|
||||
obj = ArValidToAny(obj)
|
||||
switch x := obj.(type) {
|
||||
case anymap:
|
||||
for key, value := range x {
|
||||
str, err := jsonstringify(value, level+1)
|
||||
if err != nil {
|
||||
return "", err
|
||||
case ArObject:
|
||||
if callable, ok := x.obj["__json__"]; ok {
|
||||
val, err := runCall(
|
||||
call{
|
||||
Callable: callable,
|
||||
Args: []any{Int64ToNumber(level)},
|
||||
},
|
||||
stack{},
|
||||
0,
|
||||
)
|
||||
if err.EXISTS {
|
||||
return "", errors.New(err.message)
|
||||
}
|
||||
output = append(output, ""+strconv.Quote(anyToArgon(key, false, true, 3, 0, false, 0))+": "+str)
|
||||
val = ArValidToAny(val)
|
||||
if x, ok := val.(string); ok {
|
||||
return x, nil
|
||||
} else {
|
||||
return "", errors.New("json stringify error: __json__ must return a string")
|
||||
}
|
||||
return "{" + strings.Join(output, ", ") + "}", nil
|
||||
case []any:
|
||||
for _, value := range x {
|
||||
str, err := jsonstringify(value, level+1)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
output = append(output, str)
|
||||
}
|
||||
return "[" + strings.Join(output, ", ") + "]", nil
|
||||
case string:
|
||||
return strconv.Quote(x), nil
|
||||
case number:
|
||||
num, _ := x.Float64()
|
||||
if math.IsNaN(num) || math.IsInf(num, 0) {
|
||||
return "null", nil
|
||||
}
|
||||
return numberToString(x, false), nil
|
||||
case bool:
|
||||
return strconv.FormatBool(x), nil
|
||||
case nil:
|
||||
return "null", nil
|
||||
}
|
||||
fmt.Println(level)
|
||||
err := errors.New("Cannot stringify '" + typeof(obj) + "'")
|
||||
return "", err
|
||||
}
|
||||
@@ -94,10 +88,21 @@ var ArJSON = Map(anymap{
|
||||
return jsonparse(args[0].(string))
|
||||
}},
|
||||
"stringify": builtinFunc{"stringify", func(args ...any) (any, ArErr) {
|
||||
if len(args) == 0 {
|
||||
return nil, ArErr{TYPE: "Runtime Error", message: "stringify takes 1 argument", EXISTS: true}
|
||||
if len(args) != 1 && len(args) != 2 {
|
||||
return nil, ArErr{TYPE: "Runtime Error", message: "stringify takes 1 or 2 arguments", EXISTS: true}
|
||||
}
|
||||
str, err := jsonstringify(args[0], 0)
|
||||
var level int64 = 0
|
||||
if len(args) == 2 {
|
||||
if typeof(args[1]) != "number" {
|
||||
return nil, ArErr{TYPE: "Runtime Error", message: "stringify takes a number not a '" + typeof(args[1]) + "'", EXISTS: true}
|
||||
}
|
||||
var err error
|
||||
level, err = numberToInt64(args[1].(ArObject))
|
||||
if err != nil {
|
||||
return nil, ArErr{TYPE: "Runtime Error", message: err.Error(), EXISTS: true}
|
||||
}
|
||||
}
|
||||
str, err := jsonstringify(args[0], level)
|
||||
if err != nil {
|
||||
return nil, ArErr{TYPE: "Runtime Error", message: err.Error(), EXISTS: true}
|
||||
}
|
||||
|
||||
@@ -15,9 +15,6 @@ func Ln(x number) number {
|
||||
n1, _ := x.Float64()
|
||||
n2, _ := output.Float64()
|
||||
output = newNumber().SetFloat64(math.Pow(n1, n2))
|
||||
if output == nil {
|
||||
output = infinity
|
||||
}
|
||||
output.Sub(output, newNumber().SetInt64(1))
|
||||
output.Mul(output, N)
|
||||
return output
|
||||
|
||||
@@ -23,7 +23,7 @@ func main() {
|
||||
if !debug {
|
||||
defer func() {
|
||||
if r := recover(); r != nil {
|
||||
fmt.Println("There was a fundamental error in argon v3 that caused it to crash.")
|
||||
fmt.Println("There was a fundamental error in argon v" + VERSION + " that caused it to crash.")
|
||||
fmt.Println()
|
||||
fmt.Println("website:", website)
|
||||
fmt.Println("docs:", docs)
|
||||
|
||||
@@ -1,5 +1,13 @@
|
||||
package main
|
||||
|
||||
var PI, _ = newNumber().SetString("3.1415926535897932384626433832795028841971693993751058209749445923078164062862089986280348253421170679821480865132823066470938446095505822317253594081284811174502841027019385211055596446229489549303819644288109756659334461284756482337867831652712019091456485669234603486104543266482133936072602491412737245870066063155881748815209209628292540917153643678925903600113305305488204665213841469519415116094330572703657595919530921861173819326117931051185480744623799627495673518857527248912279381830119491298336733624406566430860213949463952247371907021798609437027705392171762931767523846748184676694051320005681271452635608277857713427577896091736371787214684409012249534301465495853710507922796892589235420199561121290219608640344181598136297747713099605187072113499999983729780499510597317328160963185950244594553469083026425223082533446850352619311881710100031378387528865875332083814206171776691473035982534904287554687311595628638823537875937519577818577805321712268066130019278766111959092164201989")
|
||||
var e, _ = newNumber().SetString("2.7182818284590452353602874713526624977572470936999595749669676277240766303535475945713821785251664274274663919320030599218174135966290435729003342952605956307381323286279434907632338298807531952510190115738341879307021540891499348841675092447614606680822648001684774118537423454424371075390777449920695517027618386062613313845830007520449338265602976067371132007093287091274437470472306969772093101416928368190255151086574637721112523897844250569536967707854499699679468644549059879316368892300987931277361782154249992295763514822082698951936680331825288693984964651058209392398294887933203625094431173012381970684161403970198376793206832823764648042953118023287825098194558153017567173613320698112509961818815930416903515988885193458072738667385894228792284998920868058257492796104841984443634632449684875602336248270419786232090021609902353043699418491463140934317381436405462531520961836908887070167683964243781405927145635490613031072085103837505101157477041718986106873969655212671546889570350354")
|
||||
var infinity, _ = newNumber().SetString("1e1000")
|
||||
import "math/big"
|
||||
|
||||
var PI_RAT, _ = new(big.Rat).SetString("3.1415926535897932384626433832795028841971693993751058209749445923078164062862089986280348253421170679821480865132823066470938446095505822317253594081284811174502841027019385211055596446229489549303819644288109756659334461284756482337867831652712019091456485669234603486104543266482133936072602491412737245870066063155881748815209209628292540917153643678925903600113305305488204665213841469519415116094330572703657595919530921861173819326117931051185480744623799627495673518857527248912279381830119491298336733624406566430860213949463952247371907021798609437027705392171762931767523846748184676694051320005681271452635608277857713427577896091736371787214684409012249534301465495853710507922796892589235420199561121290219608640344181598136297747713099605187072113499999983729780499510597317328160963185950244594553469083026425223082533446850352619311881710100031378387528865875332083814206171776691473035982534904287554687311595628638823537875937519577818577805321712268066130019278766111959092164201989")
|
||||
var PI ArObject
|
||||
var e_RAT, _ = new(big.Rat).SetString("2.7182818284590452353602874713526624977572470936999595749669676277240766303535475945713821785251664274274663919320030599218174135966290435729003342952605956307381323286279434907632338298807531952510190115738341879307021540891499348841675092447614606680822648001684774118537423454424371075390777449920695517027618386062613313845830007520449338265602976067371132007093287091274437470472306969772093101416928368190255151086574637721112523897844250569536967707854499699679468644549059879316368892300987931277361782154249992295763514822082698951936680331825288693984964651058209392398294887933203625094431173012381970684161403970198376793206832823764648042953118023287825098194558153017567173613320698112509961818815930416903515988885193458072738667385894228792284998920868058257492796104841984443634632449684875602336248270419786232090021609902353043699418491463140934317381436405462531520961836908887070167683964243781405927145635490613031072085103837505101157477041718986106873969655212671546889570350354")
|
||||
var e ArObject
|
||||
|
||||
func init() {
|
||||
PI = Number(compiledNumber{PI_RAT})
|
||||
e = Number(compiledNumber{e_RAT})
|
||||
}
|
||||
|
||||
450
src/number.go
450
src/number.go
@@ -15,7 +15,7 @@ var octalCompile = makeRegex("( *)(-)?(0o[0-7]+(\\.[0-7]+)?(e((\\-|\\+)?([0-9]+(
|
||||
type number = *big.Rat
|
||||
|
||||
// create a new number type
|
||||
func newNumber() number {
|
||||
func newNumber() *big.Rat {
|
||||
return new(big.Rat)
|
||||
}
|
||||
|
||||
@@ -24,14 +24,14 @@ func isNumber(code UNPARSEcode) bool {
|
||||
}
|
||||
|
||||
// converts a number type to a string
|
||||
func numberToString(num number, simplify bool) string {
|
||||
func numberToString(num *big.Rat, simplify bool) string {
|
||||
if simplify {
|
||||
divPI := newNumber().Quo(num, PI)
|
||||
if divPI.Cmp(newNumber().SetInt64(1)) == 0 {
|
||||
divPI := new(big.Rat).Quo(num, PI_RAT)
|
||||
if divPI.Cmp(_one_Rat) == 0 {
|
||||
return "π"
|
||||
} else if divPI.Cmp(newNumber().SetInt64(-1)) == 0 {
|
||||
} else if divPI.Cmp(new(big.Rat).SetInt64(-1)) == 0 {
|
||||
return "-π"
|
||||
} else if divPI.Cmp(newNumber()) == 0 {
|
||||
} else if divPI.Cmp(_zero_Rat) == 0 {
|
||||
return "0"
|
||||
} else if divPI.Denom().Cmp(new(big.Int).SetInt64(1000)) <= 0 {
|
||||
num := divPI.RatString()
|
||||
@@ -59,7 +59,92 @@ type compiledNumber = struct {
|
||||
value any
|
||||
}
|
||||
|
||||
func isNumberInt(num ArObject) bool {
|
||||
value := num.obj["__value__"]
|
||||
switch x := value.(type) {
|
||||
case *big.Rat:
|
||||
return x.IsInt()
|
||||
case *big.Int:
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func numberToInt64(num ArObject) (int64, error) {
|
||||
value := num.obj["__value__"]
|
||||
switch x := value.(type) {
|
||||
case *big.Rat:
|
||||
return floor(x).Num().Int64(), nil
|
||||
case *big.Int:
|
||||
return x.Int64(), nil
|
||||
}
|
||||
return 0, fmt.Errorf("object cannot be converted to int64")
|
||||
}
|
||||
|
||||
func Int64ToNumber(num int64) ArObject {
|
||||
return Number(compiledNumber{big.NewInt(num)})
|
||||
}
|
||||
func CompareObjects(A ArObject, B ArObject) (ArObject, ArErr) {
|
||||
if X, ok := A.obj["__compare__"]; ok {
|
||||
resp, err := runCall(call{
|
||||
Callable: X,
|
||||
Args: []any{B},
|
||||
}, stack{}, 0)
|
||||
if !err.EXISTS {
|
||||
if resp, ok := resp.(ArObject); ok {
|
||||
return resp, ArErr{}
|
||||
}
|
||||
}
|
||||
} else if X, ok := B.obj["__PostCompare__"]; ok {
|
||||
resp, err := runCall(call{
|
||||
Callable: X,
|
||||
Args: []any{A},
|
||||
}, stack{}, 0)
|
||||
if !err.EXISTS {
|
||||
if resp, ok := resp.(ArObject); ok {
|
||||
return resp, ArErr{}
|
||||
}
|
||||
}
|
||||
}
|
||||
return ArObject{}, ArErr{"Type Error", "cannot add " + typeof(A) + " and " + typeof(B), 0, "", "", true}
|
||||
}
|
||||
|
||||
func AddObjects(A ArObject, B ArObject) (ArObject, ArErr) {
|
||||
if X, ok := A.obj["__Add__"]; ok {
|
||||
resp, err := runCall(call{
|
||||
Callable: X,
|
||||
Args: []any{B},
|
||||
}, stack{}, 0)
|
||||
if !err.EXISTS {
|
||||
if resp, ok := resp.(ArObject); ok {
|
||||
return resp, ArErr{}
|
||||
}
|
||||
}
|
||||
} else if X, ok := B.obj["__PostAdd__"]; ok {
|
||||
resp, err := runCall(call{
|
||||
Callable: X,
|
||||
Args: []any{A},
|
||||
}, stack{}, 0)
|
||||
if !err.EXISTS {
|
||||
if resp, ok := resp.(ArObject); ok {
|
||||
return resp, ArErr{}
|
||||
}
|
||||
}
|
||||
}
|
||||
return ArObject{}, ArErr{"Type Error", "cannot add " + typeof(A) + " and " + typeof(B), 0, "", "", true}
|
||||
}
|
||||
|
||||
var _one = big.NewInt(1)
|
||||
var _one_Rat = big.NewRat(1, 1)
|
||||
var _one_Number ArObject
|
||||
var _zero = big.NewInt(0)
|
||||
var _zero_Rat = big.NewRat(0, 1)
|
||||
var _zero_Number ArObject
|
||||
|
||||
func init() {
|
||||
_zero_Number = Number(compiledNumber{_zero})
|
||||
_one_Number = Number(compiledNumber{_one})
|
||||
}
|
||||
|
||||
func Number(number compiledNumber) ArObject {
|
||||
// copy value to new number
|
||||
@@ -110,10 +195,66 @@ func Number(number compiledNumber) ArObject {
|
||||
return strings.Join(output, ""), ArErr{}
|
||||
},
|
||||
}
|
||||
val.obj["__Compare__"] = builtinFunc{
|
||||
"__Compare__",
|
||||
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{CurrentNumber.Cmp(ReceivingNumber)}), ArErr{}
|
||||
case *big.Rat:
|
||||
return Number(compiledNumber{new(big.Rat).SetInt(CurrentNumber).Cmp(ReceivingNumber)}), ArErr{}
|
||||
}
|
||||
return nil, ArErr{"Type Error", "expected number, got " + typeof(a[0]), 0, "", "", true}
|
||||
},
|
||||
}
|
||||
val.obj["__PostCompare__"] = builtinFunc{
|
||||
"__PostCompare__",
|
||||
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{ReceivingNumber.Cmp(CurrentNumber)}), ArErr{}
|
||||
case *big.Rat:
|
||||
return Number(compiledNumber{ReceivingNumber.Cmp(new(big.Rat).SetInt(CurrentNumber))}), ArErr{}
|
||||
}
|
||||
return nil, ArErr{"Type Error", "expected number, got " + typeof(a[0]), 0, "", "", true}
|
||||
},
|
||||
}
|
||||
val.obj["__json__"] = builtinFunc{
|
||||
"__json__",
|
||||
val.obj["__string__"].(builtinFunc).FUNC,
|
||||
}
|
||||
val.obj["__Boolean__"] = builtinFunc{
|
||||
"__Boolean__",
|
||||
func(a ...any) (any, ArErr) {
|
||||
return _zero, ArErr{}
|
||||
return CurrentNumber.Cmp(_zero) != 0, ArErr{}
|
||||
},
|
||||
}
|
||||
|
||||
val.obj["__factorial__"] = builtinFunc{
|
||||
"__factorial__",
|
||||
func(a ...any) (any, ArErr) {
|
||||
if CurrentNumber.Cmp(_zero) < 0 {
|
||||
return nil, ArErr{"Runtime Error", "factorial of a negative number", 0, "", "", true}
|
||||
}
|
||||
output := new(big.Int).SetInt64(1)
|
||||
for i := new(big.Int).SetInt64(2); i.Cmp(CurrentNumber) <= 0; i.Add(i, _one) {
|
||||
output.Mul(output, i)
|
||||
}
|
||||
return Number(compiledNumber{output}), ArErr{}
|
||||
},
|
||||
}
|
||||
|
||||
@@ -130,6 +271,8 @@ func Number(number compiledNumber) ArObject {
|
||||
switch ReceivingNumber := a[0].(type) {
|
||||
case *big.Int:
|
||||
return Number(compiledNumber{new(big.Int).Add(CurrentNumber, ReceivingNumber)}), ArErr{}
|
||||
case *big.Rat:
|
||||
return Number(compiledNumber{new(big.Rat).Add(new(big.Rat).SetInt(CurrentNumber), ReceivingNumber)}), ArErr{}
|
||||
}
|
||||
return nil, ArErr{"Type Error", "expected number, got " + typeof(a[0]), 0, "", "", true}
|
||||
},
|
||||
@@ -151,6 +294,8 @@ func Number(number compiledNumber) ArObject {
|
||||
switch ReceivingNumber := a[0].(type) {
|
||||
case *big.Int:
|
||||
return Number(compiledNumber{new(big.Int).Sub(CurrentNumber, ReceivingNumber)}), ArErr{}
|
||||
case *big.Rat:
|
||||
return Number(compiledNumber{new(big.Rat).Sub(new(big.Rat).SetInt(CurrentNumber), ReceivingNumber)}), ArErr{}
|
||||
}
|
||||
return nil, ArErr{"Type Error", "expected number, got " + typeof(a[0]), 0, "", "", true}
|
||||
},
|
||||
@@ -168,12 +313,301 @@ func Number(number compiledNumber) ArObject {
|
||||
switch ReceivingNumber := a[0].(type) {
|
||||
case *big.Int:
|
||||
return Number(compiledNumber{new(big.Int).Sub(ReceivingNumber, CurrentNumber)}), ArErr{}
|
||||
case *big.Rat:
|
||||
return Number(compiledNumber{new(big.Rat).Sub(ReceivingNumber, new(big.Rat).SetInt(CurrentNumber))}), ArErr{}
|
||||
}
|
||||
return nil, ArErr{"Type Error", "expected number, got " + typeof(a[0]), 0, "", "", true}
|
||||
},
|
||||
}
|
||||
val.obj["__Multiply__"] = builtinFunc{
|
||||
"__Multiply__",
|
||||
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).Mul(CurrentNumber, ReceivingNumber)}), ArErr{}
|
||||
case *big.Rat:
|
||||
panic("not implemented")
|
||||
return Number(compiledNumber{new(big.Rat).Mul(new(big.Rat).SetInt(CurrentNumber), ReceivingNumber)}), ArErr{}
|
||||
}
|
||||
return nil, ArErr{"Type Error", "expected number, got " + typeof(a[0]), 0, "", "", true}
|
||||
},
|
||||
}
|
||||
val.obj["__PostMultiply__"] = builtinFunc{
|
||||
"__PostMultiply__",
|
||||
val.obj["__Multiply__"].(builtinFunc).FUNC,
|
||||
}
|
||||
val.obj["__Divide__"] = builtinFunc{
|
||||
"__Divide__",
|
||||
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).Quo(CurrentNumber, ReceivingNumber)}), ArErr{}
|
||||
case *big.Rat:
|
||||
return Number(compiledNumber{new(big.Rat).Quo(new(big.Rat).SetInt(CurrentNumber), ReceivingNumber)}), ArErr{}
|
||||
}
|
||||
return nil, ArErr{"Type Error", "expected number, got " + typeof(a[0]), 0, "", "", true}
|
||||
},
|
||||
}
|
||||
val.obj["__PostDivide__"] = builtinFunc{
|
||||
"__PostDivide_",
|
||||
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).Quo(ReceivingNumber, CurrentNumber)}), ArErr{}
|
||||
case *big.Rat:
|
||||
return Number(compiledNumber{new(big.Rat).Quo(ReceivingNumber, new(big.Rat).SetInt(CurrentNumber))}), ArErr{}
|
||||
}
|
||||
return nil, ArErr{"Type Error", "expected number, got " + typeof(a[0]), 0, "", "", true}
|
||||
},
|
||||
}
|
||||
val.obj
|
||||
|
||||
case *big.Rat:
|
||||
val.obj["__string__"] = builtinFunc{
|
||||
"__string__",
|
||||
func(a ...any) (any, ArErr) {
|
||||
return ArString(numberToString(CurrentNumber, false)), 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, numberToString(CurrentNumber, true))
|
||||
if coloured {
|
||||
output = append(output, "\x1b[0m")
|
||||
}
|
||||
return ArString(strings.Join(output, "")), ArErr{}
|
||||
},
|
||||
}
|
||||
|
||||
val.obj["__json__"] = builtinFunc{
|
||||
"__json__",
|
||||
val.obj["__string__"].(builtinFunc).FUNC,
|
||||
}
|
||||
|
||||
val.obj["__Boolean__"] = builtinFunc{
|
||||
"__Boolean__",
|
||||
func(a ...any) (any, ArErr) {
|
||||
return CurrentNumber.Cmp(_zero_Rat) != 0, ArErr{}
|
||||
},
|
||||
}
|
||||
|
||||
val.obj["__Compare__"] = builtinFunc{
|
||||
"__Compare__",
|
||||
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{CurrentNumber.Cmp(new(big.Rat).SetInt(ReceivingNumber))}), ArErr{}
|
||||
case *big.Rat:
|
||||
return Number(compiledNumber{CurrentNumber.Cmp(ReceivingNumber)}), ArErr{}
|
||||
}
|
||||
return nil, ArErr{"Type Error", "expected number, got " + typeof(a[0]), 0, "", "", true}
|
||||
},
|
||||
}
|
||||
val.obj["__PostCompare__"] = builtinFunc{
|
||||
"__PostCompare__",
|
||||
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{CurrentNumber.Cmp(new(big.Rat).SetInt(ReceivingNumber))}), ArErr{}
|
||||
case *big.Rat:
|
||||
return Number(compiledNumber{CurrentNumber.Cmp(ReceivingNumber)}), ArErr{}
|
||||
}
|
||||
return nil, ArErr{"Type Error", "expected number, got " + typeof(a[0]), 0, "", "", true}
|
||||
},
|
||||
}
|
||||
|
||||
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.Rat).Add(CurrentNumber, new(big.Rat).SetInt(ReceivingNumber))}), ArErr{}
|
||||
case *big.Rat:
|
||||
return Number(compiledNumber{new(big.Rat).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.Rat).Sub(CurrentNumber, new(big.Rat).SetInt(ReceivingNumber))}), ArErr{}
|
||||
case *big.Rat:
|
||||
return Number(compiledNumber{new(big.Rat).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.Rat).Sub(new(big.Rat).SetInt(ReceivingNumber), CurrentNumber)}), ArErr{}
|
||||
case *big.Rat:
|
||||
return Number(compiledNumber{new(big.Rat).Sub(ReceivingNumber, CurrentNumber)}), ArErr{}
|
||||
}
|
||||
return nil, ArErr{"Type Error", "expected number, got " + typeof(a[0]), 0, "", "", true}
|
||||
},
|
||||
}
|
||||
val.obj["__Multiply__"] = builtinFunc{
|
||||
"__Multiply__",
|
||||
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.Rat).Mul(CurrentNumber, new(big.Rat).SetInt(ReceivingNumber))}), ArErr{}
|
||||
case *big.Rat:
|
||||
return Number(compiledNumber{new(big.Rat).Mul(CurrentNumber, ReceivingNumber)}), ArErr{}
|
||||
}
|
||||
return nil, ArErr{"Type Error", "expected number, got " + typeof(a[0]), 0, "", "", true}
|
||||
},
|
||||
}
|
||||
val.obj["__PostMultiply__"] = builtinFunc{
|
||||
"__PostMultiply__",
|
||||
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.Rat).Mul(new(big.Rat).SetInt(ReceivingNumber), CurrentNumber)}), ArErr{}
|
||||
case *big.Rat:
|
||||
return Number(compiledNumber{new(big.Rat).Mul(ReceivingNumber, CurrentNumber)}), ArErr{}
|
||||
}
|
||||
return nil, ArErr{"Type Error", "expected number, got " + typeof(a[0]), 0, "", "", true}
|
||||
},
|
||||
}
|
||||
|
||||
val.obj["__Divide__"] = builtinFunc{
|
||||
"__Divide__",
|
||||
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.Rat).Quo(CurrentNumber, new(big.Rat).SetInt(ReceivingNumber))}), ArErr{}
|
||||
case *big.Rat:
|
||||
return Number(compiledNumber{new(big.Rat).Quo(CurrentNumber, ReceivingNumber)}), ArErr{}
|
||||
}
|
||||
return nil, ArErr{"Type Error", "expected number, got " + typeof(a[0]), 0, "", "", true}
|
||||
},
|
||||
}
|
||||
val.obj["__PostDivide__"] = builtinFunc{
|
||||
"__PostDivide__",
|
||||
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.Rat).Quo(new(big.Rat).SetInt(ReceivingNumber), CurrentNumber)}), ArErr{}
|
||||
case *big.Rat:
|
||||
return Number(compiledNumber{new(big.Rat).Quo(ReceivingNumber, CurrentNumber)}), ArErr{}
|
||||
}
|
||||
return nil, ArErr{"Type Error", "expected number, got " + typeof(a[0]), 0, "", "", true}
|
||||
},
|
||||
}
|
||||
|
||||
val.obj["__factorial__"] = builtinFunc{
|
||||
"__factorial__",
|
||||
func(a ...any) (any, ArErr) {
|
||||
return nil, ArErr{"Runtime Error", "factorial of a non-integer number", 0, "", "", true}
|
||||
},
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return val
|
||||
|
||||
@@ -431,6 +431,22 @@ func calcMul(o operationType, stack stack, stacklevel int) (any, ArErr) {
|
||||
}
|
||||
}
|
||||
}
|
||||
if x, ok := resp.(ArObject); ok {
|
||||
if y, ok := x.obj["__PostMultiply__"]; 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{
|
||||
"Runtime Error",
|
||||
"Cannot multiply type '" + typeof(resp) + "'",
|
||||
|
||||
@@ -2,6 +2,7 @@ package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"math/big"
|
||||
"reflect"
|
||||
)
|
||||
|
||||
@@ -210,6 +211,8 @@ func runVal(line any, stack stack, stacklevel int) (any, ArErr) {
|
||||
return runTryCatch(x, stack, stacklevel+1)
|
||||
case compiledNumber:
|
||||
return Number(x), ArErr{}
|
||||
case *big.Rat, *big.Int:
|
||||
return Number(compiledNumber{x}), ArErr{}
|
||||
case bool, ArObject, nil, Callable, builtinFunc, anymap:
|
||||
return x, ArErr{}
|
||||
}
|
||||
@@ -224,6 +227,7 @@ func runVal(line any, stack stack, stacklevel int) (any, ArErr) {
|
||||
}
|
||||
}
|
||||
fmt.Println("unreachable", reflect.TypeOf(line))
|
||||
fmt.Println(line)
|
||||
panic("unreachable")
|
||||
}
|
||||
|
||||
|
||||
@@ -5,6 +5,7 @@ import (
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/fatih/color"
|
||||
"golang.org/x/text/cases"
|
||||
"golang.org/x/text/language"
|
||||
)
|
||||
@@ -68,6 +69,32 @@ func ArString(str string) ArObject {
|
||||
},
|
||||
}
|
||||
|
||||
obj.obj["__string__"] = builtinFunc{
|
||||
"__string__",
|
||||
func(a ...any) (any, ArErr) {
|
||||
return str, ArErr{}
|
||||
}}
|
||||
obj.obj["__repr__"] = builtinFunc{
|
||||
"__repr__",
|
||||
func(a ...any) (any, ArErr) {
|
||||
colored := false
|
||||
if len(a) == 1 {
|
||||
if typeof(a[0]) != "boolean" {
|
||||
return nil, ArErr{"Type Error", "expected boolean, got " + typeof(a[0]), 0, "", "", true}
|
||||
}
|
||||
colored = a[0].(bool)
|
||||
}
|
||||
output := []string{}
|
||||
quoted := strconv.Quote(str)
|
||||
if colored {
|
||||
output = append(output, color.New(33).Sprint(quoted))
|
||||
} else {
|
||||
output = append(output, quoted)
|
||||
}
|
||||
return ArString(strings.Join(output, "")), ArErr{}
|
||||
},
|
||||
}
|
||||
|
||||
obj.obj["__setindex__"] = builtinFunc{
|
||||
"__setindex__",
|
||||
func(a ...any) (any, ArErr) {
|
||||
|
||||
@@ -10,7 +10,7 @@ import (
|
||||
"github.com/jwalton/go-supportscolor"
|
||||
)
|
||||
|
||||
func anyToArgon(x any, quote bool, simplify bool, depth int, indent int, colored bool, plain int) string {
|
||||
func anyToArgon(x any, representive bool, simplify bool, depth int, indent int, colored bool, plain int) string {
|
||||
output := []string{}
|
||||
maybenewline := ""
|
||||
if plain == 1 {
|
||||
@@ -28,17 +28,6 @@ func anyToArgon(x any, quote bool, simplify bool, depth int, indent int, colored
|
||||
return strings.Join(output, "")
|
||||
}
|
||||
switch x := x.(type) {
|
||||
case string:
|
||||
if !quote {
|
||||
output = append(output, x)
|
||||
break
|
||||
}
|
||||
quoted := strconv.Quote(x)
|
||||
if colored {
|
||||
output = append(output, color.New(33).Sprint(quoted))
|
||||
} else {
|
||||
output = append(output, quoted)
|
||||
}
|
||||
case bool:
|
||||
if colored {
|
||||
output = append(output, "\x1b[35;5;240m")
|
||||
@@ -56,7 +45,7 @@ func anyToArgon(x any, quote bool, simplify bool, depth int, indent int, colored
|
||||
output = append(output, "\x1b[0m")
|
||||
}
|
||||
case ArObject:
|
||||
if callable, ok := x.obj["__string__"]; ok && !quote {
|
||||
if callable, ok := x.obj["__string__"]; ok && !representive {
|
||||
val, err := runCall(
|
||||
call{
|
||||
Callable: callable,
|
||||
@@ -66,7 +55,7 @@ func anyToArgon(x any, quote bool, simplify bool, depth int, indent int, colored
|
||||
0,
|
||||
)
|
||||
if !err.EXISTS {
|
||||
output = append(output, anyToArgon(val, false, simplify, depth, indent, colored, plain))
|
||||
output = append(output, fmt.Sprint(ArValidToAny(val)))
|
||||
break
|
||||
}
|
||||
} else if callable, ok := x.obj["__repr__"]; ok {
|
||||
@@ -79,11 +68,11 @@ func anyToArgon(x any, quote bool, simplify bool, depth int, indent int, colored
|
||||
0,
|
||||
)
|
||||
if !err.EXISTS {
|
||||
output = append(output, anyToArgon(val, false, simplify, depth, indent, colored, plain))
|
||||
output = append(output, fmt.Sprint(ArValidToAny(val)))
|
||||
break
|
||||
}
|
||||
} else if val, ok := x.obj["__value__"]; ok {
|
||||
output = append(output, anyToArgon(val, quote, simplify, depth, indent, colored, plain))
|
||||
output = append(output, anyToArgon(val, representive, simplify, depth, indent, colored, plain))
|
||||
break
|
||||
}
|
||||
output = append(output, "<object>")
|
||||
|
||||
38
src/trig.go
38
src/trig.go
@@ -14,9 +14,9 @@ type sinCacheValue struct {
|
||||
|
||||
var sinCache = []sinCacheValue{
|
||||
{newNumber(), newNumber()},
|
||||
{newNumber().Quo(PI, newNumber().SetInt64(2)), newNumber().SetInt64(1)},
|
||||
{PI, newNumber()},
|
||||
{newNumber().Add(PI, newNumber().Quo(PI, newNumber().SetInt64(2))), newNumber().SetInt64(-1)},
|
||||
{newNumber().Quo(PI_RAT, newNumber().SetInt64(2)), newNumber().SetInt64(1)},
|
||||
{PI_RAT, newNumber()},
|
||||
{newNumber().Add(PI_RAT, newNumber().Quo(PI_RAT, newNumber().SetInt64(2))), newNumber().SetInt64(-1)},
|
||||
}
|
||||
|
||||
func init() {
|
||||
@@ -37,10 +37,10 @@ var ArSin = builtinFunc{"sin", func(args ...any) (any, ArErr) {
|
||||
}
|
||||
}
|
||||
num := newNumber().Set(args[0].(number))
|
||||
toTrim := newNumber().Mul(PI, newNumber().SetInt64(2))
|
||||
toTrim := newNumber().Mul(PI_RAT, newNumber().SetInt64(2))
|
||||
toTrim.Quo(num, toTrim)
|
||||
toTrim = floor(toTrim)
|
||||
toTrim.Mul(toTrim, newNumber().Mul(PI, newNumber().SetInt64(2)))
|
||||
toTrim.Mul(toTrim, newNumber().Mul(PI_RAT, newNumber().SetInt64(2)))
|
||||
num.Sub(num, toTrim)
|
||||
|
||||
for i := 0; i < len(sinCache); i++ {
|
||||
@@ -49,7 +49,7 @@ var ArSin = builtinFunc{"sin", func(args ...any) (any, ArErr) {
|
||||
}
|
||||
}
|
||||
|
||||
num.Quo(num, PI)
|
||||
num.Quo(num, PI_RAT)
|
||||
num.Mul(num, PIFloatInaccuracy)
|
||||
n, _ := num.Float64()
|
||||
outputnum := newNumber().SetFloat64(math.Sin(n))
|
||||
@@ -78,7 +78,7 @@ var ArArcsin = builtinFunc{"arcsin", func(args ...any) (any, ArErr) {
|
||||
}
|
||||
outputnum := newNumber().SetFloat64(math.Asin(n))
|
||||
outputnum.Quo(outputnum, PIFloatInaccuracy)
|
||||
outputnum.Mul(outputnum, PI)
|
||||
outputnum.Mul(outputnum, PI_RAT)
|
||||
return outputnum, ArErr{}
|
||||
}}
|
||||
|
||||
@@ -95,7 +95,7 @@ var ArCos = builtinFunc{"cos", func(args ...any) (any, ArErr) {
|
||||
EXISTS: true,
|
||||
}
|
||||
}
|
||||
return builtinCall(ArSin, []any{newNumber().Add(args[0].(number), newNumber().Quo(PI, newNumber().SetInt64(2)))})
|
||||
return builtinCall(ArSin, []any{newNumber().Add(args[0].(number), newNumber().Quo(PI_RAT, newNumber().SetInt64(2)))})
|
||||
}}
|
||||
var ArArccos = builtinFunc{"arccos", func(args ...any) (any, ArErr) {
|
||||
if len(args) != 1 {
|
||||
@@ -120,7 +120,7 @@ var ArArccos = builtinFunc{"arccos", func(args ...any) (any, ArErr) {
|
||||
}
|
||||
outputnum := newNumber().SetFloat64(math.Acos(n))
|
||||
outputnum.Quo(outputnum, PIFloatInaccuracy)
|
||||
outputnum.Mul(outputnum, PI)
|
||||
outputnum.Mul(outputnum, PI_RAT)
|
||||
return outputnum, ArErr{}
|
||||
}}
|
||||
|
||||
@@ -138,7 +138,7 @@ var ArTan = builtinFunc{"tan", func(args ...any) (any, ArErr) {
|
||||
}
|
||||
}
|
||||
num := newNumber().Set(args[0].(number))
|
||||
num.Quo(num, PI)
|
||||
num.Quo(num, PI_RAT)
|
||||
num.Mul(num, PIFloatInaccuracy)
|
||||
n, _ := num.Float64()
|
||||
outputnum := newNumber().SetFloat64(math.Tan(n))
|
||||
@@ -161,7 +161,7 @@ var ArArctan = builtinFunc{"arctan", func(args ...any) (any, ArErr) {
|
||||
n, _ := num.Float64()
|
||||
outputnum := newNumber().SetFloat64(math.Atan(n))
|
||||
outputnum.Quo(outputnum, PIFloatInaccuracy)
|
||||
outputnum.Mul(outputnum, PI)
|
||||
outputnum.Mul(outputnum, PI_RAT)
|
||||
return outputnum, ArErr{}
|
||||
}}
|
||||
|
||||
@@ -179,7 +179,7 @@ var ArCosec = builtinFunc{"cosec", func(args ...any) (any, ArErr) {
|
||||
}
|
||||
}
|
||||
num := newNumber().Set(args[0].(number))
|
||||
num.Quo(num, PI)
|
||||
num.Quo(num, PI_RAT)
|
||||
num.Mul(num, PIFloatInaccuracy)
|
||||
n, _ := num.Float64()
|
||||
outputnum := newNumber().SetFloat64(1 / math.Sin(n))
|
||||
@@ -208,7 +208,7 @@ var ArArccosec = builtinFunc{"arccosec", func(args ...any) (any, ArErr) {
|
||||
}
|
||||
outputnum := newNumber().SetFloat64(math.Asin(1 / n))
|
||||
outputnum.Quo(outputnum, PIFloatInaccuracy)
|
||||
outputnum.Mul(outputnum, PI)
|
||||
outputnum.Mul(outputnum, PI_RAT)
|
||||
return outputnum, ArErr{}
|
||||
}}
|
||||
|
||||
@@ -226,7 +226,7 @@ var ArSec = builtinFunc{"sec", func(args ...any) (any, ArErr) {
|
||||
}
|
||||
}
|
||||
num := newNumber().Set(args[0].(number))
|
||||
num.Quo(num, PI)
|
||||
num.Quo(num, PI_RAT)
|
||||
num.Mul(num, PIFloatInaccuracy)
|
||||
n, _ := num.Float64()
|
||||
outputnum := newNumber().SetFloat64(1 / math.Cos(n))
|
||||
@@ -256,7 +256,7 @@ var ArArcsec = builtinFunc{"arcsec", func(args ...any) (any, ArErr) {
|
||||
}
|
||||
outputnum := newNumber().SetFloat64(math.Acos(1 / n))
|
||||
outputnum.Quo(outputnum, PIFloatInaccuracy)
|
||||
outputnum.Mul(outputnum, PI)
|
||||
outputnum.Mul(outputnum, PI_RAT)
|
||||
return outputnum, ArErr{}
|
||||
}}
|
||||
|
||||
@@ -274,7 +274,7 @@ var ArCot = builtinFunc{"cot", func(args ...any) (any, ArErr) {
|
||||
}
|
||||
}
|
||||
num := newNumber().Set(args[0].(number))
|
||||
num.Quo(num, PI)
|
||||
num.Quo(num, PI_RAT)
|
||||
num.Mul(num, PIFloatInaccuracy)
|
||||
n, _ := num.Float64()
|
||||
outputnum := newNumber().SetFloat64(1 / math.Tan(n))
|
||||
@@ -298,7 +298,7 @@ var ArArccot = builtinFunc{"arccot", func(args ...any) (any, ArErr) {
|
||||
n, _ := num.Float64()
|
||||
outputnum := newNumber().SetFloat64(math.Atan(1 / n))
|
||||
outputnum.Quo(outputnum, PIFloatInaccuracy)
|
||||
outputnum.Mul(outputnum, PI)
|
||||
outputnum.Mul(outputnum, PI_RAT)
|
||||
return outputnum, ArErr{}
|
||||
}}
|
||||
|
||||
@@ -316,7 +316,7 @@ var ArToDeg = builtinFunc{"toDeg", func(args ...any) (any, ArErr) {
|
||||
}
|
||||
}
|
||||
num := newNumber().Set(args[0].(number))
|
||||
num.Quo(num, PI)
|
||||
num.Quo(num, PI_RAT)
|
||||
num.Mul(num, newNumber().SetInt64(180))
|
||||
return num, ArErr{}
|
||||
}}
|
||||
@@ -336,6 +336,6 @@ var ArToRad = builtinFunc{"toRad", func(args ...any) (any, ArErr) {
|
||||
}
|
||||
num := newNumber().Set(args[0].(number))
|
||||
num.Quo(num, newNumber().SetInt64(180))
|
||||
num.Mul(num, PI)
|
||||
num.Mul(num, PI_RAT)
|
||||
return num, ArErr{}
|
||||
}}
|
||||
|
||||
@@ -8,6 +8,8 @@ func typeof(val any) string {
|
||||
return "boolean"
|
||||
case string:
|
||||
return "string"
|
||||
case number:
|
||||
return "number"
|
||||
case []any:
|
||||
return "array"
|
||||
case anymap:
|
||||
|
||||
@@ -76,12 +76,13 @@ func parseVariable(code UNPARSEcode) (accessVariable, bool, ArErr, int) {
|
||||
}
|
||||
|
||||
func readVariable(v accessVariable, stack stack) (any, ArErr) {
|
||||
name := ArString(v.Name)
|
||||
for i := len(stack) - 1; i >= 0; i-- {
|
||||
callable, ok := stack[i].obj["__Contains__"]
|
||||
if !ok {
|
||||
continue
|
||||
}
|
||||
contains, err := builtinCall(callable, []any{v.Name})
|
||||
contains, err := builtinCall(callable, []any{name})
|
||||
if err.EXISTS {
|
||||
return nil, err
|
||||
}
|
||||
@@ -90,7 +91,7 @@ func readVariable(v accessVariable, stack stack) (any, ArErr) {
|
||||
if !ok {
|
||||
continue
|
||||
}
|
||||
return builtinCall(callable, []any{v.Name})
|
||||
return builtinCall(callable, []any{name})
|
||||
}
|
||||
}
|
||||
return nil, ArErr{"Name Error", "variable \"" + v.Name + "\" does not exist", v.Line, v.Path, v.Code, true}
|
||||
@@ -159,7 +160,7 @@ func parseSetVariable(code UNPARSEcode, index int, lines []UNPARSEcode, isLine i
|
||||
params = x.params
|
||||
toset = x.toset
|
||||
if toset == nil {
|
||||
return setVariable{}, false, ArErr{"Type Error", "can't set for non variable, did you mean to put 'let' before?", code.line, code.path, code.realcode, true}, 1
|
||||
return setVariable{}, false, ArErr{"Type Error", "can't set for non variable, did you mean '=='?", code.line, code.path, code.realcode, true}, 1
|
||||
}
|
||||
default:
|
||||
return setVariable{}, false, ArErr{"Type Error", "can't set for non variable, did you mean '=='?", code.line, code.path, code.realcode, true}, 1
|
||||
@@ -223,7 +224,7 @@ func parseAutoAsignVariable(code UNPARSEcode, index int, lines []UNPARSEcode, is
|
||||
toset = x.toset
|
||||
default:
|
||||
if i == len(equalsplit)-1 {
|
||||
return setVariable{}, false, ArErr{"Type Error", "can't set for non variable, did you mean to put 'let' before?", code.line, code.path, code.realcode, true}, 1
|
||||
return setVariable{}, false, ArErr{"Type Error", "can't set for non variable, did you mean '=='?", code.line, code.path, code.realcode, true}, 1
|
||||
}
|
||||
continue
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user