From 7220d12fb6cfe1f8eee1d8e7b069eca95dce63de Mon Sep 17 00:00:00 2001 From: Ugric Date: Sun, 12 Mar 2023 23:34:33 +0000 Subject: [PATCH] add json and file read --- ArLogo.svg | 25 ++++++++ build.bat | 1 - src/array.go | 40 ++++++++++++ src/built-ins.go | 2 + src/file.go | 54 ++++++++++++++++ src/{mapAndArray.go => getIndex.go} | 8 ++- src/jsonread.go | 99 +++++++++++++++++++++++++++++ src/run.go | 2 + src/translate.go | 2 + test.ar | 3 +- test.json | 26 ++++++++ 11 files changed, 256 insertions(+), 6 deletions(-) create mode 100644 ArLogo.svg create mode 100644 src/array.go create mode 100644 src/file.go rename src/{mapAndArray.go => getIndex.go} (97%) create mode 100644 src/jsonread.go create mode 100644 test.json diff --git a/ArLogo.svg b/ArLogo.svg new file mode 100644 index 0000000..5b0b936 --- /dev/null +++ b/ArLogo.svg @@ -0,0 +1,25 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/build.bat b/build.bat index 1318b26..9af9c18 100644 --- a/build.bat +++ b/build.bat @@ -1,3 +1,2 @@ @echo off - go build -o bin/argon.exe ./src \ No newline at end of file diff --git a/src/array.go b/src/array.go new file mode 100644 index 0000000..de9971d --- /dev/null +++ b/src/array.go @@ -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{} +} diff --git a/src/built-ins.go b/src/built-ins.go index c8adef6..87f67c8 100644 --- a/src/built-ins.go +++ b/src/built-ins.go @@ -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 } diff --git a/src/file.go b/src/file.go new file mode 100644 index 0000000..2863d9f --- /dev/null +++ b/src/file.go @@ -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{} +} diff --git a/src/mapAndArray.go b/src/getIndex.go similarity index 97% rename from src/mapAndArray.go rename to src/getIndex.go index 46a1ddc..6fdb5c9 100644 --- a/src/mapAndArray.go +++ b/src/getIndex.go @@ -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{ diff --git a/src/jsonread.go b/src/jsonread.go new file mode 100644 index 0000000..a4734b3 --- /dev/null +++ b/src/jsonread.go @@ -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{} + }}, +} diff --git a/src/run.go b/src/run.go index 68d9134..fdc4777 100644 --- a/src/run.go +++ b/src/run.go @@ -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: diff --git a/src/translate.go b/src/translate.go index d93e0fc..d2ac357 100644 --- a/src/translate.go +++ b/src/translate.go @@ -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) { diff --git a/test.ar b/test.ar index c9573e2..38c7218 100644 --- a/test.ar +++ b/test.ar @@ -5,5 +5,4 @@ forever do a = append(a, i) i = i + 1 if (i % 1000000 == 0) do - term.log(i) - break \ No newline at end of file + term.log(i) \ No newline at end of file diff --git a/test.json b/test.json new file mode 100644 index 0000000..ef57753 --- /dev/null +++ b/test.json @@ -0,0 +1,26 @@ +[ + { + "id": 1, + "name": "John", + "age": 20, + "city": "New York" + }, + { + "id": 2, + "name": "Peter", + "age": 21, + "city": "London" + }, + { + "id": 3, + "name": "Sally", + "age": 22, + "city": "Paris" + }, + { + "id": 4, + "name": "Jane", + "age": 23, + "city": "Tokyo" + } +] \ No newline at end of file