mirror of
https://github.com/Open-Argon/argon-v3.git
synced 2025-12-06 08:56:07 +00:00
Merge remote-tracking branch 'upstream/master'
This commit is contained in:
@@ -20,13 +20,15 @@ func makeGlobal(allowDocument bool) ArObject {
|
|||||||
if x.TYPE == "array" {
|
if x.TYPE == "array" {
|
||||||
newmap := anymap{}
|
newmap := anymap{}
|
||||||
for i, v := range x.obj["__value__"].([]any) {
|
for i, v := range x.obj["__value__"].([]any) {
|
||||||
|
v := ArValidToAny(v)
|
||||||
switch y := v.(type) {
|
switch y := v.(type) {
|
||||||
case []any:
|
case []any:
|
||||||
if len(y) == 2 {
|
if len(y) == 2 {
|
||||||
if isUnhashable(y[0]) {
|
if isUnhashable(y[0]) {
|
||||||
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: " + typeof(y[0]), EXISTS: true}
|
||||||
}
|
}
|
||||||
newmap[y[0]] = y[1]
|
key := ArValidToAny(y[0])
|
||||||
|
newmap[key] = y[1]
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -165,5 +167,22 @@ func makeGlobal(allowDocument bool) ArObject {
|
|||||||
return ArArray([]any{}), ArErr{}
|
return ArArray([]any{}), ArErr{}
|
||||||
}}
|
}}
|
||||||
vars.obj["subprocess"] = builtinFunc{"subprocess", ArSubprocess}
|
vars.obj["subprocess"] = builtinFunc{"subprocess", ArSubprocess}
|
||||||
|
vars.obj["class"] = builtinFunc{"class", func(a ...any) (any, ArErr) {
|
||||||
|
if len(a) == 0 {
|
||||||
|
return nil, ArErr{TYPE: "TypeError", message: "Cannot create class from '" + typeof(a[0]) + "'", EXISTS: true}
|
||||||
|
}
|
||||||
|
switch x := a[0].(type) {
|
||||||
|
case ArObject:
|
||||||
|
if x.TYPE == "class" {
|
||||||
|
return x, ArErr{}
|
||||||
|
}
|
||||||
|
newclass := ArObject{TYPE: "class", obj: anymap{}}
|
||||||
|
for key, val := range x.obj {
|
||||||
|
newclass.obj[key] = val
|
||||||
|
}
|
||||||
|
return newclass, ArErr{}
|
||||||
|
}
|
||||||
|
return nil, ArErr{TYPE: "TypeError", message: "Cannot create class from '" + typeof(a[0]) + "'", EXISTS: true}
|
||||||
|
}}
|
||||||
return vars
|
return vars
|
||||||
}
|
}
|
||||||
|
|||||||
14
src/run.go
14
src/run.go
@@ -189,15 +189,11 @@ func runVal(line any, stack stack, stacklevel int) (any, ArErr) {
|
|||||||
break
|
break
|
||||||
}
|
}
|
||||||
return runImport(x, stack, stacklevel+1)
|
return runImport(x, stack, stacklevel+1)
|
||||||
case ABS:
|
case bool:
|
||||||
if stackoverflow {
|
return x, ArErr{}
|
||||||
linenum = x.line
|
case nil:
|
||||||
path = x.path
|
return x, ArErr{}
|
||||||
code = x.code
|
case ArObject:
|
||||||
break
|
|
||||||
}
|
|
||||||
return runAbs(x, stack, stacklevel+1)
|
|
||||||
case bool, ArObject, number, nil:
|
|
||||||
return x, ArErr{}
|
return x, ArErr{}
|
||||||
}
|
}
|
||||||
if stackoverflow {
|
if stackoverflow {
|
||||||
|
|||||||
@@ -14,13 +14,14 @@ func ArSubprocess(args ...any) (any, ArErr) {
|
|||||||
EXISTS: true,
|
EXISTS: true,
|
||||||
}
|
}
|
||||||
} else if typeof(args[0]) != "array" {
|
} else if typeof(args[0]) != "array" {
|
||||||
fmt.Println(args[0])
|
|
||||||
return nil, ArErr{
|
return nil, ArErr{
|
||||||
TYPE: "TypeError",
|
TYPE: "TypeError",
|
||||||
message: fmt.Sprintf("subprocess() argument must be an array, not %s", typeof(args[0])),
|
message: fmt.Sprintf("subprocess() argument must be an array, not %s", typeof(args[0])),
|
||||||
EXISTS: true,
|
EXISTS: true,
|
||||||
}
|
}
|
||||||
} else if len(args[0].([]any)) == 0 {
|
}
|
||||||
|
args[0] = ArValidToAny(args[0])
|
||||||
|
if len(args[0].([]any)) == 0 {
|
||||||
return nil, ArErr{
|
return nil, ArErr{
|
||||||
TYPE: "RuntimeError",
|
TYPE: "RuntimeError",
|
||||||
message: "subprocess() argument must be an array of strings, not an empty array",
|
message: "subprocess() argument must be an array of strings, not an empty array",
|
||||||
|
|||||||
@@ -42,6 +42,8 @@ func translateVal(code UNPARSEcode, index int, codelines []UNPARSEcode, isLine i
|
|||||||
return parseForLoop(code, index, codelines)
|
return parseForLoop(code, index, codelines)
|
||||||
} else if isGenericImport(code) {
|
} else if isGenericImport(code) {
|
||||||
return parseGenericImport(code, index, codelines)
|
return parseGenericImport(code, index, codelines)
|
||||||
|
} else if isTryCatch(code) {
|
||||||
|
return parseTryCatch(code, index, codelines)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if isLine >= 1 {
|
if isLine >= 1 {
|
||||||
@@ -77,12 +79,6 @@ func translateVal(code UNPARSEcode, index int, codelines []UNPARSEcode, isLine i
|
|||||||
return resp, worked, err, i
|
return resp, worked, err, i
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if isAutoAsignVariable(code) {
|
|
||||||
resp, worked, err, i = parseAutoAsignVariable(code, index, codelines, isLine)
|
|
||||||
if worked {
|
|
||||||
return resp, worked, err, i
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if isNumber(code) {
|
if isNumber(code) {
|
||||||
return parseNumber(code)
|
return parseNumber(code)
|
||||||
} else if isString(code) {
|
} else if isString(code) {
|
||||||
@@ -101,6 +97,12 @@ func translateVal(code UNPARSEcode, index int, codelines []UNPARSEcode, isLine i
|
|||||||
return resp, worked, err, i
|
return resp, worked, err, i
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if isAutoAsignVariable(code) {
|
||||||
|
resp, worked, err, i = parseAutoAsignVariable(code, index, codelines, isLine)
|
||||||
|
if worked {
|
||||||
|
return resp, worked, err, i
|
||||||
|
}
|
||||||
|
}
|
||||||
{
|
{
|
||||||
operation, worked, err, step := parseOperations(code, index, codelines)
|
operation, worked, err, step := parseOperations(code, index, codelines)
|
||||||
if worked {
|
if worked {
|
||||||
|
|||||||
73
src/trycatch.go
Normal file
73
src/trycatch.go
Normal file
@@ -0,0 +1,73 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
var tryCompiled = makeRegex(`\s*try\s(.|\n)+`)
|
||||||
|
var catchCompiled = makeRegex(`\s*catch\s*\(\s*` + spacelessVariable + `\s*\)\s*(.|\n)+`)
|
||||||
|
|
||||||
|
type TryCatch struct {
|
||||||
|
Try any
|
||||||
|
Catch any
|
||||||
|
errorName string
|
||||||
|
line int
|
||||||
|
path string
|
||||||
|
code string
|
||||||
|
}
|
||||||
|
|
||||||
|
func isTryCatch(code UNPARSEcode) bool {
|
||||||
|
return tryCompiled.MatchString(code.code)
|
||||||
|
}
|
||||||
|
|
||||||
|
func parseTryCatch(code UNPARSEcode, index int, codelines []UNPARSEcode) (TryCatch, bool, ArErr, int) {
|
||||||
|
trytrimmed := strings.TrimSpace(code.code)
|
||||||
|
totalIndex := 0
|
||||||
|
tryparsed, worked, err, i := translateVal(UNPARSEcode{trytrimmed[4:], code.realcode, code.line, code.path}, index, codelines, 1)
|
||||||
|
if !worked {
|
||||||
|
return TryCatch{}, false, err, i
|
||||||
|
}
|
||||||
|
totalIndex += i
|
||||||
|
catchtrimmed := strings.TrimSpace(codelines[index+totalIndex].code)
|
||||||
|
if !catchCompiled.MatchString(catchtrimmed) {
|
||||||
|
return TryCatch{}, false, ArErr{"Syntax Error", "invalid syntax", code.line, code.path, code.realcode, true}, i
|
||||||
|
}
|
||||||
|
catchtrimmed = catchtrimmed[6:]
|
||||||
|
catchbracketSplit := strings.SplitN(catchtrimmed, ")", 2)
|
||||||
|
errorName := strings.TrimSpace(strings.TrimSpace(catchbracketSplit[0])[1:])
|
||||||
|
errcode := catchbracketSplit[1]
|
||||||
|
|
||||||
|
catchparsed, worked, err, i := translateVal(UNPARSEcode{errcode, code.realcode, code.line, code.path}, index+totalIndex, codelines, 1)
|
||||||
|
if !worked {
|
||||||
|
return TryCatch{}, false, err, i
|
||||||
|
}
|
||||||
|
totalIndex += i
|
||||||
|
|
||||||
|
return TryCatch{
|
||||||
|
tryparsed,
|
||||||
|
catchparsed,
|
||||||
|
errorName,
|
||||||
|
code.line,
|
||||||
|
code.path,
|
||||||
|
code.realcode,
|
||||||
|
}, true, ArErr{}, totalIndex
|
||||||
|
}
|
||||||
|
|
||||||
|
func runTryCatch(t TryCatch, stack stack, stacklevel int) (any, ArErr) {
|
||||||
|
val, err := runVal(t.Try, stack, stacklevel)
|
||||||
|
if err.EXISTS {
|
||||||
|
scope := newscope()
|
||||||
|
scope.obj[t.errorName] = Map(anymap{
|
||||||
|
"type": err.TYPE,
|
||||||
|
"message": err.message,
|
||||||
|
"line": newNumber().SetInt64(int64(err.line)),
|
||||||
|
"path": err.path,
|
||||||
|
"code": err.code,
|
||||||
|
})
|
||||||
|
val, err = runVal(t.Catch, append(stack, scope), stacklevel)
|
||||||
|
if err.EXISTS {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return val, ArErr{}
|
||||||
|
}
|
||||||
@@ -35,6 +35,8 @@ var blockedVariableNames = map[string]bool{
|
|||||||
"not": true,
|
"not": true,
|
||||||
"and": true,
|
"and": true,
|
||||||
"or": true,
|
"or": true,
|
||||||
|
"try": true,
|
||||||
|
"catch": true,
|
||||||
}
|
}
|
||||||
|
|
||||||
type accessVariable struct {
|
type accessVariable struct {
|
||||||
@@ -85,7 +87,7 @@ func readVariable(v accessVariable, stack stack) (any, ArErr) {
|
|||||||
return val, ArErr{}
|
return val, ArErr{}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return nil, ArErr{"Runtime Error", "variable \"" + v.name + "\" does not exist", v.line, v.path, v.code, true}
|
return nil, ArErr{"Name Error", "variable \"" + v.name + "\" does not exist", v.line, v.path, v.code, true}
|
||||||
}
|
}
|
||||||
|
|
||||||
func isSetVariable(code UNPARSEcode) bool {
|
func isSetVariable(code UNPARSEcode) bool {
|
||||||
@@ -212,7 +214,7 @@ func setVariableValue(v setVariable, stack stack, stacklevel int) (any, ArErr) {
|
|||||||
_, ok := stack[len(stack)-1].obj[v.toset.(accessVariable).name]
|
_, ok := stack[len(stack)-1].obj[v.toset.(accessVariable).name]
|
||||||
varMutex.RUnlock()
|
varMutex.RUnlock()
|
||||||
if ok {
|
if ok {
|
||||||
return nil, ArErr{"Runtime Error", "variable \"" + v.toset.(accessVariable).name + "\" already exists", v.line, v.path, v.code, true}
|
return nil, ArErr{"Name Error", "variable \"" + v.toset.(accessVariable).name + "\" already exists", v.line, v.path, v.code, true}
|
||||||
}
|
}
|
||||||
varMutex.Lock()
|
varMutex.Lock()
|
||||||
stack[len(stack)-1].obj[v.toset.(accessVariable).name] = resp
|
stack[len(stack)-1].obj[v.toset.(accessVariable).name] = resp
|
||||||
@@ -307,7 +309,7 @@ func runDelete(d ArDelete, stack stack, stacklevel int) (any, ArErr) {
|
|||||||
return nil, ArErr{}
|
return nil, ArErr{}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return nil, ArErr{"Runtime Error", "variable \"" + x.name + "\" does not exist", d.line, d.path, d.code, true}
|
return nil, ArErr{"Name Error", "variable \"" + x.name + "\" does not exist", d.line, d.path, d.code, true}
|
||||||
case ArMapGet:
|
case ArMapGet:
|
||||||
respp, err := runVal(x.VAL, stack, stacklevel+1)
|
respp, err := runVal(x.VAL, stack, stacklevel+1)
|
||||||
if err.EXISTS {
|
if err.EXISTS {
|
||||||
|
|||||||
Reference in New Issue
Block a user