mirror of
https://github.com/Open-Argon/argon-v3.git
synced 2025-12-06 08:56:07 +00:00
248 lines
4.5 KiB
Go
248 lines
4.5 KiB
Go
package main
|
|
|
|
import (
|
|
"fmt"
|
|
"reflect"
|
|
)
|
|
|
|
// returns (number|string|nil), error
|
|
func runVal(line any, stack stack, stacklevel int) (any, ArErr) {
|
|
var (
|
|
linenum = 0
|
|
path = ""
|
|
code = ""
|
|
stackoverflow = stacklevel >= 10000
|
|
)
|
|
switch x := line.(type) {
|
|
case string:
|
|
return ArString(x), ArErr{}
|
|
case call:
|
|
if stackoverflow {
|
|
linenum = x.Line
|
|
path = x.Path
|
|
code = x.Code
|
|
break
|
|
}
|
|
return runCall(x, stack, stacklevel+1)
|
|
case factorial:
|
|
if stackoverflow {
|
|
linenum = x.line
|
|
path = x.path
|
|
code = x.code
|
|
break
|
|
}
|
|
return runFactorial(x, stack, stacklevel+1)
|
|
case accessVariable:
|
|
if stackoverflow {
|
|
linenum = x.Line
|
|
path = x.Path
|
|
code = x.Code
|
|
break
|
|
}
|
|
return readVariable(x, stack)
|
|
case ArMapGet:
|
|
if stackoverflow {
|
|
linenum = x.Line
|
|
path = x.Path
|
|
code = x.Code
|
|
break
|
|
}
|
|
return mapGet(x, stack, stacklevel+1)
|
|
case setVariable:
|
|
if stackoverflow {
|
|
linenum = x.line
|
|
path = x.path
|
|
code = x.code
|
|
break
|
|
}
|
|
return setVariableValue(x, stack, stacklevel+1)
|
|
case negative:
|
|
if stackoverflow {
|
|
linenum = x.line
|
|
path = x.path
|
|
code = x.code
|
|
break
|
|
}
|
|
resp, err := runVal(x.VAL, stack, stacklevel+1)
|
|
resp = AnyToArValid(resp)
|
|
if err.EXISTS {
|
|
return nil, err
|
|
}
|
|
switch y := resp.(type) {
|
|
case number:
|
|
if !x.sign {
|
|
return newNumber().Neg(y), ArErr{}
|
|
}
|
|
return y, ArErr{}
|
|
}
|
|
return nil, ArErr{
|
|
TYPE: "TypeError",
|
|
message: "cannot negate a non-number",
|
|
EXISTS: true,
|
|
}
|
|
case brackets:
|
|
if stackoverflow {
|
|
linenum = x.line
|
|
path = x.path
|
|
code = x.code
|
|
break
|
|
}
|
|
return runVal(x.VAL, stack, stacklevel+1)
|
|
case operationType:
|
|
if stackoverflow {
|
|
linenum = x.line
|
|
path = x.path
|
|
code = x.code
|
|
break
|
|
}
|
|
return runOperation(x, stack, stacklevel+1)
|
|
case dowrap:
|
|
if stackoverflow {
|
|
linenum = x.line
|
|
path = x.path
|
|
code = x.code
|
|
break
|
|
}
|
|
return runDoWrap(x, stack, stacklevel+1)
|
|
case CallReturn:
|
|
if stackoverflow {
|
|
linenum = x.line
|
|
path = x.path
|
|
code = x.code
|
|
break
|
|
}
|
|
return runReturn(x, stack, stacklevel+1)
|
|
case Break:
|
|
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:
|
|
if stackoverflow {
|
|
linenum = x.line
|
|
path = x.path
|
|
code = x.code
|
|
break
|
|
}
|
|
return runDelete(x, stack, stacklevel+1)
|
|
case not:
|
|
if stackoverflow {
|
|
linenum = x.line
|
|
path = x.path
|
|
code = x.code
|
|
break
|
|
}
|
|
return runNot(x, stack, stacklevel+1)
|
|
case ifstatement:
|
|
if stackoverflow {
|
|
linenum = x.line
|
|
path = x.path
|
|
code = x.code
|
|
break
|
|
}
|
|
return runIfStatement(x, stack, stacklevel+1)
|
|
case whileLoop:
|
|
if stackoverflow {
|
|
linenum = x.line
|
|
path = x.path
|
|
code = x.code
|
|
break
|
|
}
|
|
return runWhileLoop(x, stack, stacklevel+1)
|
|
case forLoop:
|
|
if stackoverflow {
|
|
linenum = x.line
|
|
path = x.path
|
|
code = x.code
|
|
break
|
|
}
|
|
return runForLoop(x, stack, stacklevel+1)
|
|
case CreateArray:
|
|
if stackoverflow {
|
|
linenum = x.line
|
|
path = x.path
|
|
code = x.code
|
|
break
|
|
}
|
|
return runArray(x, stack, stacklevel+1)
|
|
case squareroot:
|
|
if stackoverflow {
|
|
linenum = x.line
|
|
path = x.path
|
|
code = x.code
|
|
break
|
|
}
|
|
return runSquareroot(x, stack, stacklevel+1)
|
|
case createMap:
|
|
if stackoverflow {
|
|
linenum = x.line
|
|
path = x.path
|
|
code = x.code
|
|
break
|
|
}
|
|
return runCreateMap(x, stack, stacklevel+1)
|
|
case ArImport:
|
|
if stackoverflow {
|
|
linenum = x.Line
|
|
path = x.Path
|
|
code = x.Code
|
|
break
|
|
}
|
|
return runImport(x, stack, stacklevel+1)
|
|
case ABS:
|
|
if stackoverflow {
|
|
linenum = x.line
|
|
path = x.path
|
|
code = x.code
|
|
break
|
|
}
|
|
return runAbs(x, stack, stacklevel+1)
|
|
case TryCatch:
|
|
if stackoverflow {
|
|
linenum = x.line
|
|
path = x.path
|
|
code = x.code
|
|
break
|
|
}
|
|
return runTryCatch(x, stack, stacklevel+1)
|
|
case bool, ArObject, number, nil, Callable, builtinFunc, anymap:
|
|
return x, 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))
|
|
panic("unreachable")
|
|
}
|
|
|
|
// returns error
|
|
func run(translated []any, stack stack) (any, ArErr) {
|
|
var output any = nil
|
|
for _, val := range translated {
|
|
val, err := runVal(val, stack, 0)
|
|
output = val
|
|
if err.EXISTS {
|
|
return output, err
|
|
}
|
|
}
|
|
return output, ArErr{}
|
|
}
|