add json and file read

This commit is contained in:
2023-03-12 23:34:33 +00:00
parent 4619f1c278
commit 7220d12fb6
11 changed files with 256 additions and 6 deletions

40
src/array.go Normal file
View File

@@ -0,0 +1,40 @@
package main
import "strings"
var arrayCompile = makeRegex(`( *)\[(.|\n)*\]( *)`)
type CreateArray struct {
value ArArray
line int
code string
path string
}
func isArray(code UNPARSEcode) bool {
return arrayCompile.MatchString(code.code)
}
func parseArray(code UNPARSEcode, index int, codelines []UNPARSEcode) (any, bool, ArErr, int) {
trimmed := strings.TrimSpace(code.code)
trimmed = trimmed[1 : len(trimmed)-1]
arguments, worked, err := getValuesFromLetter(trimmed, ",", index, codelines, true)
return CreateArray{
value: arguments,
line: code.line,
code: code.realcode,
path: code.path,
}, worked, err, 1
}
func runArray(a CreateArray, stack stack, stacklevel int) ([]any, ArErr) {
var array ArArray
for _, val := range a.value {
val, err := runVal(val, stack, stacklevel+1)
if err.EXISTS {
return nil, err
}
array = append(array, val)
}
return array, ArErr{}
}

View File

@@ -162,5 +162,7 @@ func init() {
return nil, ArErr{TYPE: "TypeError", message: "Cannot append to '" + typeof(a[0]) + "'", EXISTS: true}
}}
vars["sqrt"] = builtinFunc{"sqrt", ArgonSqrt}
vars["file"] = ArFile
vars["random"] = ArRandom
vars["json"] = ArJSON
}

54
src/file.go Normal file
View File

@@ -0,0 +1,54 @@
package main
import (
"bytes"
"io"
"os"
)
var ArFile = ArMap{
"read": builtinFunc{"read", ArRead},
}
func readtext(file *os.File) (string, error) {
var buf bytes.Buffer
_, err := io.Copy(&buf, file)
if err != nil {
return "", err
}
return string(buf.Bytes()), nil
}
func ArRead(args ...any) (any, ArErr) {
if len(args) == 0 {
return ArMap{}, ArErr{TYPE: "Runtime Error", message: "open takes 1 argument", EXISTS: true}
}
if typeof(args[0]) != "string" {
return ArMap{}, ArErr{TYPE: "Runtime Error", message: "open takes a string not a '" + typeof(args[0]) + "'", EXISTS: true}
}
filename := args[0].(string)
file, err := os.Open(filename)
if err != nil {
return ArMap{}, ArErr{TYPE: "Runtime Error", message: err.Error(), EXISTS: true}
}
return ArMap{
"text": builtinFunc{"text", func(...any) (any, ArErr) {
text, err := readtext(file)
if err != nil {
return ArMap{}, ArErr{TYPE: "Runtime Error", message: err.Error(), EXISTS: true}
}
return text, ArErr{}
}},
"json": builtinFunc{"json", func(...any) (any, ArErr) {
text, err := readtext(file)
if err != nil {
return ArMap{}, ArErr{TYPE: "Runtime Error", message: err.Error(), EXISTS: true}
}
return parse(text), ArErr{}
}},
"line": builtinFunc{"line", func(...any) (any, ArErr) {
return "", ArErr{}
}},
}, ArErr{}
}

View File

@@ -72,12 +72,13 @@ func mapGet(r ArMapGet, stack stack, stacklevel int) (any, ArErr) {
if err.EXISTS {
return nil, err
}
if key == "length" {
switch key {
case "length":
return newNumber().SetInt64(int64(len(m))), ArErr{}
}
return nil, ArErr{
"IndexError",
"index not found",
"" + anyToArgon(key, true, true, 3, 0, false, 0) + " does not exist in array",
r.line,
r.path,
r.code,
@@ -216,7 +217,8 @@ func mapGet(r ArMapGet, stack stack, stacklevel int) (any, ArErr) {
if !slice {
return m[startindex], ArErr{}
}
return m[startindex:endindex:step], ArErr{}
fmt.Println(startindex, endindex, step)
return m[startindex:endindex], ArErr{}
case ArClass:
if r.numberofindex > 1 {
return nil, ArErr{

99
src/jsonread.go Normal file
View File

@@ -0,0 +1,99 @@
package main
import (
"encoding/json"
"errors"
"strconv"
"strings"
)
func convertToArgon(obj any) any {
switch x := obj.(type) {
case map[string]interface{}:
newmap := ArMap{}
for key, value := range x {
newmap[key] = convertToArgon(value)
}
return newmap
case ArArray:
newarray := ArArray{}
for _, value := range x {
newarray = append(newarray, convertToArgon(value))
}
return newarray
case string:
return x
case float64:
return newNumber().SetFloat64(x)
case bool:
return x
case nil:
return nil
}
return nil
}
func parse(str string) any {
var jsonMap any
json.Unmarshal([]byte(str), &jsonMap)
return convertToArgon(jsonMap)
}
func stringify(obj any) (string, error) {
output := []string{}
switch x := obj.(type) {
case ArMap:
for key, value := range x {
str, err := stringify(value)
if err != nil {
return "", err
}
output = append(output, ""+strconv.Quote(anyToArgon(key, false, true, 3, 0, false, 0))+": "+str)
}
return "{" + strings.Join(output, ", ") + "}", nil
case ArArray:
output = append(output, "[")
for _, value := range x {
str, err := stringify(value)
if err != nil {
return "", err
}
output = append(output, str)
}
output = append(output, "]")
return strings.Join(output, ", "), nil
case string:
return strconv.Quote(x), nil
case number:
num, _ := x.Float64()
return strconv.FormatFloat(num, 'f', -1, 64), nil
case bool:
return strconv.FormatBool(x), nil
case nil:
return "null", nil
}
err := errors.New("Cannot stringify " + typeof(obj))
return "", err
}
var ArJSON = ArMap{
"parse": builtinFunc{"parse", func(args ...any) (any, ArErr) {
if len(args) == 0 {
return ArMap{}, ArErr{TYPE: "Runtime Error", message: "parse takes 1 argument", EXISTS: true}
}
if typeof(args[0]) != "string" {
return ArMap{}, ArErr{TYPE: "Runtime Error", message: "parse takes a string not a '" + typeof(args[0]) + "'", EXISTS: true}
}
return parse(args[0].(string)), ArErr{}
}},
"stringify": builtinFunc{"stringify", func(args ...any) (any, ArErr) {
if len(args) == 0 {
return ArMap{}, ArErr{TYPE: "Runtime Error", message: "stringify takes 1 argument", EXISTS: true}
}
str, err := stringify(args[0])
if err != nil {
return ArMap{}, ArErr{TYPE: "Runtime Error", message: err.Error(), EXISTS: true}
}
return str, ArErr{}
}},
}

View File

@@ -67,6 +67,8 @@ func runVal(line any, stack stack, stacklevel int) (any, ArErr) {
return runIfStatement(x, stack, stacklevel+1)
case whileLoop:
return runWhileLoop(x, stack, stacklevel+1)
case CreateArray:
return runArray(x, stack, stacklevel+1)
case bool:
return x, ArErr{}
case nil:

View File

@@ -87,6 +87,8 @@ func translateVal(code UNPARSEcode, index int, codelines []UNPARSEcode, isLine i
return parseBoolean(code)
} else if isVariable(code) {
return parseVariable(code)
} else if isArray(code) {
return parseArray(code, index, codelines)
} else if isMapGet(code) {
return mapGetParse(code, index, codelines)
} else if isIndexGet(code) {