mirror of
https://github.com/Open-Argon/argon-v3.git
synced 2025-12-06 08:56:07 +00:00
fix infinity in json stringify
This commit is contained in:
@@ -1,4 +0,0 @@
|
|||||||
cool_function() = do
|
|
||||||
term.log("this is a cool function")
|
|
||||||
time.snooze(1)
|
|
||||||
term.log("wow what a cool function")
|
|
||||||
@@ -1,3 +1,8 @@
|
|||||||
import "cool_module" as cool
|
i = 0
|
||||||
|
output = []
|
||||||
|
|
||||||
cool.cool_function()
|
while (i < 1000) do
|
||||||
|
output = append(output, i)
|
||||||
|
i = i + 1
|
||||||
|
|
||||||
|
file.write('output.json').json(output)
|
||||||
@@ -42,9 +42,8 @@ func init() {
|
|||||||
switch y := v.(type) {
|
switch y := v.(type) {
|
||||||
case ArArray:
|
case ArArray:
|
||||||
if len(y) == 2 {
|
if len(y) == 2 {
|
||||||
keytype := typeof(y[0])
|
if isUnhashable(y[0]) {
|
||||||
if keytype == "array" || keytype == "map" {
|
return nil, ArErr{TYPE: "TypeError", message: "Cannot use unhashable value as key: " + typeof(y[0]), EXISTS: true}
|
||||||
return nil, ArErr{TYPE: "TypeError", message: "Cannot use unhashable value as key: " + keytype, EXISTS: true}
|
|
||||||
}
|
}
|
||||||
newmap[y[0]] = y[1]
|
newmap[y[0]] = y[1]
|
||||||
continue
|
continue
|
||||||
|
|||||||
@@ -106,7 +106,7 @@ func runCall(c call, stack stack, stacklevel int) (any, ArErr) {
|
|||||||
level[param] = args[i]
|
level[param] = args[i]
|
||||||
}
|
}
|
||||||
resp, err := runVal(x.run, append(x.stack, level), stacklevel+1)
|
resp, err := runVal(x.run, append(x.stack, level), stacklevel+1)
|
||||||
return openReturn(resp), err
|
return ThrowOnNonLoop(openReturn(resp), err)
|
||||||
}
|
}
|
||||||
return nil, ArErr{"Runtime Error", "type '" + typeof(callable) + "' is not callable", c.line, c.path, c.code, true}
|
return nil, ArErr{"Runtime Error", "type '" + typeof(callable) + "' is not callable", c.line, c.path, c.code, true}
|
||||||
}
|
}
|
||||||
|
|||||||
54
src/file.go
54
src/file.go
@@ -2,12 +2,14 @@ package main
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"os"
|
"os"
|
||||||
)
|
)
|
||||||
|
|
||||||
var ArFile = ArMap{
|
var ArFile = ArMap{
|
||||||
"read": builtinFunc{"read", ArRead},
|
"read": builtinFunc{"read", ArRead},
|
||||||
|
"write": builtinFunc{"write", ArWrite},
|
||||||
}
|
}
|
||||||
|
|
||||||
func readtext(file *os.File) (string, error) {
|
func readtext(file *os.File) (string, error) {
|
||||||
@@ -16,15 +18,15 @@ func readtext(file *os.File) (string, error) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
return string(buf.Bytes()), nil
|
return buf.String(), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func ArRead(args ...any) (any, ArErr) {
|
func ArRead(args ...any) (any, ArErr) {
|
||||||
if len(args) == 0 {
|
if len(args) != 1 {
|
||||||
return ArMap{}, ArErr{TYPE: "Runtime Error", message: "open takes 1 argument", EXISTS: true}
|
return ArMap{}, ArErr{TYPE: "Runtime Error", message: "read takes 1 argument, got " + fmt.Sprint(len(args)), EXISTS: true}
|
||||||
}
|
}
|
||||||
if typeof(args[0]) != "string" {
|
if typeof(args[0]) != "string" {
|
||||||
return ArMap{}, ArErr{TYPE: "Runtime Error", message: "open takes a string not a '" + typeof(args[0]) + "'", EXISTS: true}
|
return ArMap{}, ArErr{TYPE: "Runtime Error", message: "read takes a string not type '" + typeof(args[0]) + "'", EXISTS: true}
|
||||||
}
|
}
|
||||||
filename := args[0].(string)
|
filename := args[0].(string)
|
||||||
file, err := os.Open(filename)
|
file, err := os.Open(filename)
|
||||||
@@ -44,11 +46,45 @@ func ArRead(args ...any) (any, ArErr) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return ArMap{}, ArErr{TYPE: "Runtime Error", message: err.Error(), EXISTS: true}
|
return ArMap{}, ArErr{TYPE: "Runtime Error", message: err.Error(), EXISTS: true}
|
||||||
}
|
}
|
||||||
return parse(text), ArErr{}
|
return jsonparse(text), ArErr{}
|
||||||
}},
|
|
||||||
"line": builtinFunc{"line", func(...any) (any, ArErr) {
|
|
||||||
|
|
||||||
return "", ArErr{}
|
|
||||||
}},
|
}},
|
||||||
}, ArErr{}
|
}, ArErr{}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func ArWrite(args ...any) (any, ArErr) {
|
||||||
|
if len(args) != 1 {
|
||||||
|
return ArMap{}, ArErr{TYPE: "Runtime Error", message: "write takes 1 argument, got " + fmt.Sprint(len(args)), EXISTS: true}
|
||||||
|
}
|
||||||
|
if typeof(args[0]) != "string" {
|
||||||
|
return ArMap{}, ArErr{TYPE: "Runtime Error", message: "write takes a string not type '" + typeof(args[0]) + "'", EXISTS: true}
|
||||||
|
}
|
||||||
|
filename := args[0].(string)
|
||||||
|
file, err := os.Create(filename)
|
||||||
|
if err != nil {
|
||||||
|
return ArMap{}, ArErr{TYPE: "Runtime Error", message: err.Error(), EXISTS: true}
|
||||||
|
}
|
||||||
|
return ArMap{
|
||||||
|
"text": builtinFunc{"text", func(args ...any) (any, ArErr) {
|
||||||
|
if len(args) != 1 {
|
||||||
|
return ArMap{}, ArErr{TYPE: "Runtime Error", message: "text takes 1 argument, got " + fmt.Sprint(len(args)), EXISTS: true}
|
||||||
|
}
|
||||||
|
if typeof(args[0]) != "string" {
|
||||||
|
return ArMap{}, 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 ArMap{}, 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 ArMap{}, ArErr{TYPE: "Runtime Error", message: err.Error(), EXISTS: true}
|
||||||
|
}
|
||||||
|
file.Write([]byte(jsonstr))
|
||||||
|
return nil, ArErr{}
|
||||||
|
}},
|
||||||
|
}, ArErr{}
|
||||||
|
|
||||||
|
}
|
||||||
|
|||||||
561
src/getIndex.go
561
src/getIndex.go
@@ -13,11 +13,8 @@ var indexGetCompile = makeRegex(`(.|\n)+\[(.|\n)+\]( *)`)
|
|||||||
|
|
||||||
type ArMapGet struct {
|
type ArMapGet struct {
|
||||||
VAL any
|
VAL any
|
||||||
start any
|
args ArArray
|
||||||
end any
|
|
||||||
step any
|
|
||||||
index bool
|
index bool
|
||||||
numberofindex int
|
|
||||||
line int
|
line int
|
||||||
code string
|
code string
|
||||||
path string
|
path string
|
||||||
@@ -30,7 +27,7 @@ func mapGet(r ArMapGet, stack stack, stacklevel int) (any, ArErr) {
|
|||||||
}
|
}
|
||||||
switch m := resp.(type) {
|
switch m := resp.(type) {
|
||||||
case ArMap:
|
case ArMap:
|
||||||
if r.numberofindex > 1 {
|
if len(r.args) > 1 {
|
||||||
return nil, ArErr{
|
return nil, ArErr{
|
||||||
"IndexError",
|
"IndexError",
|
||||||
"index not found",
|
"index not found",
|
||||||
@@ -40,10 +37,20 @@ func mapGet(r ArMapGet, stack stack, stacklevel int) (any, ArErr) {
|
|||||||
true,
|
true,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
key, err := runVal(r.start, stack, stacklevel+1)
|
key, err := runVal(r.args[0], stack, stacklevel+1)
|
||||||
if err.EXISTS {
|
if err.EXISTS {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
if isUnhashable(key) {
|
||||||
|
return nil, ArErr{
|
||||||
|
"TypeError",
|
||||||
|
"unhashable type: '" + typeof(key) + "'",
|
||||||
|
r.line,
|
||||||
|
r.path,
|
||||||
|
r.code,
|
||||||
|
true,
|
||||||
|
}
|
||||||
|
}
|
||||||
if _, ok := m[key]; !ok {
|
if _, ok := m[key]; !ok {
|
||||||
return nil, ArErr{
|
return nil, ArErr{
|
||||||
"KeyError",
|
"KeyError",
|
||||||
@@ -57,335 +64,12 @@ func mapGet(r ArMapGet, stack stack, stacklevel int) (any, ArErr) {
|
|||||||
return m[key], ArErr{}
|
return m[key], ArErr{}
|
||||||
|
|
||||||
case ArArray:
|
case ArArray:
|
||||||
startindex := 0
|
return getFromArArray(m, r, stack, stacklevel)
|
||||||
endindex := 1
|
|
||||||
step := 1
|
|
||||||
slice := false
|
|
||||||
|
|
||||||
if !r.index {
|
|
||||||
key, err := runVal(r.start, stack, stacklevel+1)
|
|
||||||
if err.EXISTS {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
switch key {
|
|
||||||
case "length":
|
|
||||||
return newNumber().SetInt64(int64(len(m))), ArErr{}
|
|
||||||
}
|
|
||||||
return nil, ArErr{
|
|
||||||
"IndexError",
|
|
||||||
"" + anyToArgon(key, true, true, 3, 0, false, 0) + " does not exist in array",
|
|
||||||
r.line,
|
|
||||||
r.path,
|
|
||||||
r.code,
|
|
||||||
true,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if r.start != nil {
|
|
||||||
sindex, err := runVal(r.start, stack, stacklevel+1)
|
|
||||||
if err.EXISTS {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
if typeof(sindex) != "number" {
|
|
||||||
return nil, ArErr{
|
|
||||||
"TypeError",
|
|
||||||
"index must be a number",
|
|
||||||
r.line,
|
|
||||||
r.path,
|
|
||||||
r.code,
|
|
||||||
true,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
num := sindex.(number)
|
|
||||||
if !num.IsInt() {
|
|
||||||
return nil, ArErr{
|
|
||||||
"TypeError",
|
|
||||||
"index must be an integer",
|
|
||||||
r.line,
|
|
||||||
r.path,
|
|
||||||
r.code,
|
|
||||||
true,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
startindex = int(num.Num().Int64())
|
|
||||||
endindex = startindex + 1
|
|
||||||
}
|
|
||||||
if r.end != nil {
|
|
||||||
eindex, err := runVal(r.end, stack, stacklevel+1)
|
|
||||||
if err.EXISTS {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
if typeof(eindex) != "number" {
|
|
||||||
return nil, ArErr{
|
|
||||||
"TypeError",
|
|
||||||
"ending index must be a number",
|
|
||||||
r.line,
|
|
||||||
r.path,
|
|
||||||
r.code,
|
|
||||||
true,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
slice = true
|
|
||||||
num := eindex.(number)
|
|
||||||
if !num.IsInt() {
|
|
||||||
return nil, ArErr{
|
|
||||||
"TypeError",
|
|
||||||
"ending index must be an integer",
|
|
||||||
r.line,
|
|
||||||
r.path,
|
|
||||||
r.code,
|
|
||||||
true,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
endindex = int(num.Num().Int64())
|
|
||||||
} else if r.numberofindex > 1 {
|
|
||||||
endindex = len(m)
|
|
||||||
}
|
|
||||||
if r.step != nil {
|
|
||||||
step, err := runVal(r.step, stack, stacklevel+1)
|
|
||||||
if err.EXISTS {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
if typeof(step) != "number" {
|
|
||||||
return nil, ArErr{
|
|
||||||
"TypeError",
|
|
||||||
"step must be a number",
|
|
||||||
r.line,
|
|
||||||
r.path,
|
|
||||||
r.code,
|
|
||||||
true,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
slice = true
|
|
||||||
num := step.(number)
|
|
||||||
if !num.IsInt() {
|
|
||||||
return nil, ArErr{
|
|
||||||
"TypeError",
|
|
||||||
"step must be an integer",
|
|
||||||
r.line,
|
|
||||||
r.path,
|
|
||||||
r.code,
|
|
||||||
true,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
step = int(num.Num().Int64())
|
|
||||||
}
|
|
||||||
if startindex < 0 {
|
|
||||||
startindex = len(m) + startindex
|
|
||||||
}
|
|
||||||
if endindex < 0 {
|
|
||||||
endindex = len(m) + endindex
|
|
||||||
}
|
|
||||||
if step < 0 {
|
|
||||||
step = -step
|
|
||||||
startindex, endindex = endindex, startindex
|
|
||||||
}
|
|
||||||
if startindex < 0 || startindex >= len(m) {
|
|
||||||
return nil, ArErr{
|
|
||||||
"IndexError",
|
|
||||||
"index '" + fmt.Sprint(startindex) + "' out of range",
|
|
||||||
r.line,
|
|
||||||
r.path,
|
|
||||||
r.code,
|
|
||||||
true,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if endindex < 0 || endindex > len(m) {
|
|
||||||
return nil, ArErr{
|
|
||||||
"IndexError",
|
|
||||||
"index '" + fmt.Sprint(endindex) + "' out of range",
|
|
||||||
r.line,
|
|
||||||
r.path,
|
|
||||||
r.code,
|
|
||||||
true,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if step == 0 {
|
|
||||||
return nil, ArErr{
|
|
||||||
"ValueError",
|
|
||||||
"step cannot be 0",
|
|
||||||
r.line,
|
|
||||||
r.path,
|
|
||||||
r.code,
|
|
||||||
true,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if !slice {
|
|
||||||
return m[startindex], ArErr{}
|
|
||||||
} else if step == 1 {
|
|
||||||
return m[startindex:endindex], ArErr{}
|
|
||||||
}
|
|
||||||
output := ArArray{}
|
|
||||||
for i := startindex; i < endindex; i += step {
|
|
||||||
output = append(output, output[i])
|
|
||||||
}
|
|
||||||
return output, ArErr{}
|
|
||||||
case string:
|
case string:
|
||||||
startindex := 0
|
return getFromString(m, r, stack, stacklevel)
|
||||||
endindex := 1
|
|
||||||
step := 1
|
|
||||||
slice := false
|
|
||||||
|
|
||||||
if !r.index {
|
|
||||||
key, err := runVal(r.start, stack, stacklevel+1)
|
|
||||||
if err.EXISTS {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
switch key {
|
|
||||||
case "length":
|
|
||||||
return newNumber().SetInt64(int64(len(m))), ArErr{}
|
|
||||||
}
|
|
||||||
return nil, ArErr{
|
|
||||||
"IndexError",
|
|
||||||
"" + anyToArgon(key, true, true, 3, 0, false, 0) + " does not exist in array",
|
|
||||||
r.line,
|
|
||||||
r.path,
|
|
||||||
r.code,
|
|
||||||
true,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if r.start != nil {
|
|
||||||
sindex, err := runVal(r.start, stack, stacklevel+1)
|
|
||||||
if err.EXISTS {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
if typeof(sindex) != "number" {
|
|
||||||
return nil, ArErr{
|
|
||||||
"TypeError",
|
|
||||||
"index must be a number",
|
|
||||||
r.line,
|
|
||||||
r.path,
|
|
||||||
r.code,
|
|
||||||
true,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
num := sindex.(number)
|
|
||||||
if !num.IsInt() {
|
|
||||||
return nil, ArErr{
|
|
||||||
"TypeError",
|
|
||||||
"index must be an integer",
|
|
||||||
r.line,
|
|
||||||
r.path,
|
|
||||||
r.code,
|
|
||||||
true,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
startindex = int(num.Num().Int64())
|
|
||||||
endindex = startindex + 1
|
|
||||||
}
|
|
||||||
if r.end != nil {
|
|
||||||
eindex, err := runVal(r.end, stack, stacklevel+1)
|
|
||||||
if err.EXISTS {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
if typeof(eindex) != "number" {
|
|
||||||
return nil, ArErr{
|
|
||||||
"TypeError",
|
|
||||||
"ending index must be a number",
|
|
||||||
r.line,
|
|
||||||
r.path,
|
|
||||||
r.code,
|
|
||||||
true,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
slice = true
|
|
||||||
num := eindex.(number)
|
|
||||||
if !num.IsInt() {
|
|
||||||
return nil, ArErr{
|
|
||||||
"TypeError",
|
|
||||||
"ending index must be an integer",
|
|
||||||
r.line,
|
|
||||||
r.path,
|
|
||||||
r.code,
|
|
||||||
true,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
endindex = int(num.Num().Int64())
|
|
||||||
} else if r.numberofindex > 1 {
|
|
||||||
endindex = len(m)
|
|
||||||
}
|
|
||||||
if r.step != nil {
|
|
||||||
step, err := runVal(r.step, stack, stacklevel+1)
|
|
||||||
if err.EXISTS {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
if typeof(step) != "number" {
|
|
||||||
return nil, ArErr{
|
|
||||||
"TypeError",
|
|
||||||
"step must be a number",
|
|
||||||
r.line,
|
|
||||||
r.path,
|
|
||||||
r.code,
|
|
||||||
true,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
slice = true
|
|
||||||
num := step.(number)
|
|
||||||
if !num.IsInt() {
|
|
||||||
return nil, ArErr{
|
|
||||||
"TypeError",
|
|
||||||
"step must be an integer",
|
|
||||||
r.line,
|
|
||||||
r.path,
|
|
||||||
r.code,
|
|
||||||
true,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
step = int(num.Num().Int64())
|
|
||||||
}
|
|
||||||
if startindex < 0 {
|
|
||||||
startindex = len(m) + startindex
|
|
||||||
}
|
|
||||||
if endindex < 0 {
|
|
||||||
endindex = len(m) + endindex
|
|
||||||
}
|
|
||||||
if step < 0 {
|
|
||||||
step = -step
|
|
||||||
startindex, endindex = endindex, startindex
|
|
||||||
}
|
|
||||||
if startindex < 0 || startindex >= len(m) {
|
|
||||||
return nil, ArErr{
|
|
||||||
"IndexError",
|
|
||||||
"index '" + fmt.Sprint(startindex) + "' out of range",
|
|
||||||
r.line,
|
|
||||||
r.path,
|
|
||||||
r.code,
|
|
||||||
true,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if endindex < 0 || endindex > len(m) {
|
|
||||||
return nil, ArErr{
|
|
||||||
"IndexError",
|
|
||||||
"index '" + fmt.Sprint(endindex) + "' out of range",
|
|
||||||
r.line,
|
|
||||||
r.path,
|
|
||||||
r.code,
|
|
||||||
true,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if step == 0 {
|
|
||||||
return nil, ArErr{
|
|
||||||
"ValueError",
|
|
||||||
"step cannot be 0",
|
|
||||||
r.line,
|
|
||||||
r.path,
|
|
||||||
r.code,
|
|
||||||
true,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
fmt.Println(startindex, endindex,step)
|
|
||||||
if !slice {
|
|
||||||
return string(m[startindex]), ArErr{}
|
|
||||||
} else if step == 1 {
|
|
||||||
return string(m[startindex:endindex]), ArErr{}
|
|
||||||
}
|
|
||||||
output := []byte{}
|
|
||||||
for i := startindex; i < endindex; i += step {
|
|
||||||
output = append(output, output[i])
|
|
||||||
}
|
|
||||||
return string(output), ArErr{}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
key, err := runVal(r.start, stack, stacklevel+1)
|
key, err := runVal(r.args[0], stack, stacklevel+1)
|
||||||
if err.EXISTS {
|
if err.EXISTS {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -421,8 +105,7 @@ func mapGetParse(code UNPARSEcode, index int, codelines []UNPARSEcode) (ArMapGet
|
|||||||
if !worked {
|
if !worked {
|
||||||
return ArMapGet{}, false, err, i
|
return ArMapGet{}, false, err, i
|
||||||
}
|
}
|
||||||
k := key
|
return ArMapGet{resp, ArArray{key}, false, code.line, code.realcode, code.path}, true, ArErr{}, 1
|
||||||
return ArMapGet{resp, k, nil, nil, false, 1, code.line, code.realcode, code.path}, true, ArErr{}, 1
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func isIndexGet(code UNPARSEcode) bool {
|
func isIndexGet(code UNPARSEcode) bool {
|
||||||
@@ -433,11 +116,6 @@ func indexGetParse(code UNPARSEcode, index int, codelines []UNPARSEcode) (ArMapG
|
|||||||
trim := strings.TrimSpace(code.code)
|
trim := strings.TrimSpace(code.code)
|
||||||
trim = trim[:len(trim)-1]
|
trim = trim[:len(trim)-1]
|
||||||
split := strings.Split(trim, "[")
|
split := strings.Split(trim, "[")
|
||||||
var toindex any
|
|
||||||
var start any
|
|
||||||
var end any
|
|
||||||
var step any
|
|
||||||
numberofindexs := 0
|
|
||||||
for i := 1; i < len(split); i++ {
|
for i := 1; i < len(split); i++ {
|
||||||
ti := strings.Join(split[:i], "[")
|
ti := strings.Join(split[:i], "[")
|
||||||
innerbrackets := strings.Join(split[i:], "[")
|
innerbrackets := strings.Join(split[i:], "[")
|
||||||
@@ -461,25 +139,13 @@ func indexGetParse(code UNPARSEcode, index int, codelines []UNPARSEcode) (ArMapG
|
|||||||
}
|
}
|
||||||
tival, worked, err, i := translateVal(UNPARSEcode{code: ti, realcode: code.realcode, line: code.line, path: code.path}, index, codelines, 0)
|
tival, worked, err, i := translateVal(UNPARSEcode{code: ti, realcode: code.realcode, line: code.line, path: code.path}, index, codelines, 0)
|
||||||
if !worked {
|
if !worked {
|
||||||
fmt.Println(err)
|
|
||||||
if i == len(split)-1 {
|
if i == len(split)-1 {
|
||||||
return ArMapGet{}, false, err, i
|
return ArMapGet{}, false, err, i
|
||||||
}
|
}
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
numberofindexs = len(args)
|
return ArMapGet{tival, args, true, code.line, code.realcode, code.path}, true, ArErr{}, 1
|
||||||
if len(args) >= 1 {
|
|
||||||
toindex = tival
|
|
||||||
start = args[0]
|
|
||||||
}
|
}
|
||||||
if len(args) >= 2 {
|
|
||||||
end = args[1]
|
|
||||||
}
|
|
||||||
if len(args) >= 3 {
|
|
||||||
step = args[2]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if toindex == nil {
|
|
||||||
return ArMapGet{}, false, ArErr{
|
return ArMapGet{}, false, ArErr{
|
||||||
"SyntaxError",
|
"SyntaxError",
|
||||||
"invalid index get",
|
"invalid index get",
|
||||||
@@ -489,5 +155,194 @@ func indexGetParse(code UNPARSEcode, index int, codelines []UNPARSEcode) (ArMapG
|
|||||||
true,
|
true,
|
||||||
}, 1
|
}, 1
|
||||||
}
|
}
|
||||||
return ArMapGet{toindex, start, end, step, true, numberofindexs, code.line, code.realcode, code.path}, true, ArErr{}, 1
|
|
||||||
|
func isUnhashable(val any) bool {
|
||||||
|
keytype := typeof(val)
|
||||||
|
return keytype == "array" || keytype == "map"
|
||||||
|
}
|
||||||
|
|
||||||
|
func getFromArArray(m []any, r ArMapGet, stack stack, stacklevel int) (ArArray, ArErr) {
|
||||||
|
var (
|
||||||
|
start int = 0
|
||||||
|
end any = nil
|
||||||
|
step int = 1
|
||||||
|
)
|
||||||
|
{
|
||||||
|
startval, err := runVal(r.args[0], stack, stacklevel+1)
|
||||||
|
if err.EXISTS {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if startval == nil {
|
||||||
|
start = 0
|
||||||
|
} else if typeof(startval) != "number" && !startval.(number).IsInt() {
|
||||||
|
return nil, ArErr{
|
||||||
|
"TypeError",
|
||||||
|
"slice index must be an integer",
|
||||||
|
r.line,
|
||||||
|
r.path,
|
||||||
|
r.code,
|
||||||
|
true,
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
start = int(startval.(number).Num().Int64())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if len(r.args) > 1 {
|
||||||
|
endval, err := runVal(r.args[1], stack, stacklevel+1)
|
||||||
|
if err.EXISTS {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if endval == nil {
|
||||||
|
end = len(m)
|
||||||
|
} else if typeof(endval) != "number" && !endval.(number).IsInt() {
|
||||||
|
return nil, ArErr{
|
||||||
|
"TypeError",
|
||||||
|
"slice ending index must be an integer",
|
||||||
|
r.line,
|
||||||
|
r.path,
|
||||||
|
r.code,
|
||||||
|
true,
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
end = int(endval.(number).Num().Int64())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if len(r.args) > 2 {
|
||||||
|
stepval, err := runVal(r.args[2], stack, stacklevel+1)
|
||||||
|
if err.EXISTS {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if stepval == nil {
|
||||||
|
step = 1
|
||||||
|
} else if typeof(stepval) != "number" && !stepval.(number).IsInt() {
|
||||||
|
return nil, ArErr{
|
||||||
|
"TypeError",
|
||||||
|
"slice step must be an integer",
|
||||||
|
r.line,
|
||||||
|
r.path,
|
||||||
|
r.code,
|
||||||
|
true,
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
step = int(stepval.(number).Num().Int64())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if start < 0 {
|
||||||
|
start = len(m) + start
|
||||||
|
}
|
||||||
|
if _, ok := end.(int); ok && end.(int) < 0 {
|
||||||
|
end = len(m) + end.(int)
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Println(start, end, step)
|
||||||
|
if end == nil {
|
||||||
|
return ArArray{m[start]}, ArErr{}
|
||||||
|
} else if step == 1 {
|
||||||
|
return m[start:end.(int)], ArErr{}
|
||||||
|
} else {
|
||||||
|
output := ArArray{}
|
||||||
|
if step > 0 {
|
||||||
|
for i := start; i < end.(int); i += step {
|
||||||
|
output = append(output, m[i])
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
for i := end.(int) - 1; i >= start; i += step {
|
||||||
|
output = append(output, m[i])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return (output), ArErr{}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func getFromString(m string, r ArMapGet, stack stack, stacklevel int) (string, ArErr) {
|
||||||
|
var (
|
||||||
|
start int = 0
|
||||||
|
end any = nil
|
||||||
|
step int = 1
|
||||||
|
)
|
||||||
|
{
|
||||||
|
startval, err := runVal(r.args[0], stack, stacklevel+1)
|
||||||
|
if err.EXISTS {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
if startval == nil {
|
||||||
|
start = 0
|
||||||
|
} else if typeof(startval) != "number" && !startval.(number).IsInt() {
|
||||||
|
return "", ArErr{
|
||||||
|
"TypeError",
|
||||||
|
"slice index must be an integer",
|
||||||
|
r.line,
|
||||||
|
r.path,
|
||||||
|
r.code,
|
||||||
|
true,
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
start = int(startval.(number).Num().Int64())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if len(r.args) > 1 {
|
||||||
|
endval, err := runVal(r.args[1], stack, stacklevel+1)
|
||||||
|
if err.EXISTS {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
if endval == nil {
|
||||||
|
end = len(m)
|
||||||
|
} else if typeof(endval) != "number" && !endval.(number).IsInt() {
|
||||||
|
return "", ArErr{
|
||||||
|
"TypeError",
|
||||||
|
"slice ending index must be an integer",
|
||||||
|
r.line,
|
||||||
|
r.path,
|
||||||
|
r.code,
|
||||||
|
true,
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
end = int(endval.(number).Num().Int64())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if len(r.args) > 2 {
|
||||||
|
stepval, err := runVal(r.args[2], stack, stacklevel+1)
|
||||||
|
if err.EXISTS {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
if stepval == nil {
|
||||||
|
step = 1
|
||||||
|
} else if typeof(stepval) != "number" && !stepval.(number).IsInt() {
|
||||||
|
return "", ArErr{
|
||||||
|
"TypeError",
|
||||||
|
"slice step must be an integer",
|
||||||
|
r.line,
|
||||||
|
r.path,
|
||||||
|
r.code,
|
||||||
|
true,
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
step = int(stepval.(number).Num().Int64())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if start < 0 {
|
||||||
|
start = len(m) + start
|
||||||
|
}
|
||||||
|
if _, ok := end.(int); ok && end.(int) < 0 {
|
||||||
|
end = len(m) + end.(int)
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Println(start, end, step)
|
||||||
|
if end == nil {
|
||||||
|
return string(m[start]), ArErr{}
|
||||||
|
} else if step == 1 {
|
||||||
|
return m[start:end.(int)], ArErr{}
|
||||||
|
} else {
|
||||||
|
output := []byte{}
|
||||||
|
if step > 0 {
|
||||||
|
for i := start; i < end.(int); i += step {
|
||||||
|
output = append(output, m[i])
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
for i := end.(int) - 1; i >= start; i += step {
|
||||||
|
output = append(output, m[i])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return string(output), ArErr{}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ package main
|
|||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"errors"
|
"errors"
|
||||||
|
"math"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
)
|
)
|
||||||
@@ -33,19 +34,22 @@ func convertToArgon(obj any) any {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func parse(str string) any {
|
func jsonparse(str string) any {
|
||||||
var jsonMap any
|
var jsonMap any
|
||||||
json.Unmarshal([]byte(str), &jsonMap)
|
json.Unmarshal([]byte(str), &jsonMap)
|
||||||
return convertToArgon(jsonMap)
|
return convertToArgon(jsonMap)
|
||||||
}
|
}
|
||||||
|
|
||||||
func stringify(obj any) (string, error) {
|
func jsonstringify(obj any, level int) (string, error) {
|
||||||
|
if level > 100 {
|
||||||
|
return "", errors.New("json stringify error: too many levels")
|
||||||
|
}
|
||||||
output := []string{}
|
output := []string{}
|
||||||
obj = classVal(obj)
|
obj = classVal(obj)
|
||||||
switch x := obj.(type) {
|
switch x := obj.(type) {
|
||||||
case ArMap:
|
case ArMap:
|
||||||
for key, value := range x {
|
for key, value := range x {
|
||||||
str, err := stringify(value)
|
str, err := jsonstringify(value, level+1)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
@@ -53,20 +57,22 @@ func stringify(obj any) (string, error) {
|
|||||||
}
|
}
|
||||||
return "{" + strings.Join(output, ", ") + "}", nil
|
return "{" + strings.Join(output, ", ") + "}", nil
|
||||||
case ArArray:
|
case ArArray:
|
||||||
output = append(output, "[")
|
|
||||||
for _, value := range x {
|
for _, value := range x {
|
||||||
str, err := stringify(value)
|
str, err := jsonstringify(value, level+1)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
output = append(output, str)
|
output = append(output, str)
|
||||||
}
|
}
|
||||||
output = append(output, "]")
|
return "[" + strings.Join(output, ", ") + "]", nil
|
||||||
return strings.Join(output, ", "), nil
|
|
||||||
case string:
|
case string:
|
||||||
return strconv.Quote(x), nil
|
return strconv.Quote(x), nil
|
||||||
case number:
|
case number:
|
||||||
return anyToArgon(x, true, false, 1, 0, false, 0), nil
|
num, _ := x.Float64()
|
||||||
|
if math.IsNaN(num) || math.IsInf(num, 0) {
|
||||||
|
return "null", nil
|
||||||
|
}
|
||||||
|
return numberToString(x, false), nil
|
||||||
case bool:
|
case bool:
|
||||||
return strconv.FormatBool(x), nil
|
return strconv.FormatBool(x), nil
|
||||||
case nil:
|
case nil:
|
||||||
@@ -84,13 +90,13 @@ var ArJSON = ArMap{
|
|||||||
if typeof(args[0]) != "string" {
|
if typeof(args[0]) != "string" {
|
||||||
return ArMap{}, ArErr{TYPE: "Runtime Error", message: "parse takes a string not a '" + typeof(args[0]) + "'", EXISTS: true}
|
return ArMap{}, ArErr{TYPE: "Runtime Error", message: "parse takes a string not a '" + typeof(args[0]) + "'", EXISTS: true}
|
||||||
}
|
}
|
||||||
return parse(args[0].(string)), ArErr{}
|
return jsonparse(args[0].(string)), ArErr{}
|
||||||
}},
|
}},
|
||||||
"stringify": builtinFunc{"stringify", func(args ...any) (any, ArErr) {
|
"stringify": builtinFunc{"stringify", func(args ...any) (any, ArErr) {
|
||||||
if len(args) == 0 {
|
if len(args) == 0 {
|
||||||
return ArMap{}, ArErr{TYPE: "Runtime Error", message: "stringify takes 1 argument", EXISTS: true}
|
return ArMap{}, ArErr{TYPE: "Runtime Error", message: "stringify takes 1 argument", EXISTS: true}
|
||||||
}
|
}
|
||||||
str, err := stringify(args[0])
|
str, err := jsonstringify(args[0], 0)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return ArMap{}, ArErr{TYPE: "Runtime Error", message: err.Error(), EXISTS: true}
|
return ArMap{}, ArErr{TYPE: "Runtime Error", message: err.Error(), EXISTS: true}
|
||||||
}
|
}
|
||||||
@@ -6,6 +6,7 @@ import (
|
|||||||
|
|
||||||
var returnCompile = makeRegex(`( *)return( +)(.|\n)+`)
|
var returnCompile = makeRegex(`( *)return( +)(.|\n)+`)
|
||||||
var breakCompile = makeRegex(`( *)break( *)`)
|
var breakCompile = makeRegex(`( *)break( *)`)
|
||||||
|
var continueCompile = makeRegex(`( *)continue( *)`)
|
||||||
|
|
||||||
type CallReturn struct {
|
type CallReturn struct {
|
||||||
value any
|
value any
|
||||||
@@ -20,13 +21,12 @@ type Return struct {
|
|||||||
code string
|
code string
|
||||||
path string
|
path string
|
||||||
}
|
}
|
||||||
|
type Break struct {
|
||||||
type CallBreak struct {
|
|
||||||
line int
|
line int
|
||||||
code string
|
code string
|
||||||
path string
|
path string
|
||||||
}
|
}
|
||||||
type Break struct {
|
type Continue struct {
|
||||||
line int
|
line int
|
||||||
code string
|
code string
|
||||||
path string
|
path string
|
||||||
@@ -40,6 +40,10 @@ func isBreak(code UNPARSEcode) bool {
|
|||||||
return breakCompile.MatchString(code.code)
|
return breakCompile.MatchString(code.code)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func isContinue(code UNPARSEcode) bool {
|
||||||
|
return continueCompile.MatchString(code.code)
|
||||||
|
}
|
||||||
|
|
||||||
func parseReturn(code UNPARSEcode, index int, codeline []UNPARSEcode) (CallReturn, bool, ArErr, int) {
|
func parseReturn(code UNPARSEcode, index int, codeline []UNPARSEcode) (CallReturn, bool, ArErr, int) {
|
||||||
resp, worked, err, i := translateVal(UNPARSEcode{
|
resp, worked, err, i := translateVal(UNPARSEcode{
|
||||||
code: strings.TrimSpace(code.code)[6:],
|
code: strings.TrimSpace(code.code)[6:],
|
||||||
@@ -81,18 +85,29 @@ func openReturn(resp any) any {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func parseBreak(code UNPARSEcode, index int, codeline []UNPARSEcode) (CallBreak, bool, ArErr, int) {
|
func parseBreak(code UNPARSEcode) (Break, bool, ArErr, int) {
|
||||||
return CallBreak{
|
return Break{
|
||||||
line: code.line,
|
line: code.line,
|
||||||
code: code.realcode,
|
code: code.realcode,
|
||||||
path: code.path,
|
path: code.path,
|
||||||
}, true, ArErr{}, 1
|
}, true, ArErr{}, 1
|
||||||
}
|
}
|
||||||
|
|
||||||
func runBreak(code CallBreak, stack stack, stacklevel int) (any, ArErr) {
|
func parseContinue(code UNPARSEcode) (Continue, bool, ArErr, int) {
|
||||||
return Break{
|
return Continue{
|
||||||
line: code.line,
|
line: code.line,
|
||||||
code: code.code,
|
code: code.realcode,
|
||||||
path: code.path,
|
path: code.path,
|
||||||
}, ArErr{}
|
}, true, ArErr{}, 1
|
||||||
|
}
|
||||||
|
|
||||||
|
func ThrowOnNonLoop(val any, err ArErr) (any, ArErr) {
|
||||||
|
switch x := val.(type) {
|
||||||
|
case Break:
|
||||||
|
return nil, ArErr{"Break Error", "break can only be used in loops", x.line, x.path, x.code, true}
|
||||||
|
case Continue:
|
||||||
|
return nil, ArErr{"Continue Error", "continue can only be used in loops", x.line, x.path, x.code, true}
|
||||||
|
default:
|
||||||
|
return x, err
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -44,6 +44,7 @@ func numberToString(num number, simplify bool) string {
|
|||||||
return fmt.Sprint(num, "π")
|
return fmt.Sprint(num, "π")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
x, _ := num.Float64()
|
x, _ := num.Float64()
|
||||||
|
|
||||||
return fmt.Sprint(x)
|
return fmt.Sprint(x)
|
||||||
|
|||||||
146
src/run.go
146
src/run.go
@@ -7,32 +7,64 @@ import (
|
|||||||
|
|
||||||
// returns (number|string|nil), error
|
// returns (number|string|nil), error
|
||||||
func runVal(line any, stack stack, stacklevel int) (any, ArErr) {
|
func runVal(line any, stack stack, stacklevel int) (any, ArErr) {
|
||||||
if stacklevel >= 10000 {
|
var (
|
||||||
return nil, ArErr{
|
linenum = 0
|
||||||
TYPE: "RuntimeError",
|
path = ""
|
||||||
message: "stack overflow",
|
code = ""
|
||||||
line: 0,
|
stackoverflow = stacklevel >= 10000
|
||||||
path: "",
|
)
|
||||||
code: "",
|
|
||||||
EXISTS: true,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
switch x := line.(type) {
|
switch x := line.(type) {
|
||||||
case number:
|
case number:
|
||||||
return x, ArErr{}
|
return x, ArErr{}
|
||||||
case string:
|
case string:
|
||||||
return x, ArErr{}
|
return x, ArErr{}
|
||||||
case call:
|
case call:
|
||||||
|
if stackoverflow {
|
||||||
|
linenum = x.line
|
||||||
|
path = x.path
|
||||||
|
code = x.code
|
||||||
|
break
|
||||||
|
}
|
||||||
return runCall(x, stack, stacklevel+1)
|
return runCall(x, stack, stacklevel+1)
|
||||||
case factorial:
|
case factorial:
|
||||||
|
if stackoverflow {
|
||||||
|
linenum = x.line
|
||||||
|
path = x.path
|
||||||
|
code = x.code
|
||||||
|
break
|
||||||
|
}
|
||||||
return runFactorial(x, stack, stacklevel+1)
|
return runFactorial(x, stack, stacklevel+1)
|
||||||
case accessVariable:
|
case accessVariable:
|
||||||
|
if stackoverflow {
|
||||||
|
linenum = x.line
|
||||||
|
path = x.path
|
||||||
|
code = x.code
|
||||||
|
break
|
||||||
|
}
|
||||||
return readVariable(x, stack)
|
return readVariable(x, stack)
|
||||||
case ArMapGet:
|
case ArMapGet:
|
||||||
|
if stackoverflow {
|
||||||
|
linenum = x.line
|
||||||
|
path = x.path
|
||||||
|
code = x.code
|
||||||
|
break
|
||||||
|
}
|
||||||
return mapGet(x, stack, stacklevel+1)
|
return mapGet(x, stack, stacklevel+1)
|
||||||
case setVariable:
|
case setVariable:
|
||||||
|
if stackoverflow {
|
||||||
|
linenum = x.line
|
||||||
|
path = x.path
|
||||||
|
code = x.code
|
||||||
|
break
|
||||||
|
}
|
||||||
return setVariableValue(x, stack, stacklevel+1)
|
return setVariableValue(x, stack, stacklevel+1)
|
||||||
case negative:
|
case negative:
|
||||||
|
if stackoverflow {
|
||||||
|
linenum = x.line
|
||||||
|
path = x.path
|
||||||
|
code = x.code
|
||||||
|
break
|
||||||
|
}
|
||||||
resp, err := runVal(x.VAL, stack, stacklevel+1)
|
resp, err := runVal(x.VAL, stack, stacklevel+1)
|
||||||
resp = classVal(resp)
|
resp = classVal(resp)
|
||||||
if err.EXISTS {
|
if err.EXISTS {
|
||||||
@@ -48,34 +80,124 @@ func runVal(line any, stack stack, stacklevel int) (any, ArErr) {
|
|||||||
EXISTS: true,
|
EXISTS: true,
|
||||||
}
|
}
|
||||||
case brackets:
|
case brackets:
|
||||||
|
if stackoverflow {
|
||||||
|
linenum = x.line
|
||||||
|
path = x.path
|
||||||
|
code = x.code
|
||||||
|
break
|
||||||
|
}
|
||||||
return runVal(x.VAL, stack, stacklevel+1)
|
return runVal(x.VAL, stack, stacklevel+1)
|
||||||
case operationType:
|
case operationType:
|
||||||
|
if stackoverflow {
|
||||||
|
linenum = x.line
|
||||||
|
path = x.path
|
||||||
|
code = x.code
|
||||||
|
break
|
||||||
|
}
|
||||||
return runOperation(x, stack, stacklevel+1)
|
return runOperation(x, stack, stacklevel+1)
|
||||||
case dowrap:
|
case dowrap:
|
||||||
|
if stackoverflow {
|
||||||
|
linenum = x.line
|
||||||
|
path = x.path
|
||||||
|
code = x.code
|
||||||
|
break
|
||||||
|
}
|
||||||
return runDoWrap(x, stack, stacklevel+1)
|
return runDoWrap(x, stack, stacklevel+1)
|
||||||
case CallReturn:
|
case CallReturn:
|
||||||
|
if stackoverflow {
|
||||||
|
linenum = x.line
|
||||||
|
path = x.path
|
||||||
|
code = x.code
|
||||||
|
break
|
||||||
|
}
|
||||||
return runReturn(x, stack, stacklevel+1)
|
return runReturn(x, stack, stacklevel+1)
|
||||||
case CallBreak:
|
case Break:
|
||||||
return runBreak(x, stack, stacklevel+1)
|
if stackoverflow {
|
||||||
|
linenum = x.line
|
||||||
|
path = x.path
|
||||||
|
code = x.code
|
||||||
|
break
|
||||||
|
}
|
||||||
|
return x, ArErr{}
|
||||||
|
case Continue:
|
||||||
|
if stackoverflow {
|
||||||
|
linenum = x.line
|
||||||
|
path = x.path
|
||||||
|
code = x.code
|
||||||
|
break
|
||||||
|
}
|
||||||
|
return x, ArErr{}
|
||||||
case ArDelete:
|
case ArDelete:
|
||||||
|
if stackoverflow {
|
||||||
|
linenum = x.line
|
||||||
|
path = x.path
|
||||||
|
code = x.code
|
||||||
|
break
|
||||||
|
}
|
||||||
return runDelete(x, stack, stacklevel+1)
|
return runDelete(x, stack, stacklevel+1)
|
||||||
case not:
|
case not:
|
||||||
|
if stackoverflow {
|
||||||
|
linenum = x.line
|
||||||
|
path = x.path
|
||||||
|
code = x.code
|
||||||
|
break
|
||||||
|
}
|
||||||
return runNot(x, stack, stacklevel+1)
|
return runNot(x, stack, stacklevel+1)
|
||||||
case ifstatement:
|
case ifstatement:
|
||||||
|
if stackoverflow {
|
||||||
|
linenum = x.line
|
||||||
|
path = x.path
|
||||||
|
code = x.code
|
||||||
|
break
|
||||||
|
}
|
||||||
return runIfStatement(x, stack, stacklevel+1)
|
return runIfStatement(x, stack, stacklevel+1)
|
||||||
case whileLoop:
|
case whileLoop:
|
||||||
|
if stackoverflow {
|
||||||
|
linenum = x.line
|
||||||
|
path = x.path
|
||||||
|
code = x.code
|
||||||
|
break
|
||||||
|
}
|
||||||
return runWhileLoop(x, stack, stacklevel+1)
|
return runWhileLoop(x, stack, stacklevel+1)
|
||||||
case CreateArray:
|
case CreateArray:
|
||||||
|
if stackoverflow {
|
||||||
|
linenum = x.line
|
||||||
|
path = x.path
|
||||||
|
code = x.code
|
||||||
|
break
|
||||||
|
}
|
||||||
return runArray(x, stack, stacklevel+1)
|
return runArray(x, stack, stacklevel+1)
|
||||||
case squareroot:
|
case squareroot:
|
||||||
|
if stackoverflow {
|
||||||
|
linenum = x.line
|
||||||
|
path = x.path
|
||||||
|
code = x.code
|
||||||
|
break
|
||||||
|
}
|
||||||
return runSquareroot(x, stack, stacklevel+1)
|
return runSquareroot(x, stack, stacklevel+1)
|
||||||
case ArImport:
|
case ArImport:
|
||||||
|
if stackoverflow {
|
||||||
|
linenum = x.line
|
||||||
|
path = x.path
|
||||||
|
code = x.code
|
||||||
|
break
|
||||||
|
}
|
||||||
return runImport(x, stack, stacklevel+1)
|
return runImport(x, stack, stacklevel+1)
|
||||||
case bool:
|
case bool:
|
||||||
return x, ArErr{}
|
return x, ArErr{}
|
||||||
case nil:
|
case nil:
|
||||||
return nil, ArErr{}
|
return nil, ArErr{}
|
||||||
}
|
}
|
||||||
|
if stackoverflow {
|
||||||
|
return nil, ArErr{
|
||||||
|
TYPE: "RuntimeError",
|
||||||
|
message: "stack overflow",
|
||||||
|
line: linenum,
|
||||||
|
path: path,
|
||||||
|
code: code,
|
||||||
|
EXISTS: true,
|
||||||
|
}
|
||||||
|
}
|
||||||
fmt.Println("unreachable", reflect.TypeOf(line))
|
fmt.Println("unreachable", reflect.TypeOf(line))
|
||||||
panic("unreachable")
|
panic("unreachable")
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,12 +6,6 @@ import (
|
|||||||
"os/signal"
|
"os/signal"
|
||||||
)
|
)
|
||||||
|
|
||||||
var endingWithDoCompiled = makeRegex(`.*do( )*`)
|
|
||||||
|
|
||||||
func isEndingWithDo(str string) bool {
|
|
||||||
return endingWithDoCompiled.MatchString(str)
|
|
||||||
}
|
|
||||||
|
|
||||||
func shell() {
|
func shell() {
|
||||||
global := stack{vars, scope{}}
|
global := stack{vars, scope{}}
|
||||||
c := make(chan os.Signal, 1)
|
c := make(chan os.Signal, 1)
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
|
||||||
"strings"
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -30,7 +29,9 @@ func translateVal(code UNPARSEcode, index int, codelines []UNPARSEcode, isLine i
|
|||||||
} else if isReturn(code) {
|
} else if isReturn(code) {
|
||||||
return parseReturn(code, index, codelines)
|
return parseReturn(code, index, codelines)
|
||||||
} else if isBreak(code) {
|
} else if isBreak(code) {
|
||||||
return parseBreak(code, index, codelines)
|
return parseBreak(code)
|
||||||
|
} else if isContinue(code) {
|
||||||
|
return parseContinue(code)
|
||||||
} else if isIfStatement(code) {
|
} else if isIfStatement(code) {
|
||||||
return parseIfStatement(code, index, codelines)
|
return parseIfStatement(code, index, codelines)
|
||||||
} else if isWhileLoop(code) {
|
} else if isWhileLoop(code) {
|
||||||
@@ -98,7 +99,6 @@ func translateVal(code UNPARSEcode, index int, codelines []UNPARSEcode, isLine i
|
|||||||
return parseVariable(code)
|
return parseVariable(code)
|
||||||
} else if isArray(code) {
|
} else if isArray(code) {
|
||||||
resp, worked, err, i = parseArray(code, index, codelines)
|
resp, worked, err, i = parseArray(code, index, codelines)
|
||||||
fmt.Println(resp, worked, err, i)
|
|
||||||
if worked {
|
if worked {
|
||||||
return resp, worked, err, i
|
return resp, worked, err, i
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -227,7 +227,7 @@ func setVariableValue(v setVariable, stack stack, stacklevel int) (any, ArErr) {
|
|||||||
varMutex.Lock()
|
varMutex.Lock()
|
||||||
stack[i][x.name] = resp
|
stack[i][x.name] = resp
|
||||||
varMutex.Unlock()
|
varMutex.Unlock()
|
||||||
return resp, ArErr{}
|
return ThrowOnNonLoop(resp, ArErr{})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
varMutex.Lock()
|
varMutex.Lock()
|
||||||
@@ -238,15 +238,17 @@ func setVariableValue(v setVariable, stack stack, stacklevel int) (any, ArErr) {
|
|||||||
if err.EXISTS {
|
if err.EXISTS {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
key, err := runVal(x.start, stack, stacklevel+1)
|
if len(x.args) != 1 {
|
||||||
|
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)
|
||||||
if err.EXISTS {
|
if err.EXISTS {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
switch y := respp.(type) {
|
switch y := respp.(type) {
|
||||||
case ArMap:
|
case ArMap:
|
||||||
keytype := typeof(key)
|
if isUnhashable(key) {
|
||||||
if keytype == "array" || keytype == "map" {
|
return nil, ArErr{"Runtime Error", "can't use unhashable type as map key: " + typeof(key), v.line, v.path, v.code, true}
|
||||||
return nil, ArErr{TYPE: "TypeError", message: "Cannot use unhashable value as key: " + keytype, EXISTS: true}
|
|
||||||
}
|
}
|
||||||
varMutex.Lock()
|
varMutex.Lock()
|
||||||
y[key] = resp
|
y[key] = resp
|
||||||
@@ -256,7 +258,7 @@ func setVariableValue(v setVariable, stack stack, stacklevel int) (any, ArErr) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return resp, ArErr{}
|
return ThrowOnNonLoop(resp, ArErr{})
|
||||||
}
|
}
|
||||||
|
|
||||||
func parseDelete(code UNPARSEcode, index int, lines []UNPARSEcode) (ArDelete, bool, ArErr, int) {
|
func parseDelete(code UNPARSEcode, index int, lines []UNPARSEcode) (ArDelete, bool, ArErr, int) {
|
||||||
@@ -294,7 +296,10 @@ func runDelete(d ArDelete, stack stack, stacklevel int) (any, ArErr) {
|
|||||||
if err.EXISTS {
|
if err.EXISTS {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
key, err := runVal(x.start, stack, stacklevel+1)
|
if len(x.args) != 1 {
|
||||||
|
return nil, ArErr{"Runtime Error", "can't delete by slice", d.line, d.path, d.code, true}
|
||||||
|
}
|
||||||
|
key, err := runVal(x.args[0], stack, stacklevel+1)
|
||||||
if err.EXISTS {
|
if err.EXISTS {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -125,6 +125,8 @@ func runWhileLoop(loop whileLoop, stack stack, stacklevel int) (any, ArErr) {
|
|||||||
return x, ArErr{}
|
return x, ArErr{}
|
||||||
case Break:
|
case Break:
|
||||||
return nil, ArErr{}
|
return nil, ArErr{}
|
||||||
|
case Continue:
|
||||||
|
continue
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return nil, ArErr{}
|
return nil, ArErr{}
|
||||||
|
|||||||
Reference in New Issue
Block a user