mirror of
https://github.com/Open-Argon/argon-v3.git
synced 2025-12-06 00:46:07 +00:00
work on adding indexing and slices
This commit is contained in:
@@ -8,7 +8,6 @@
|
|||||||
ARGON 3 is a math-driven programming language designed to make code easy to read and write. It's not meant to be fast, as it's interpreted. This specification should be used as a guideline, and is subject to change for later versions. Later updates for Argon 3 should be backwards compatible (where possible) with code designed for older versions of the interpreter.
|
ARGON 3 is a math-driven programming language designed to make code easy to read and write. It's not meant to be fast, as it's interpreted. This specification should be used as a guideline, and is subject to change for later versions. Later updates for Argon 3 should be backwards compatible (where possible) with code designed for older versions of the interpreter.
|
||||||
|
|
||||||
## 📚 Features
|
## 📚 Features
|
||||||
|
|
||||||
- Easy to read and write: Argon 3 is designed with clarity of code in mind, making it easier for you and others to read and write code.
|
- Easy to read and write: Argon 3 is designed with clarity of code in mind, making it easier for you and others to read and write code.
|
||||||
- All numbers are stored as rational numbers, preventing precision errors.
|
- All numbers are stored as rational numbers, preventing precision errors.
|
||||||
- Math-driven: Designed for mathematical computations, Argon 3 uses techniques and rules set in maths. It's designed to be easy for mathematicians to write and understand algorithms in.
|
- Math-driven: Designed for mathematical computations, Argon 3 uses techniques and rules set in maths. It's designed to be easy for mathematicians to write and understand algorithms in.
|
||||||
@@ -20,7 +19,6 @@ ARGON 3 is a math-driven programming language designed to make code easy to read
|
|||||||
As of now, Argon 3 does not have an installer. Feel free to clone this repo and run the `build` file for your plateform. the build will be found in `bin/argon(.exe)`.
|
As of now, Argon 3 does not have an installer. Feel free to clone this repo and run the `build` file for your plateform. the build will be found in `bin/argon(.exe)`.
|
||||||
|
|
||||||
## 📖 Usage
|
## 📖 Usage
|
||||||
|
|
||||||
To use Argon 3, you can create a file with the .ar extension and write your code in it. Then, you can run your code using the interpreter. For example, if you have a file called example.ar, you can run it using the following command:
|
To use Argon 3, you can create a file with the .ar extension and write your code in it. Then, you can run your code using the interpreter. For example, if you have a file called example.ar, you can run it using the following command:
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ package main
|
|||||||
var vars = scope{}
|
var vars = scope{}
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
vars["vars"] = vars
|
vars["global"] = vars
|
||||||
vars["term"] = ArTerm
|
vars["term"] = ArTerm
|
||||||
vars["true"] = true
|
vars["true"] = true
|
||||||
vars["false"] = false
|
vars["false"] = false
|
||||||
@@ -21,10 +21,33 @@ func init() {
|
|||||||
}
|
}
|
||||||
return nil, ArErr{TYPE: "TypeError", message: "Cannot get length of " + typeof(a[0]), EXISTS: true}
|
return nil, ArErr{TYPE: "TypeError", message: "Cannot get length of " + typeof(a[0]), EXISTS: true}
|
||||||
}}
|
}}
|
||||||
|
vars["map"] = builtinFunc{"map", func(a ...any) (any, ArErr) {
|
||||||
|
if len(a) == 0 {
|
||||||
|
return ArMap{}, ArErr{}
|
||||||
|
}
|
||||||
|
switch x := a[0].(type) {
|
||||||
|
case ArMap:
|
||||||
|
return x, ArErr{}
|
||||||
|
case string:
|
||||||
|
newmap := ArMap{}
|
||||||
|
for i, v := range x {
|
||||||
|
newmap[i] = string(v)
|
||||||
|
}
|
||||||
|
return newmap, ArErr{}
|
||||||
|
case []any:
|
||||||
|
newmap := ArMap{}
|
||||||
|
for i, v := range x {
|
||||||
|
newmap[i] = v
|
||||||
|
}
|
||||||
|
return newmap, ArErr{}
|
||||||
|
}
|
||||||
|
return nil, ArErr{TYPE: "TypeError", message: "Cannot create map from " + typeof(a[0]), EXISTS: true}
|
||||||
|
}}
|
||||||
vars["time"] = ArTime
|
vars["time"] = ArTime
|
||||||
vars["PI"] = PI
|
vars["PI"] = PI
|
||||||
vars["π"] = PI
|
vars["π"] = PI
|
||||||
vars["e"] = e
|
vars["e"] = e
|
||||||
sqrt := builtinFunc{"sqrt", ArgonSqrt}
|
sqrt := builtinFunc{"sqrt", ArgonSqrt}
|
||||||
vars["sqrt"] = sqrt
|
vars["sqrt"] = sqrt
|
||||||
|
vars["thread"] = builtinFunc{"thread", ArThread}
|
||||||
}
|
}
|
||||||
|
|||||||
17
src/call.go
17
src/call.go
@@ -30,7 +30,7 @@ func parseCall(code UNPARSEcode, index int, codelines []UNPARSEcode) (any, bool,
|
|||||||
for i := 1; i < len(splitby); i++ {
|
for i := 1; i < len(splitby); i++ {
|
||||||
name := strings.Join(splitby[0:i], "(")
|
name := strings.Join(splitby[0:i], "(")
|
||||||
argstr := strings.Join(splitby[i:], "(")
|
argstr := strings.Join(splitby[i:], "(")
|
||||||
args, success, argserr := getValuesFromCommas(argstr, index, codelines)
|
args, success, argserr := getValuesFromLetter(argstr, ",", index, codelines, true)
|
||||||
arguments = args
|
arguments = args
|
||||||
if !success {
|
if !success {
|
||||||
if i == len(splitby)-1 {
|
if i == len(splitby)-1 {
|
||||||
@@ -56,9 +56,18 @@ func parseCall(code UNPARSEcode, index int, codelines []UNPARSEcode) (any, bool,
|
|||||||
}
|
}
|
||||||
|
|
||||||
func runCall(c call, stack stack) (any, ArErr) {
|
func runCall(c call, stack stack) (any, ArErr) {
|
||||||
callable, err := runVal(c.callable, stack)
|
var callable any
|
||||||
if err.EXISTS {
|
switch x := c.callable.(type) {
|
||||||
return nil, err
|
case builtinFunc:
|
||||||
|
callable = x
|
||||||
|
case Callable:
|
||||||
|
callable = x
|
||||||
|
default:
|
||||||
|
callable_, err := runVal(c.callable, stack)
|
||||||
|
if err.EXISTS {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
callable = callable_
|
||||||
}
|
}
|
||||||
args := []any{}
|
args := []any{}
|
||||||
level := append(stack, scope{})
|
level := append(stack, scope{})
|
||||||
|
|||||||
@@ -1,27 +0,0 @@
|
|||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"strings"
|
|
||||||
)
|
|
||||||
|
|
||||||
func getValuesFromCommas(str string, index int, codelines []UNPARSEcode) ([]any, bool, ArErr) {
|
|
||||||
// make a function which takes a string of code and returns a translated values
|
|
||||||
str = strings.Trim(str, " ")
|
|
||||||
commasplit := strings.Split(str, ",")
|
|
||||||
temp := []string{}
|
|
||||||
arguments := []any{}
|
|
||||||
if str != "" {
|
|
||||||
for i, arg := range commasplit {
|
|
||||||
temp = append(temp, arg)
|
|
||||||
test := strings.TrimSpace(strings.Join(temp, ","))
|
|
||||||
resp, worked, _, _ := translateVal(UNPARSEcode{code: test, realcode: codelines[index].realcode, line: index + 1, path: codelines[index].path}, index, codelines, false)
|
|
||||||
if worked {
|
|
||||||
arguments = append(arguments, resp)
|
|
||||||
temp = []string{}
|
|
||||||
} else if i == len(commasplit)-1 {
|
|
||||||
return nil, false, ArErr{"Syntax Error", "invalid argument", codelines[index].line, codelines[index].path, codelines[index].realcode, true}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return arguments, true, ArErr{}
|
|
||||||
}
|
|
||||||
32
src/letterseperateseperate.go
Normal file
32
src/letterseperateseperate.go
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
func getValuesFromLetter(str string, splitstr string, index int, codelines []UNPARSEcode, allowempty bool) ([]any, bool, ArErr) {
|
||||||
|
// make a function which takes a string of code and returns a translated values
|
||||||
|
str = strings.Trim(str, " ")
|
||||||
|
commasplit := strings.Split(str, splitstr)
|
||||||
|
temp := []string{}
|
||||||
|
arguments := []any{}
|
||||||
|
if str != "" {
|
||||||
|
for i, arg := range commasplit {
|
||||||
|
temp = append(temp, arg)
|
||||||
|
test := strings.TrimSpace(strings.Join(temp, splitstr))
|
||||||
|
if test == "" && allowempty {
|
||||||
|
arguments = append(arguments, nil)
|
||||||
|
temp = []string{}
|
||||||
|
} else {
|
||||||
|
resp, worked, _, _ := translateVal(UNPARSEcode{code: test, realcode: codelines[index].realcode, line: index + 1, path: codelines[index].path}, index, codelines, false)
|
||||||
|
if worked {
|
||||||
|
arguments = append(arguments, resp)
|
||||||
|
temp = []string{}
|
||||||
|
} else if i == len(commasplit)-1 {
|
||||||
|
return nil, false, ArErr{"Syntax Error", "invalid argument", codelines[index].line, codelines[index].path, codelines[index].realcode, true}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return arguments, true, ArErr{}
|
||||||
|
}
|
||||||
93
src/map.go
93
src/map.go
@@ -1,93 +0,0 @@
|
|||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"strings"
|
|
||||||
)
|
|
||||||
|
|
||||||
type ArMap = map[any]any
|
|
||||||
|
|
||||||
type ArClass struct {
|
|
||||||
value any
|
|
||||||
MAP ArMap
|
|
||||||
}
|
|
||||||
|
|
||||||
var mapGetCompile = makeRegex(`(.|\n)+\.([a-zA-Z_]|(\p{L}\p{M}*))([a-zA-Z0-9_]|(\p{L}\p{M}*))*( *)`)
|
|
||||||
|
|
||||||
type ArMapGet struct {
|
|
||||||
VAL any
|
|
||||||
key any
|
|
||||||
line int
|
|
||||||
code string
|
|
||||||
path string
|
|
||||||
}
|
|
||||||
|
|
||||||
func mapGet(r ArMapGet, stack stack) (any, ArErr) {
|
|
||||||
resp, err := runVal(r.VAL, stack)
|
|
||||||
if err.EXISTS {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
key, err := runVal(r.key, stack)
|
|
||||||
if err.EXISTS {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
switch m := resp.(type) {
|
|
||||||
case ArMap:
|
|
||||||
if _, ok := m[key]; !ok {
|
|
||||||
return nil, ArErr{
|
|
||||||
"KeyError",
|
|
||||||
"key '" + fmt.Sprint(key) + "' not found",
|
|
||||||
r.line,
|
|
||||||
r.path,
|
|
||||||
r.code,
|
|
||||||
true,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return m[key], ArErr{}
|
|
||||||
case ArClass:
|
|
||||||
if _, ok := m.MAP[key]; !ok {
|
|
||||||
return nil, ArErr{
|
|
||||||
"KeyError",
|
|
||||||
"key '" + fmt.Sprint(key) + "' not found",
|
|
||||||
r.line,
|
|
||||||
r.path,
|
|
||||||
r.code,
|
|
||||||
true,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return m.MAP[key], ArErr{}
|
|
||||||
|
|
||||||
}
|
|
||||||
return nil, ArErr{
|
|
||||||
"TypeError",
|
|
||||||
"cannot read " + anyToArgon(key, true, true, 3, 0, false, 0) + " from type '" + typeof(resp) + "'",
|
|
||||||
r.line,
|
|
||||||
r.path,
|
|
||||||
r.code,
|
|
||||||
true,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func classVal(r any) any {
|
|
||||||
if _, ok := r.(ArClass); ok {
|
|
||||||
return r.(ArClass).value
|
|
||||||
}
|
|
||||||
return r
|
|
||||||
}
|
|
||||||
|
|
||||||
func isMapGet(code UNPARSEcode) bool {
|
|
||||||
return mapGetCompile.MatchString(code.code)
|
|
||||||
}
|
|
||||||
|
|
||||||
func mapGetParse(code UNPARSEcode, index int, codelines []UNPARSEcode) (ArMapGet, bool, ArErr, int) {
|
|
||||||
trim := strings.TrimSpace(code.code)
|
|
||||||
split := strings.Split(trim, ".")
|
|
||||||
start := strings.Join(split[:len(split)-1], ".")
|
|
||||||
key := split[len(split)-1]
|
|
||||||
resp, worked, err, i := translateVal(UNPARSEcode{code: start, realcode: code.realcode, line: code.line, path: code.path}, index, codelines, false)
|
|
||||||
if !worked {
|
|
||||||
return ArMapGet{}, false, err, i
|
|
||||||
}
|
|
||||||
k := key
|
|
||||||
return ArMapGet{resp, k, code.line, code.realcode, code.path}, true, ArErr{}, 1
|
|
||||||
}
|
|
||||||
477
src/mapAndArray.go
Normal file
477
src/mapAndArray.go
Normal file
@@ -0,0 +1,477 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
type ArMap = map[any]any
|
||||||
|
type ArArray = []any
|
||||||
|
|
||||||
|
type ArClass struct {
|
||||||
|
value any
|
||||||
|
MAP ArMap
|
||||||
|
}
|
||||||
|
|
||||||
|
var mapGetCompile = makeRegex(`(.|\n)+\.([a-zA-Z_]|(\p{L}\p{M}*))([a-zA-Z0-9_]|(\p{L}\p{M}*))*( *)`)
|
||||||
|
var indexGetCompile = makeRegex(`(.|\n)+\[(.|\n)+\]( *)`)
|
||||||
|
|
||||||
|
type ArMapGet struct {
|
||||||
|
VAL any
|
||||||
|
start any
|
||||||
|
end any
|
||||||
|
step any
|
||||||
|
index bool
|
||||||
|
numberofindex int
|
||||||
|
line int
|
||||||
|
code string
|
||||||
|
path string
|
||||||
|
}
|
||||||
|
|
||||||
|
func mapGet(r ArMapGet, stack stack) (any, ArErr) {
|
||||||
|
resp, err := runVal(r.VAL, stack)
|
||||||
|
if err.EXISTS {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
switch m := resp.(type) {
|
||||||
|
case ArMap:
|
||||||
|
if r.numberofindex > 1 {
|
||||||
|
return nil, ArErr{
|
||||||
|
"IndexError",
|
||||||
|
"index not found",
|
||||||
|
r.line,
|
||||||
|
r.path,
|
||||||
|
r.code,
|
||||||
|
true,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
key, err := runVal(r.start, stack)
|
||||||
|
if err.EXISTS {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if _, ok := m[key]; !ok {
|
||||||
|
return nil, ArErr{
|
||||||
|
"KeyError",
|
||||||
|
"key '" + fmt.Sprint(key) + "' not found",
|
||||||
|
r.line,
|
||||||
|
r.path,
|
||||||
|
r.code,
|
||||||
|
true,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return m[key], ArErr{}
|
||||||
|
|
||||||
|
case ArArray:
|
||||||
|
startindex := 0
|
||||||
|
endindex := 1
|
||||||
|
step := 1
|
||||||
|
|
||||||
|
if !r.index {
|
||||||
|
key, err := runVal(r.start, stack)
|
||||||
|
if err.EXISTS {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if key == "length" {
|
||||||
|
return len(m), ArErr{}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if r.start != nil {
|
||||||
|
sindex, err := runVal(r.start, stack)
|
||||||
|
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)
|
||||||
|
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,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
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)
|
||||||
|
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,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
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,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return m[startindex:endindex:step], ArErr{}
|
||||||
|
case ArClass:
|
||||||
|
if r.numberofindex > 1 {
|
||||||
|
return nil, ArErr{
|
||||||
|
"IndexError",
|
||||||
|
"index not found",
|
||||||
|
r.line,
|
||||||
|
r.path,
|
||||||
|
r.code,
|
||||||
|
true,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
key, err := runVal(r.start, stack)
|
||||||
|
if err.EXISTS {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if _, ok := m.MAP[key]; !ok {
|
||||||
|
return nil, ArErr{
|
||||||
|
"KeyError",
|
||||||
|
"key '" + fmt.Sprint(key) + "' not found",
|
||||||
|
r.line,
|
||||||
|
r.path,
|
||||||
|
r.code,
|
||||||
|
true,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return m.MAP[key], ArErr{}
|
||||||
|
case string:
|
||||||
|
startindex := 0
|
||||||
|
endindex := 1
|
||||||
|
step := 1
|
||||||
|
|
||||||
|
if !r.index {
|
||||||
|
key, err := runVal(r.start, stack)
|
||||||
|
if err.EXISTS {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if key == "length" {
|
||||||
|
return len(m), ArErr{}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if r.start != nil {
|
||||||
|
sindex, err := runVal(r.start, stack)
|
||||||
|
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)
|
||||||
|
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,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
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)
|
||||||
|
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,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
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,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return string(([]byte(m))[startindex:endindex:step]), ArErr{}
|
||||||
|
}
|
||||||
|
|
||||||
|
key, err := runVal(r.start, stack)
|
||||||
|
if err.EXISTS {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return nil, ArErr{
|
||||||
|
"TypeError",
|
||||||
|
"cannot read " + anyToArgon(key, true, true, 3, 0, false, 0) + " from type '" + typeof(resp) + "'",
|
||||||
|
r.line,
|
||||||
|
r.path,
|
||||||
|
r.code,
|
||||||
|
true,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func classVal(r any) any {
|
||||||
|
if _, ok := r.(ArClass); ok {
|
||||||
|
return r.(ArClass).value
|
||||||
|
}
|
||||||
|
return r
|
||||||
|
}
|
||||||
|
|
||||||
|
func isMapGet(code UNPARSEcode) bool {
|
||||||
|
return mapGetCompile.MatchString(code.code)
|
||||||
|
}
|
||||||
|
|
||||||
|
func mapGetParse(code UNPARSEcode, index int, codelines []UNPARSEcode) (ArMapGet, bool, ArErr, int) {
|
||||||
|
trim := strings.TrimSpace(code.code)
|
||||||
|
split := strings.Split(trim, ".")
|
||||||
|
start := strings.Join(split[:len(split)-1], ".")
|
||||||
|
key := split[len(split)-1]
|
||||||
|
resp, worked, err, i := translateVal(UNPARSEcode{code: start, realcode: code.realcode, line: code.line, path: code.path}, index, codelines, false)
|
||||||
|
if !worked {
|
||||||
|
return ArMapGet{}, false, err, i
|
||||||
|
}
|
||||||
|
k := key
|
||||||
|
return ArMapGet{resp, k, nil, nil, false, 1, code.line, code.realcode, code.path}, true, ArErr{}, 1
|
||||||
|
}
|
||||||
|
|
||||||
|
func isIndexGet(code UNPARSEcode) bool {
|
||||||
|
return indexGetCompile.MatchString(code.code)
|
||||||
|
}
|
||||||
|
|
||||||
|
func indexGetParse(code UNPARSEcode, index int, codelines []UNPARSEcode) (ArMapGet, bool, ArErr, int) {
|
||||||
|
trim := strings.TrimSpace(code.code)
|
||||||
|
trim = trim[:len(trim)-1]
|
||||||
|
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++ {
|
||||||
|
ti := strings.Join(split[:i], "[")
|
||||||
|
innerbrackets := strings.Join(split[i:], "[")
|
||||||
|
args, success, argserr := getValuesFromLetter(innerbrackets, ":", index, codelines, true)
|
||||||
|
if !success {
|
||||||
|
if i == len(split)-1 {
|
||||||
|
return ArMapGet{}, false, argserr, 1
|
||||||
|
}
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if len(args) > 3 {
|
||||||
|
return ArMapGet{}, false, ArErr{
|
||||||
|
"SyntaxError",
|
||||||
|
"too many arguments for index get",
|
||||||
|
code.line,
|
||||||
|
code.path,
|
||||||
|
code.realcode,
|
||||||
|
true,
|
||||||
|
}, 1
|
||||||
|
}
|
||||||
|
tival, worked, err, i := translateVal(UNPARSEcode{code: ti, realcode: code.realcode, line: code.line, path: code.path}, index, codelines, false)
|
||||||
|
if !worked {
|
||||||
|
if i == len(split)-1 {
|
||||||
|
return ArMapGet{}, false, err, i
|
||||||
|
}
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
numberofindexs = len(args)
|
||||||
|
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{
|
||||||
|
"SyntaxError",
|
||||||
|
"invalid index get",
|
||||||
|
code.line,
|
||||||
|
code.path,
|
||||||
|
code.realcode,
|
||||||
|
true,
|
||||||
|
}, 1
|
||||||
|
}
|
||||||
|
return ArMapGet{toindex, start, end, step, true, numberofindexs, code.line, code.realcode, code.path}, true, ArErr{}, 1
|
||||||
|
}
|
||||||
49
src/threading.go
Normal file
49
src/threading.go
Normal file
@@ -0,0 +1,49 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import "sync"
|
||||||
|
|
||||||
|
func ArThread(args ...any) (any, ArErr) {
|
||||||
|
if len(args) == 0 {
|
||||||
|
return nil, ArErr{TYPE: "TypeError", message: "Cannot call thread without a function", EXISTS: true}
|
||||||
|
}
|
||||||
|
var tocall any
|
||||||
|
switch x := args[0].(type) {
|
||||||
|
case Callable:
|
||||||
|
tocall = x
|
||||||
|
case builtinFunc:
|
||||||
|
tocall = x
|
||||||
|
default:
|
||||||
|
return nil, ArErr{TYPE: "TypeError", message: "Cannot call thread with a '" + typeof(args[0]) + "'", EXISTS: true}
|
||||||
|
}
|
||||||
|
var resp any
|
||||||
|
var err ArErr
|
||||||
|
currentscope := stack{vars, scope{}}
|
||||||
|
hasrun := false
|
||||||
|
joined := false
|
||||||
|
var wg sync.WaitGroup
|
||||||
|
threaMap := ArMap{
|
||||||
|
"start": builtinFunc{"start", func(args ...any) (any, ArErr) {
|
||||||
|
if hasrun {
|
||||||
|
return nil, ArErr{TYPE: "Runtime Error", message: "Cannot start a thread twice", EXISTS: true}
|
||||||
|
}
|
||||||
|
hasrun = true
|
||||||
|
wg.Add(1)
|
||||||
|
go func() {
|
||||||
|
resp, err = runCall(call{tocall, []any{}, "", 0, ""}, currentscope)
|
||||||
|
wg.Done()
|
||||||
|
}()
|
||||||
|
return nil, ArErr{}
|
||||||
|
}},
|
||||||
|
"join": builtinFunc{"join", func(args ...any) (any, ArErr) {
|
||||||
|
if !hasrun {
|
||||||
|
return nil, ArErr{TYPE: "Runtime Error", message: "Cannot join a thread that has not started", EXISTS: true}
|
||||||
|
} else if joined {
|
||||||
|
return nil, ArErr{TYPE: "Runtime Error", message: "Cannot join a thread twice", EXISTS: true}
|
||||||
|
}
|
||||||
|
joined = true
|
||||||
|
wg.Wait()
|
||||||
|
return resp, err
|
||||||
|
}},
|
||||||
|
}
|
||||||
|
return threaMap, ArErr{}
|
||||||
|
}
|
||||||
@@ -70,6 +70,9 @@ func anyToArgon(x any, quote bool, simplify bool, depth int, indent int, color b
|
|||||||
output = append(output, "\x1b[0m")
|
output = append(output, "\x1b[0m")
|
||||||
}
|
}
|
||||||
case ArMap:
|
case ArMap:
|
||||||
|
if len(x) == 0 {
|
||||||
|
return "{}"
|
||||||
|
}
|
||||||
keys := make([]any, len(x))
|
keys := make([]any, len(x))
|
||||||
|
|
||||||
i := 0
|
i := 0
|
||||||
|
|||||||
@@ -61,6 +61,8 @@ func translateVal(code UNPARSEcode, index int, codelines []UNPARSEcode, isLine b
|
|||||||
return parseVariable(code)
|
return parseVariable(code)
|
||||||
} else if isMapGet(code) {
|
} else if isMapGet(code) {
|
||||||
return mapGetParse(code, index, codelines)
|
return mapGetParse(code, index, codelines)
|
||||||
|
} else if isIndexGet(code) {
|
||||||
|
return indexGetParse(code, index, codelines)
|
||||||
} else if isString(code) {
|
} else if isString(code) {
|
||||||
return parseString(code)
|
return parseString(code)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
var variableCompile = makeRegex(`( *)([a-zA-Z_]|(\p{L}\p{M}*))([a-zA-Z0-9_]|(\p{L}\p{M}*))*( *)`)
|
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 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)+`)
|
var setVariableCompile = makeRegex(`( *)(let( +))(.|\n)+( *)=(.|\n)+`)
|
||||||
var autoAsignVariableCompile = makeRegex(`(.|\n)+=(.|\n)+`)
|
var autoAsignVariableCompile = makeRegex(`(.|\n)+=(.|\n)+`)
|
||||||
var deleteVariableCompile = makeRegex(`( *)delete( +)(.|\n)+( *)`)
|
var deleteVariableCompile = makeRegex(`( *)delete( +)(.|\n)+( *)`)
|
||||||
@@ -101,6 +101,9 @@ func nameToTranslated(code UNPARSEcode, index int, lines []UNPARSEcode) (any, bo
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
name := strings.TrimSpace(trimmed[:start])
|
name := strings.TrimSpace(trimmed[:start])
|
||||||
|
if name == "" {
|
||||||
|
return setFunction{toset: nil, params: params}, true, ArErr{}, 1
|
||||||
|
}
|
||||||
if blockedVariableNames[name] {
|
if blockedVariableNames[name] {
|
||||||
return accessVariable{}, false, ArErr{"Naming Error", "\"" + name + "\" is a reserved keyword", code.line, code.path, code.realcode, true}, 1
|
return accessVariable{}, false, ArErr{"Naming Error", "\"" + name + "\" is a reserved keyword", code.line, code.path, code.realcode, true}, 1
|
||||||
}
|
}
|
||||||
@@ -136,6 +139,9 @@ func parseSetVariable(code UNPARSEcode, index int, lines []UNPARSEcode) (setVari
|
|||||||
function = true
|
function = true
|
||||||
params = toset.(setFunction).params
|
params = toset.(setFunction).params
|
||||||
toset = toset.(setFunction).toset
|
toset = toset.(setFunction).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
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
return setVariable{}, false, ArErr{"Type Error", "can't set for non variable, did you mean '=='?", 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
|
||||||
}
|
}
|
||||||
@@ -210,7 +216,7 @@ func setVariableValue(v setVariable, stack stack) (any, ArErr) {
|
|||||||
if err.EXISTS {
|
if err.EXISTS {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
key, err := runVal(x.key, stack)
|
key, err := runVal(x.start, stack)
|
||||||
if err.EXISTS {
|
if err.EXISTS {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -260,7 +266,7 @@ func runDelete(d ArDelete, stack stack) (any, ArErr) {
|
|||||||
if err.EXISTS {
|
if err.EXISTS {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
key, err := runVal(x.key, stack)
|
key, err := runVal(x.start, stack)
|
||||||
if err.EXISTS {
|
if err.EXISTS {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user