make strings object

This commit is contained in:
2023-03-19 01:10:23 +00:00
parent c725d26c01
commit 2e04bb0152
26 changed files with 528 additions and 124 deletions

View File

@@ -1,6 +1,8 @@
package main
import "strings"
import (
"strings"
)
var arrayCompile = makeRegex(`( *)\[(.|\n)*\]( *)`)
@@ -20,7 +22,7 @@ func ArArray(arr []any) ArObject {
"array",
anymap{
"__value__": arr,
"length": len(arr),
"length": newNumber().SetUint64(uint64(len(arr))),
},
}
val.obj["remove"] = builtinFunc{
@@ -56,7 +58,7 @@ func ArArray(arr []any) ArObject {
}
}
arr = append(arr[:num], arr[num+1:]...)
val.obj["length"] = len(arr)
val.obj["length"] = newNumber().SetUint64(uint64(len(arr)))
val.obj["__value__"] = arr
return nil, ArErr{}
}}
@@ -71,7 +73,7 @@ func ArArray(arr []any) ArObject {
}
}
arr = append(arr, args...)
val.obj["length"] = len(arr)
val.obj["length"] = newNumber().SetUint64(uint64(len(arr)))
val.obj["__value__"] = arr
return nil, ArErr{}
},
@@ -109,7 +111,7 @@ func ArArray(arr []any) ArObject {
}
}
arr = append(arr[:num], append(args[1:], arr[num:]...)...)
val.obj["length"] = len(arr)
val.obj["length"] = newNumber().SetUint64(uint64(len(arr)))
val.obj["__value__"] = arr
return nil, ArErr{}
},
@@ -149,13 +151,13 @@ func ArArray(arr []any) ArObject {
}
v := arr[num]
arr = append(arr[:num], arr[num+1:]...)
val.obj["length"] = len(arr)
val.obj["length"] = newNumber().SetUint64(uint64(len(arr)))
val.obj["__value__"] = arr
return v, ArErr{}
}
v := arr[len(arr)-1]
arr = arr[:len(arr)-1]
val.obj["length"] = len(arr)
val.obj["length"] = newNumber().SetUint64(uint64(len(arr)))
val.obj["__value__"] = arr
return v, ArErr{}
},
@@ -171,7 +173,7 @@ func ArArray(arr []any) ArObject {
}
}
arr = []any{}
val.obj["length"] = len(arr)
val.obj["length"] = newNumber().SetUint64(uint64(len(arr)))
val.obj["__value__"] = arr
return nil, ArErr{}
},
@@ -199,6 +201,66 @@ func ArArray(arr []any) ArObject {
return nil, ArErr{}
},
}
val.obj["sort"] = builtinFunc{
"sort",
func(args ...any) (any, ArErr) {
if len(args) > 2 {
return nil, ArErr{
TYPE: "TypeError",
message: "too many arguments",
EXISTS: true,
}
}
reverse := false
if len(args) >= 1 {
if typeof(args[0]) != "boolean" {
return nil, ArErr{
TYPE: "TypeError",
message: "argument must be a boolean",
EXISTS: true,
}
}
reverse = args[0].(bool)
}
if len(args) == 2 {
if typeof(args[1]) != "function" {
return nil, ArErr{
TYPE: "TypeError",
message: "argument must be a function",
EXISTS: true,
}
}
output, err := quickSort(arr, func(a any) (any, ArErr) {
return runCall(call{
args[1],
[]any{a}, "", 0, "",
}, stack{vars, newscope()}, 0)
})
if err.EXISTS {
return nil, err
}
arr = output
val.obj["length"] = len(arr)
val.obj["__value__"] = arr
return nil, ArErr{}
}
output, err := quickSort(arr, func(a any) (any, ArErr) {
return a, ArErr{}
})
if err.EXISTS {
return nil, err
}
if reverse {
for i, j := 0, len(output)-1; i < j; i, j = i+1, j-1 {
output[i], output[j] = output[j], output[i]
}
}
arr = output
val.obj["length"] = len(arr)
val.obj["__value__"] = arr
return nil, ArErr{}
},
}
val.obj["map"] = builtinFunc{
"map",
func(args ...any) (any, ArErr) {
@@ -320,6 +382,7 @@ func ArArray(arr []any) ArObject {
}
output := []string{}
for _, v := range arr {
v = ArValidToAny(v)
if typeof(v) != "string" {
return nil, ArErr{
TYPE: "TypeError",
@@ -329,7 +392,7 @@ func ArArray(arr []any) ArObject {
}
output = append(output, v.(string))
}
return strings.Join(output, args[0].(string)), ArErr{}
return ArString(strings.Join(output, args[0].(string))), ArErr{}
},
}
val.obj["concat"] = builtinFunc{
@@ -356,15 +419,6 @@ func ArArray(arr []any) ArObject {
return val
}
func potentialAnyArrayToArArray(arr any) any {
switch arr := arr.(type) {
case []any:
return ArArray(arr)
default:
return arr
}
}
func parseArray(code UNPARSEcode, index int, codelines []UNPARSEcode) (any, bool, ArErr, int) {
trimmed := strings.TrimSpace(code.code)
trimmed = trimmed[1 : len(trimmed)-1]

30
src/arvalid.go Normal file
View File

@@ -0,0 +1,30 @@
package main
func AnyToArValid(arr any) any {
switch arr := arr.(type) {
case []any:
return ArArray(arr)
case string:
return ArString(arr)
default:
return arr
}
}
func ArValidToAny(a any) any {
switch a := a.(type) {
case ArObject:
switch a.TYPE {
case "string":
return a.obj["__value__"]
case "array":
return a.obj["__value__"]
case "class":
return a.obj["__value__"]
default:
return a.obj
}
default:
return a
}
}

View File

@@ -10,9 +10,15 @@ type builtinFunc struct {
}
func ArgonString(args ...any) (any, ArErr) {
return anyToArgon(args[0], true, false, 3, 0, false, 0), ArErr{}
return ArString(anyToArgon(args[0], true, false, 3, 0, false, 0)), ArErr{}
}
func ArgonPassworInput(args ...any) (any, ArErr) {
resp, err := getPassword(args...)
if err != nil {
return nil, ArErr{TYPE: "Runtime Error", message: err.Error(), EXISTS: true}
}
return ArString(resp), ArErr{}
}
func ArgonInput(args ...any) (any, ArErr) {
return input(args...), ArErr{}
}

View File

@@ -6,21 +6,10 @@ func init() {
vars.obj["global"] = vars
vars.obj["term"] = ArTerm
vars.obj["input"] = builtinFunc{"input", ArgonInput}
vars.obj["passwordInput"] = builtinFunc{"passwordInput", ArgonPassworInput}
vars.obj["number"] = builtinFunc{"number", ArgonNumber}
vars.obj["string"] = builtinFunc{"string", ArgonString}
vars.obj["infinity"] = infinity
vars.obj["length"] = builtinFunc{"length", func(a ...any) (any, ArErr) {
switch x := a[0].(type) {
case string:
return len(x), ArErr{}
case ArObject:
if x.TYPE == "array" {
return len(x.obj["__value__"].([]any)), ArErr{}
}
return len(x.obj), ArErr{}
}
return nil, ArErr{TYPE: "TypeError", message: "Cannot get length of " + typeof(a[0]), EXISTS: true}
}}
vars.obj["map"] = builtinFunc{"map", func(a ...any) (any, ArErr) {
if len(a) == 0 {
return Map(anymap{}), ArErr{}
@@ -48,7 +37,7 @@ func init() {
case string:
newmap := anymap{}
for i, v := range x {
newmap[i] = string(v)
newmap[i] = ArString(string(v))
}
return Map(newmap), ArErr{}
}
@@ -62,7 +51,7 @@ func init() {
case string:
newarray := []any{}
for _, v := range x {
newarray = append(newarray, string(v))
newarray = append(newarray, ArString(string(v)))
}
return ArArray(newarray), ArErr{}
case ArObject:
@@ -139,7 +128,7 @@ func init() {
return nil, ArErr{TYPE: "TypeError", message: "Cannot ceil '" + typeof(a[0]) + "'", EXISTS: true}
}}
vars.obj["sqrt"] = builtinFunc{"sqrt", ArgonSqrt}
vars.obj["file"] = ArFile
vars.obj["open"] = builtinFunc{"open", ArOpen}
vars.obj["random"] = ArRandom
vars.obj["json"] = ArJSON
vars.obj["sin"] = ArSin

View File

@@ -92,7 +92,11 @@ func runCall(c call, stack stack, stacklevel int) (any, ArErr) {
}
switch x := callable.(type) {
case builtinFunc:
for i := range args {
args[i] = ArValidToAny(args[i])
}
resp, err := x.FUNC(args...)
resp = AnyToArValid(resp)
if err.EXISTS {
if err.line == 0 {
err.line = c.line

View File

@@ -21,7 +21,10 @@ func parseComment(code UNPARSEcode, index int, codelines []UNPARSEcode) (any, bo
for i := 0; i < len(split)-1; i++ {
temp = append(temp, split[i])
joined := strings.Join(temp, "#")
resp, worked, _, s := translateVal(UNPARSEcode{code: joined, realcode: code.realcode, line: code.line, path: code.path}, index, codelines, 0)
if isBlank(UNPARSEcode{code: joined, realcode: code.realcode, line: code.line, path: code.path}) {
return nil, true, ArErr{}, step
}
resp, worked, _, s := translateVal(UNPARSEcode{code: joined, realcode: code.realcode, line: code.line, path: code.path}, index, codelines, 2)
step += s - 1
if worked {
return resp, true, ArErr{}, step

View File

@@ -7,10 +7,87 @@ import (
"os"
)
var ArFile = Map(anymap{
"read": builtinFunc{"read", ArRead},
"write": builtinFunc{"write", ArWrite},
})
func ArOpen(args ...any) (any, ArErr) {
if len(args) > 2 {
return ArObject{}, ArErr{TYPE: "Runtime Error", message: "open takes 1 or 2 argument, got " + fmt.Sprint(len(args)), EXISTS: true}
}
if typeof(args[0]) != "string" {
return ArObject{}, ArErr{TYPE: "Runtime Error", message: "open takes a string not type '" + typeof(args[0]) + "'", EXISTS: true}
}
path := args[0].(string)
mode := "r"
if len(args) == 2 {
if typeof(args[1]) != "string" {
return ArObject{}, ArErr{TYPE: "Runtime Error", message: "open takes a string not type '" + typeof(args[1]) + "'", EXISTS: true}
}
mode = args[1].(string)
}
if mode != "r" && mode != "w" {
return ArObject{}, ArErr{TYPE: "Runtime Error", message: "open mode must be 'r', or 'w'", EXISTS: true}
}
if mode == "r" {
file, err := os.Open(path)
if err != nil {
return ArObject{}, ArErr{TYPE: "Runtime Error", message: err.Error(), EXISTS: true}
}
return Map(anymap{
"text": builtinFunc{"text", func(...any) (any, ArErr) {
text, err := readtext(file)
if err != nil {
return ArObject{}, ArErr{TYPE: "Runtime Error", message: err.Error(), EXISTS: true}
}
return ArString(text), ArErr{}
},
},
"json": builtinFunc{"json", func(...any) (any, ArErr) {
text, err := readtext(file)
if err != nil {
return ArObject{}, ArErr{TYPE: "Runtime Error", message: err.Error(), EXISTS: true}
}
return jsonparse(text), ArErr{}
},
},
}), ArErr{}
}
file, err := os.Create(path)
if err != nil {
return ArObject{}, ArErr{TYPE: "Runtime Error", message: err.Error(), EXISTS: true}
}
return Map(anymap{
"text": builtinFunc{"text", func(args ...any) (any, ArErr) {
if len(args) != 1 {
return ArObject{}, ArErr{TYPE: "Runtime Error", message: "text takes 1 argument, got " + fmt.Sprint(len(args)), EXISTS: true}
}
if typeof(args[0]) != "string" {
return ArObject{}, ArErr{TYPE: "Runtime Error", message: "text takes a string not type '" + typeof(args[0]) + "'", EXISTS: true}
}
file.Write([]byte(args[0].(string)))
return nil, ArErr{}
}},
"json": builtinFunc{"json", func(args ...any) (any, ArErr) {
if len(args) != 1 {
return ArObject{}, ArErr{TYPE: "Runtime Error", message: "json takes 1 argument, got " + fmt.Sprint(len(args)), EXISTS: true}
}
jsonstr, err := jsonstringify(args[0], 0)
if err != nil {
return ArObject{}, ArErr{TYPE: "Runtime Error", message: err.Error(), EXISTS: true}
}
file.Write([]byte(jsonstr))
return nil, ArErr{}
}},
"append": builtinFunc{"append", func(args ...any) (any, ArErr) {
if len(args) != 1 {
return ArObject{}, ArErr{TYPE: "Runtime Error", message: "append takes 1 argument, got " + fmt.Sprint(len(args)), EXISTS: true}
}
if typeof(args[0]) != "string" {
return ArObject{}, ArErr{TYPE: "Runtime Error", message: "append takes a string not type '" + typeof(args[0]) + "'", EXISTS: true}
}
file.Write([]byte(args[0].(string)))
return nil, ArErr{}
}},
}), ArErr{}
}
func readtext(file *os.File) (string, error) {
var buf bytes.Buffer
@@ -39,7 +116,7 @@ func ArRead(args ...any) (any, ArErr) {
if err != nil {
return ArObject{}, ArErr{TYPE: "Runtime Error", message: err.Error(), EXISTS: true}
}
return text, ArErr{}
return ArString(text), ArErr{}
}},
"json": builtinFunc{"json", func(...any) (any, ArErr) {
text, err := readtext(file)

View File

@@ -37,6 +37,11 @@ func mapGet(r ArMapGet, stack stack, stacklevel int) (any, ArErr) {
if !err.EXISTS {
return resp, err
}
case "string":
resp, err := getFromString(m.obj["__value__"].(string), r, stack, stacklevel+1)
if !err.EXISTS {
return ArString(resp), err
}
}
if len(r.args) > 1 {
return nil, ArErr{
@@ -52,6 +57,7 @@ func mapGet(r ArMapGet, stack stack, stacklevel int) (any, ArErr) {
if err.EXISTS {
return nil, err
}
key = ArValidToAny(key)
if isUnhashable(key) {
return nil, ArErr{
"TypeError",
@@ -72,15 +78,7 @@ func mapGet(r ArMapGet, stack stack, stacklevel int) (any, ArErr) {
true,
}
}
return potentialAnyArrayToArArray(m.obj[key]), ArErr{}
case string:
if val, ok := r.args[0].(string); !r.index && ok {
switch val {
case "length":
return len(m), ArErr{}
}
}
return getFromString(m, r, stack, stacklevel+1)
return AnyToArValid(m.obj[key]), ArErr{}
}
key, err := runVal(r.args[0], stack, stacklevel+1)
@@ -97,15 +95,6 @@ func mapGet(r ArMapGet, stack stack, stacklevel int) (any, ArErr) {
}
}
func classVal(r any) any {
if j, ok := r.(ArObject); ok {
if _, ok := j.obj["__value__"]; ok {
return j.obj["__value__"]
}
}
return r
}
func isMapGet(code UNPARSEcode) bool {
return mapGetCompile.MatchString(code.code)
}
@@ -174,7 +163,7 @@ func isUnhashable(val any) bool {
return keytype == "array" || keytype == "map"
}
func getFromArArray(m ArObject, r ArMapGet, stack stack, stacklevel int) (ArObject, ArErr) {
func getFromArArray(m ArObject, r ArMapGet, stack stack, stacklevel int) (any, ArErr) {
var (
start int = 0
end any = nil
@@ -247,7 +236,7 @@ func getFromArArray(m ArObject, r ArMapGet, stack stack, stacklevel int) (ArObje
end = m.obj["length"].(int) + end.(int)
}
if end == nil {
return ArArray([]any{m.obj["__value__"].([]any)[start]}), ArErr{}
return m.obj["__value__"].([]any)[start], ArErr{}
} else if step == 1 {
return ArArray([]any{m.obj["__value__"].([]any)[start:end.(int)]}), ArErr{}
} else {

View File

@@ -4,6 +4,8 @@ import (
"bufio"
"fmt"
"os"
"golang.org/x/term"
)
func input(args ...any) string {
@@ -17,3 +19,42 @@ func input(args ...any) string {
input := scanner.Text()
return input
}
func getPassword(args ...any) (string, error) {
output := []any{}
for i := 0; i < len(args); i++ {
output = append(output, anyToArgon(args[i], false, true, 3, 0, true, 0))
}
fmt.Print(output...)
password := []byte{}
oldState, err := term.MakeRaw(int(os.Stdin.Fd()))
if err != nil {
panic(err)
}
defer term.Restore(int(os.Stdin.Fd()), oldState)
for {
char := make([]byte, 1)
_, err := os.Stdin.Read(char)
if err != nil {
fmt.Println(err)
break
}
if char[0] == 3 || char[0] == 4 {
return "", fmt.Errorf("User cancelled")
} else if char[0] == '\r' || char[0] == '\n' {
fmt.Println()
break
} else if char[0] == '\b' {
if len(password) > 0 {
password = password[:len(password)-1]
fmt.Print("\b \b")
}
} else {
password = append(password, char[0])
fmt.Print("*")
}
}
return string(password), nil
}

View File

@@ -11,12 +11,15 @@ import (
func convertToArgon(obj any) any {
switch x := obj.(type) {
case map[string]interface{}:
newmap := Map(anymap{})
newmap := anymap{}
for key, value := range x {
newmap.obj[key] = convertToArgon(value)
newmap[key] = convertToArgon(value)
}
return newmap
return Map(newmap)
case []any:
for i, value := range x {
x[i] = convertToArgon(value)
}
return ArArray(x)
case string:
return x
@@ -41,19 +44,9 @@ func jsonstringify(obj any, level int) (string, error) {
return "", errors.New("json stringify error: too many levels")
}
output := []string{}
obj = classVal(obj)
obj = ArValidToAny(obj)
switch x := obj.(type) {
case ArObject:
if x.TYPE == "array" {
for _, value := range x.obj["__value__"].([]any) {
str, err := jsonstringify(value, level+1)
if err != nil {
return "", err
}
output = append(output, str)
}
return "[" + strings.Join(output, ", ") + "]", nil
}
for key, value := range x.obj {
str, err := jsonstringify(value, level+1)
if err != nil {

View File

@@ -5,7 +5,7 @@ import (
"math"
)
var N = newNumber().SetInt64(1e10)
var N = newNumber().SetInt64(1e6)
func Ln(x number) number {
output := newNumber()

View File

@@ -1,8 +1,33 @@
package main
import (
"fmt"
"strings"
)
var mapCompiled = makeRegex(`( *)\{(((( *).+( *):( *).+( *))|(` + spacelessVariable + `))(( *)\,(( *).+( *):( *).+( *))|(` + spacelessVariable + `)))*\}( *)`)
func isMap(code UNPARSEcode) bool {
return mapCompiled.MatchString(code.code)
}
func parseMap(code UNPARSEcode) (any, UNPARSEcode) {
trimmed := strings.Trim(code.code, " ")
trimmed = trimmed[1 : len(trimmed)-1]
fmt.Println(trimmed)
return nil, UNPARSEcode{}
}
func Map(val anymap) ArObject {
return ArObject{
TYPE: "map",
obj: val,
}
}
func Class(val anymap) ArObject {
return ArObject{
TYPE: "class",
obj: val,
}
}

View File

@@ -121,7 +121,7 @@ func compareValues(o operationType, stack stack, stacklevel int) (bool, ArErr) {
stack,
stacklevel+1,
)
resp = classVal(resp)
resp = ArValidToAny(resp)
if err.EXISTS {
return false, err
}
@@ -131,7 +131,7 @@ func compareValues(o operationType, stack stack, stacklevel int) (bool, ArErr) {
stack,
stacklevel+1,
)
resp2 = classVal(resp2)
resp2 = ArValidToAny(resp2)
if err.EXISTS {
return false, err
}
@@ -207,7 +207,7 @@ func calcNegative(o operationType, stack stack, stacklevel int) (number, ArErr)
stack,
stacklevel+1,
)
resp = classVal(resp)
resp = ArValidToAny(resp)
if err.EXISTS {
return nil, err
}
@@ -228,7 +228,7 @@ func calcNegative(o operationType, stack stack, stacklevel int) (number, ArErr)
stack,
stacklevel+1,
)
resp = classVal(resp)
resp = ArValidToAny(resp)
if err.EXISTS {
return nil, err
}
@@ -255,7 +255,7 @@ func calcDivide(o operationType, stack stack, stacklevel int) (number, ArErr) {
stack,
stacklevel+1,
)
resp = classVal(resp)
resp = ArValidToAny(resp)
if err.EXISTS {
return nil, err
}
@@ -276,7 +276,7 @@ func calcDivide(o operationType, stack stack, stacklevel int) (number, ArErr) {
stack,
stacklevel+1,
)
resp = classVal(resp)
resp = ArValidToAny(resp)
if err.EXISTS {
return nil, err
}
@@ -303,7 +303,7 @@ func calcAdd(o operationType, stack stack, stacklevel int) (any, ArErr) {
stack,
stacklevel+1,
)
resp = classVal(resp)
resp = ArValidToAny(resp)
if err.EXISTS {
return nil, err
}
@@ -319,7 +319,7 @@ func calcAdd(o operationType, stack stack, stacklevel int) (any, ArErr) {
stack,
stacklevel+1,
)
resp = classVal(resp)
resp = ArValidToAny(resp)
if err.EXISTS {
return nil, err
}
@@ -333,7 +333,7 @@ func calcAdd(o operationType, stack stack, stacklevel int) (any, ArErr) {
}
}
return output, ArErr{}
return AnyToArValid(output), ArErr{}
}
func calcMul(o operationType, stack stack, stacklevel int) (any, ArErr) {
@@ -343,7 +343,7 @@ func calcMul(o operationType, stack stack, stacklevel int) (any, ArErr) {
stack,
stacklevel+1,
)
resp = classVal(resp)
resp = ArValidToAny(resp)
if err.EXISTS {
return nil, err
}
@@ -359,7 +359,7 @@ func calcMul(o operationType, stack stack, stacklevel int) (any, ArErr) {
stack,
stacklevel+1,
)
resp = classVal(resp)
resp = ArValidToAny(resp)
if err.EXISTS {
return nil, err
}
@@ -393,7 +393,7 @@ func calcAnd(o operationType, stack stack, stacklevel int) (any, ArErr) {
stack,
stacklevel+1,
)
resp = classVal(resp)
resp = ArValidToAny(resp)
if err.EXISTS {
return nil, err
}
@@ -413,7 +413,7 @@ func calcOr(o operationType, stack stack, stacklevel int) (any, ArErr) {
stack,
stacklevel+1,
)
resp = classVal(resp)
resp = ArValidToAny(resp)
if err.EXISTS {
return nil, err
}
@@ -450,7 +450,7 @@ func calcIn(o operationType, stack stack, stacklevel int) (bool, ArErr) {
stack,
stacklevel+1,
)
resp = classVal(resp)
resp = ArValidToAny(resp)
if err.EXISTS {
return false, err
}
@@ -460,7 +460,7 @@ func calcIn(o operationType, stack stack, stacklevel int) (bool, ArErr) {
stack,
stacklevel+1,
)
resp2 = classVal(resp2)
resp2 = ArValidToAny(resp2)
if err.EXISTS {
return false, err
}
@@ -501,7 +501,7 @@ func calcMod(o operationType, stack stack, stacklevel int) (number, ArErr) {
stack,
stacklevel+1,
)
resp = classVal(resp)
resp = ArValidToAny(resp)
if err.EXISTS {
return nil, err
}
@@ -522,7 +522,7 @@ func calcMod(o operationType, stack stack, stacklevel int) (number, ArErr) {
stack,
stacklevel+1,
)
resp = classVal(resp)
resp = ArValidToAny(resp)
if err.EXISTS {
return nil, err
}
@@ -557,7 +557,7 @@ func calcPower(o operationType, stack stack, stacklevel int) (number, ArErr) {
stack,
stacklevel+1,
)
resp = classVal(resp)
resp = ArValidToAny(resp)
if err.EXISTS {
return nil, err
}
@@ -578,7 +578,7 @@ func calcPower(o operationType, stack stack, stacklevel int) (number, ArErr) {
stack,
stacklevel+1,
)
resp = classVal(resp)
resp = ArValidToAny(resp)
if err.EXISTS {
return nil, err
}

View File

@@ -17,7 +17,7 @@ func runVal(line any, stack stack, stacklevel int) (any, ArErr) {
case number:
return x, ArErr{}
case string:
return x, ArErr{}
return ArString(x), ArErr{}
case call:
if stackoverflow {
linenum = x.line
@@ -66,7 +66,7 @@ func runVal(line any, stack stack, stacklevel int) (any, ArErr) {
break
}
resp, err := runVal(x.VAL, stack, stacklevel+1)
resp = classVal(resp)
resp = AnyToArValid(resp)
if err.EXISTS {
return nil, err
}

86
src/sortany.go Normal file
View File

@@ -0,0 +1,86 @@
package main
import "fmt"
type keyCache map[interface{}]interface{}
func quickSort(list []interface{}, getKey func(interface{}) (interface{}, ArErr)) ([]interface{}, ArErr) {
if len(list) <= 1 {
return list, ArErr{}
}
pivot := list[0]
var left []interface{}
var right []interface{}
var cache = make(keyCache)
for _, v := range list[1:] {
val, err := getkeyCache(getKey, v, cache)
if err.EXISTS {
return nil, err
}
pivotval, err := getkeyCache(getKey, pivot, cache)
if err.EXISTS {
return nil, err
}
comp, comperr := compare(val, pivotval)
if comperr != nil {
return nil, ArErr{
TYPE: "TypeError",
message: comperr.Error(),
EXISTS: true,
}
}
if comp < 0 {
left = append(left, v)
} else {
right = append(right, v)
}
}
left, err := quickSort(left, getKey)
if err.EXISTS {
return nil, err
}
right, err = quickSort(right, getKey)
if err.EXISTS {
return nil, err
}
return append(append(left, pivot), right...), ArErr{}
}
func getkeyCache(getKey func(interface{}) (interface{}, ArErr), index interface{}, cache keyCache) (interface{}, ArErr) {
if cacheval, ok := cache[index]; ok {
return cacheval, ArErr{}
}
val, err := getKey(index)
if err.EXISTS {
return nil, err
}
cache[index] = 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)
}
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)
}

View File

@@ -41,3 +41,32 @@ func parseString(code UNPARSEcode) (string, bool, ArErr, int) {
return unquoted, true, ArErr{}, 1
}
func ArString(str string) ArObject {
obj := ArObject{
"string",
anymap{
"__value__": str,
"length": newNumber().SetUint64(uint64(len(str))),
},
}
obj.obj["append"] = builtinFunc{
"append",
func(a ...any) (any, ArErr) {
if len(a) == 0 {
return nil, ArErr{"TypeError", "expected 1 or more argument, got 0", 0, "", "", true}
}
output := []string{str}
for _, v := range a {
if typeof(v) != "string" {
return nil, ArErr{"TypeError", "expected string, got " + typeof(v), 0, "", "", true}
}
output = append(output, v.(string))
}
str = strings.Join(output, "")
obj.obj["__value__"] = str
obj.obj["length"] = newNumber().SetUint64(uint64(len(str)))
return nil, ArErr{}
}}
return obj
}

View File

@@ -7,7 +7,7 @@ import (
var MicroSeconds = newNumber().SetInt64(1000000)
func ArTimeClass(N time.Time) ArObject {
return Map(anymap{
return Class(anymap{
"__value__": newNumber().Quo(newNumber().SetInt64(N.UnixMicro()), MicroSeconds),
"year": builtinFunc{
"year",

View File

@@ -11,6 +11,7 @@ import (
)
func anyToArgon(x any, quote bool, simplify bool, depth int, indent int, colored bool, plain int) string {
x = ArValidToAny(x)
output := []string{}
maybenewline := ""
if plain == 1 {
@@ -72,17 +73,14 @@ func anyToArgon(x any, quote bool, simplify bool, depth int, indent int, colored
if colored {
output = append(output, "\x1b[0m")
}
case ArObject:
if x.TYPE == "array" {
return anyToArgon(x.obj["__value__"], quote, simplify, depth, indent, colored, plain)
}
if len(x.obj) == 0 {
case anymap:
if len(x) == 0 {
return "{}"
}
keys := make([]any, len(x.obj))
keys := make([]any, len(x))
i := 0
for k := range x.obj {
for k := range x {
keys[i] = k
i++
}
@@ -103,7 +101,7 @@ func anyToArgon(x any, quote bool, simplify bool, depth int, indent int, colored
}
keyval = strings.Join(outputkeyval, "")
}
output = append(output, keyval+": "+anyToArgon(x.obj[key], true, true, depth-1, indent+1, colored, plain))
output = append(output, keyval+": "+anyToArgon(x[key], true, true, depth-1, indent+1, colored, plain))
}
return "{" + maybenewline + (strings.Repeat(" ", (indent+1)*plain)) + strings.Join(output, ","+maybenewline+(strings.Repeat(" ", (indent+1)*plain))) + maybenewline + (strings.Repeat(" ", indent*plain)) + "}"
case []any:

View File

@@ -1,23 +1,22 @@
package main
func typeof(val any) string {
switch x := val.(type) {
switch val.(type) {
case number:
return "number"
case string:
return "string"
case nil:
return "null"
case bool:
return "boolean"
case string:
return "string"
case anymap:
return "array"
case Callable:
return "function"
case builtinFunc:
return "function"
case ArObject:
if x.TYPE == "array" {
return "array"
}
return "map"
case accessVariable:
return "variable"

View File

@@ -5,7 +5,8 @@ import (
"sync"
)
var SpacelessVariableCompiled = makeRegex(`([a-zA-Z_]|(\p{L}\p{M}*))([a-zA-Z0-9_]|(\p{L}\p{M}*))*`)
var spacelessVariable = `([a-zA-Z_]|(\p{L}\p{M}*))([a-zA-Z0-9_]|(\p{L}\p{M}*))*`
var SpacelessVariableCompiled = makeRegex(spacelessVariable)
var variableCompile = makeRegex(`( *)([a-zA-Z_]|(\p{L}\p{M}*))([a-zA-Z0-9_]|(\p{L}\p{M}*))*( *)`)
var validname = makeRegex(`(.|\n)*(\(( *)((([a-zA-Z_]|(\p{L}\p{M}*))([a-zA-Z0-9_]|(\p{L}\p{M}*))*)(( *)\,( *)([a-zA-Z_]|(\p{L}\p{M}*))([a-zA-Z0-9_]|(\p{L}\p{M}*))*)*)?( *)\))`)
var setVariableCompile = makeRegex(`( *)(let( +))(.|\n)+( *)=(.|\n)+`)
@@ -242,6 +243,7 @@ func setVariableValue(v setVariable, stack stack, stacklevel int) (any, ArErr) {
return nil, ArErr{"Runtime Error", "cannot set by slice", v.line, v.path, v.code, true}
}
key, err := runVal(x.args[0], stack, stacklevel+1)
key = ArValidToAny(key)
if err.EXISTS {
return nil, err
}