mirror of
https://github.com/Open-Argon/argon-v3.git
synced 2025-12-06 00:46:07 +00:00
create logarithm functions
This commit is contained in:
@@ -24,7 +24,7 @@ func ArgonNumber(args ...any) (any, ArErr) {
|
||||
switch x := args[0].(type) {
|
||||
case string:
|
||||
if !numberCompile.MatchString(x) {
|
||||
return nil, ArErr{TYPE: "Number Error", message: "Cannot convert type '" + x + "' to a number", EXISTS: true}
|
||||
return nil, ArErr{TYPE: "Conversion Error", message: "Cannot convert " + anyToArgon(x, true, true, 3, 0, false, 0) + " to a number", EXISTS: true}
|
||||
}
|
||||
N, _ := newNumber().SetString(x)
|
||||
return N, ArErr{}
|
||||
@@ -44,7 +44,7 @@ func ArgonNumber(args ...any) (any, ArErr) {
|
||||
|
||||
func ArgonSqrt(a ...any) (any, ArErr) {
|
||||
if len(a) == 0 {
|
||||
return nil, ArErr{TYPE: "sqrt", message: "sqrt takes 1 argument",
|
||||
return nil, ArErr{TYPE: "Runtime Error", message: "sqrt takes 1 argument",
|
||||
EXISTS: true}
|
||||
}
|
||||
if typeof(a[0]) != "number" {
|
||||
@@ -55,12 +55,12 @@ func ArgonSqrt(a ...any) (any, ArErr) {
|
||||
r := a[0].(number)
|
||||
|
||||
if r.Sign() < 0 {
|
||||
return nil, ArErr{TYPE: "sqrt", message: "sqrt takes a positive number",
|
||||
return nil, ArErr{TYPE: "Runtime Error", message: "sqrt takes a positive number",
|
||||
EXISTS: true}
|
||||
}
|
||||
|
||||
var x big.Float
|
||||
x.SetPrec(30) // I didn't figure out the 'Prec' part correctly, read the docs more carefully than I did and experiement
|
||||
x.SetPrec(30)
|
||||
x.SetRat(r)
|
||||
|
||||
var s big.Float
|
||||
|
||||
@@ -66,6 +66,7 @@ func init() {
|
||||
return nil, ArErr{TYPE: "TypeError", message: "Cannot create array from '" + typeof(a[0]) + "'", EXISTS: true}
|
||||
}}
|
||||
vars["maths"] = maths
|
||||
vars["math"] = maths
|
||||
vars["time"] = ArTime
|
||||
vars["PI"] = PI
|
||||
vars["π"] = PI
|
||||
|
||||
@@ -55,7 +55,7 @@ func parseCall(code UNPARSEcode, index int, codelines []UNPARSEcode) (any, bool,
|
||||
return call{callable: callable, args: arguments, line: code.line, code: code.realcode, path: code.path}, true, ArErr{}, 1
|
||||
}
|
||||
|
||||
func runCall(c call, stack stack) (any, ArErr) {
|
||||
func runCall(c call, stack stack, stacklevel int) (any, ArErr) {
|
||||
var callable any
|
||||
switch x := c.callable.(type) {
|
||||
case builtinFunc:
|
||||
@@ -63,7 +63,7 @@ func runCall(c call, stack stack) (any, ArErr) {
|
||||
case Callable:
|
||||
callable = x
|
||||
default:
|
||||
callable_, err := runVal(c.callable, stack)
|
||||
callable_, err := runVal(c.callable, stack, stacklevel+1)
|
||||
if err.EXISTS {
|
||||
return nil, err
|
||||
}
|
||||
@@ -72,7 +72,7 @@ func runCall(c call, stack stack) (any, ArErr) {
|
||||
args := []any{}
|
||||
level := append(stack, scope{})
|
||||
for _, arg := range c.args {
|
||||
resp, err := runVal(arg, level)
|
||||
resp, err := runVal(arg, level, stacklevel+1)
|
||||
if err.EXISTS {
|
||||
return nil, err
|
||||
}
|
||||
@@ -93,7 +93,7 @@ func runCall(c call, stack stack) (any, ArErr) {
|
||||
for i, param := range x.params {
|
||||
level[param] = args[i]
|
||||
}
|
||||
resp, err := runVal(x.run, append(x.stack, level))
|
||||
resp, err := runVal(x.run, append(x.stack, level), stacklevel+1)
|
||||
return openJump(resp), err
|
||||
}
|
||||
return nil, ArErr{"Runtime Error", "type '" + typeof(callable) + "' is not callable", c.line, c.path, c.code, true}
|
||||
|
||||
@@ -48,10 +48,10 @@ func parseDoWrap(code UNPARSEcode, index int, codelines []UNPARSEcode) (any, boo
|
||||
return dowrap{run: translated, line: code.line, path: code.path, code: code.realcode}, true, ArErr{}, i - index
|
||||
}
|
||||
|
||||
func runDoWrap(d dowrap, stack stack) (any, ArErr) {
|
||||
func runDoWrap(d dowrap, stack stack, stacklevel int) (any, ArErr) {
|
||||
newstack := append(stack, scope{})
|
||||
for _, v := range d.run {
|
||||
val, err := runVal(v, newstack)
|
||||
val, err := runVal(v, newstack, stacklevel+1)
|
||||
if err.EXISTS {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -16,7 +16,7 @@ type factorial struct {
|
||||
func parseFactorial(code UNPARSEcode, index int, codeline []UNPARSEcode) (factorial, bool, ArErr, int) {
|
||||
trim := strings.TrimSpace(code.code)
|
||||
trim = trim[:len(trim)-1]
|
||||
val, success, err, i := translateVal(UNPARSEcode{code: trim, realcode: code.realcode, line: 1, path: ""}, 0, []UNPARSEcode{}, 0)
|
||||
val, success, err, i := translateVal(UNPARSEcode{code: trim, realcode: code.realcode, line: code.line, path: code.path}, index, codeline, 0)
|
||||
if !success {
|
||||
return factorial{}, false, err, i
|
||||
}
|
||||
@@ -29,7 +29,11 @@ func isFactorial(code UNPARSEcode) bool {
|
||||
}
|
||||
|
||||
func fact(n number) number {
|
||||
if n.Cmp(newNumber().SetInt64(0)) == 0 {
|
||||
if n.Cmp(newNumber().SetInt64(1000)) >= 0 {
|
||||
return infinity
|
||||
} else if n.Cmp(newNumber().SetInt64(0)) == -1 {
|
||||
return newNumber().SetInt64(0)
|
||||
} else if n.Cmp(newNumber().SetInt64(0)) == 0 {
|
||||
return newNumber().SetInt64(1)
|
||||
}
|
||||
result := newNumber().SetInt64(1)
|
||||
@@ -39,8 +43,8 @@ func fact(n number) number {
|
||||
return result
|
||||
}
|
||||
|
||||
func runFactorial(f factorial, stack stack) (any, ArErr) {
|
||||
val, err := runVal(f.value, stack)
|
||||
func runFactorial(f factorial, stack stack, stacklevel int) (any, ArErr) {
|
||||
val, err := runVal(f.value, stack, stacklevel+1)
|
||||
if err.EXISTS {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -40,10 +40,10 @@ func parseReturn(code UNPARSEcode, index int, codeline []UNPARSEcode) (CallJumpS
|
||||
}, worked, err, i
|
||||
}
|
||||
|
||||
func runJumpStatment(code CallJumpStatment, stack stack) (any, ArErr) {
|
||||
func runJumpStatment(code CallJumpStatment, stack stack, stacklevel int) (any, ArErr) {
|
||||
var val any
|
||||
if code.value != nil {
|
||||
v, err := runVal(code.value, stack)
|
||||
v, err := runVal(code.value, stack, stacklevel+1)
|
||||
if err.EXISTS {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -18,7 +18,7 @@ func getValuesFromLetter(str string, splitstr string, index int, codelines []UNP
|
||||
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, 0)
|
||||
resp, worked, _, _ := translateVal(UNPARSEcode{code: test, realcode: codelines[index].realcode, line: index, path: codelines[index].path}, index, codelines, 0)
|
||||
if worked {
|
||||
arguments = append(arguments, resp)
|
||||
temp = []string{}
|
||||
|
||||
86
src/logarithms.go
Normal file
86
src/logarithms.go
Normal file
@@ -0,0 +1,86 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"math"
|
||||
)
|
||||
|
||||
var N = newNumber().SetInt64(1e10)
|
||||
|
||||
func Ln(x number) number {
|
||||
output := newNumber()
|
||||
output.SetInt64(1)
|
||||
output.Quo(output, N)
|
||||
|
||||
n1, _ := x.Float64()
|
||||
n2, _ := output.Float64()
|
||||
output = newNumber().SetFloat64(math.Pow(n1, n2))
|
||||
if output == nil {
|
||||
output = infinity
|
||||
}
|
||||
output.Sub(output, newNumber().SetInt64(1))
|
||||
output.Mul(output, N)
|
||||
return output
|
||||
}
|
||||
|
||||
func ArgonLn(a ...any) (any, ArErr) {
|
||||
if len(a) != 0 {
|
||||
return nil, ArErr{TYPE: "Runtime Error", message: "ln takes 1 argument, got " + fmt.Sprint(len(a)),
|
||||
EXISTS: true}
|
||||
}
|
||||
if typeof(a[0]) != "number" {
|
||||
return nil, ArErr{TYPE: "Runtime Error", message: "ln takes a number not a '" + typeof(a[0]) + "'",
|
||||
EXISTS: true}
|
||||
}
|
||||
x := a[0].(number)
|
||||
if x.Sign() <= 0 {
|
||||
return nil, ArErr{TYPE: "Runtime Error", message: "ln takes a positive number",
|
||||
EXISTS: true}
|
||||
}
|
||||
return Ln(x), ArErr{}
|
||||
}
|
||||
|
||||
var __ln10 = Ln(newNumber().SetInt64(10))
|
||||
|
||||
func ArgonLog(a ...any) (any, ArErr) {
|
||||
if len(a) != 1 {
|
||||
return nil, ArErr{TYPE: "Runtime Error", message: "log takes 1 argument, got " + fmt.Sprint(len(a)),
|
||||
EXISTS: true}
|
||||
}
|
||||
if typeof(a[0]) != "number" {
|
||||
return nil, ArErr{TYPE: "Runtime Error", message: "log takes a number not a '" + typeof(a[0]) + "'",
|
||||
EXISTS: true}
|
||||
}
|
||||
x := a[0].(number)
|
||||
if x.Sign() <= 0 {
|
||||
return nil, ArErr{TYPE: "Runtime Error", message: "log takes a positive number",
|
||||
EXISTS: true}
|
||||
}
|
||||
return Ln(x).Quo(Ln(x), __ln10), ArErr{}
|
||||
}
|
||||
|
||||
func ArgonLogN(a ...any) (any, ArErr) {
|
||||
if len(a) != 2 {
|
||||
return nil, ArErr{TYPE: "Runtime Error", message: "logN takes 2 argument, got " + fmt.Sprint(len(a)),
|
||||
EXISTS: true}
|
||||
}
|
||||
if typeof(a[0]) != "number" {
|
||||
return nil, ArErr{TYPE: "Runtime Error", message: "logN takes a number not a '" + typeof(a[0]) + "'",
|
||||
EXISTS: true}
|
||||
}
|
||||
if typeof(a[1]) != "number" {
|
||||
return nil, ArErr{TYPE: "Runtime Error", message: "logN takes a number not a '" + typeof(a[0]) + "'",
|
||||
EXISTS: true}
|
||||
}
|
||||
N := a[0].(number)
|
||||
if N.Sign() <= 0 {
|
||||
return nil, ArErr{TYPE: "Runtime Error", message: "logN takes a positive number",
|
||||
EXISTS: true}
|
||||
}
|
||||
x := a[1].(number)
|
||||
if x.Sign() <= 0 {
|
||||
return nil, ArErr{TYPE: "Runtime Error", message: "logN takes a positive number",
|
||||
EXISTS: true}
|
||||
}
|
||||
return Ln(x).Quo(Ln(x), Ln(N)), ArErr{}
|
||||
}
|
||||
@@ -28,8 +28,8 @@ type ArMapGet struct {
|
||||
path string
|
||||
}
|
||||
|
||||
func mapGet(r ArMapGet, stack stack) (any, ArErr) {
|
||||
resp, err := runVal(r.VAL, stack)
|
||||
func mapGet(r ArMapGet, stack stack, stacklevel int) (any, ArErr) {
|
||||
resp, err := runVal(r.VAL, stack, stacklevel+1)
|
||||
if err.EXISTS {
|
||||
return nil, err
|
||||
}
|
||||
@@ -45,7 +45,7 @@ func mapGet(r ArMapGet, stack stack) (any, ArErr) {
|
||||
true,
|
||||
}
|
||||
}
|
||||
key, err := runVal(r.start, stack)
|
||||
key, err := runVal(r.start, stack, stacklevel+1)
|
||||
if err.EXISTS {
|
||||
return nil, err
|
||||
}
|
||||
@@ -67,7 +67,7 @@ func mapGet(r ArMapGet, stack stack) (any, ArErr) {
|
||||
step := 1
|
||||
|
||||
if !r.index {
|
||||
key, err := runVal(r.start, stack)
|
||||
key, err := runVal(r.start, stack, stacklevel+1)
|
||||
if err.EXISTS {
|
||||
return nil, err
|
||||
}
|
||||
@@ -76,7 +76,7 @@ func mapGet(r ArMapGet, stack stack) (any, ArErr) {
|
||||
}
|
||||
}
|
||||
if r.start != nil {
|
||||
sindex, err := runVal(r.start, stack)
|
||||
sindex, err := runVal(r.start, stack, stacklevel+1)
|
||||
if err.EXISTS {
|
||||
return nil, err
|
||||
}
|
||||
@@ -105,7 +105,7 @@ func mapGet(r ArMapGet, stack stack) (any, ArErr) {
|
||||
endindex = startindex + 1
|
||||
}
|
||||
if r.end != nil {
|
||||
eindex, err := runVal(r.end, stack)
|
||||
eindex, err := runVal(r.end, stack, stacklevel+1)
|
||||
if err.EXISTS {
|
||||
return nil, err
|
||||
}
|
||||
@@ -135,7 +135,7 @@ func mapGet(r ArMapGet, stack stack) (any, ArErr) {
|
||||
endindex = len(m)
|
||||
}
|
||||
if r.step != nil {
|
||||
step, err := runVal(r.step, stack)
|
||||
step, err := runVal(r.step, stack, stacklevel+1)
|
||||
if err.EXISTS {
|
||||
return nil, err
|
||||
}
|
||||
@@ -214,7 +214,7 @@ func mapGet(r ArMapGet, stack stack) (any, ArErr) {
|
||||
true,
|
||||
}
|
||||
}
|
||||
key, err := runVal(r.start, stack)
|
||||
key, err := runVal(r.start, stack, stacklevel+1)
|
||||
if err.EXISTS {
|
||||
return nil, err
|
||||
}
|
||||
@@ -235,7 +235,7 @@ func mapGet(r ArMapGet, stack stack) (any, ArErr) {
|
||||
step := 1
|
||||
|
||||
if !r.index {
|
||||
key, err := runVal(r.start, stack)
|
||||
key, err := runVal(r.start, stack, stacklevel+1)
|
||||
if err.EXISTS {
|
||||
return nil, err
|
||||
}
|
||||
@@ -244,7 +244,7 @@ func mapGet(r ArMapGet, stack stack) (any, ArErr) {
|
||||
}
|
||||
}
|
||||
if r.start != nil {
|
||||
sindex, err := runVal(r.start, stack)
|
||||
sindex, err := runVal(r.start, stack, stacklevel+1)
|
||||
if err.EXISTS {
|
||||
return nil, err
|
||||
}
|
||||
@@ -273,7 +273,7 @@ func mapGet(r ArMapGet, stack stack) (any, ArErr) {
|
||||
endindex = startindex + 1
|
||||
}
|
||||
if r.end != nil {
|
||||
eindex, err := runVal(r.end, stack)
|
||||
eindex, err := runVal(r.end, stack, stacklevel+1)
|
||||
if err.EXISTS {
|
||||
return nil, err
|
||||
}
|
||||
@@ -303,7 +303,7 @@ func mapGet(r ArMapGet, stack stack) (any, ArErr) {
|
||||
endindex = len(m)
|
||||
}
|
||||
if r.step != nil {
|
||||
step, err := runVal(r.step, stack)
|
||||
step, err := runVal(r.step, stack, stacklevel+1)
|
||||
if err.EXISTS {
|
||||
return nil, err
|
||||
}
|
||||
@@ -373,7 +373,7 @@ func mapGet(r ArMapGet, stack stack) (any, ArErr) {
|
||||
return string(([]byte(m))[startindex:endindex:step]), ArErr{}
|
||||
}
|
||||
|
||||
key, err := runVal(r.start, stack)
|
||||
key, err := runVal(r.start, stack, stacklevel+1)
|
||||
if err.EXISTS {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -61,4 +61,7 @@ var maths = ArMap{
|
||||
return nil, ArErr{TYPE: "TypeError", message: "Cannot ceil '" + typeof(a[0]) + "'", EXISTS: true}
|
||||
}},
|
||||
"sqrt": builtinFunc{"sqrt", ArgonSqrt},
|
||||
"ln": builtinFunc{"ln", ArgonLn},
|
||||
"log": builtinFunc{"log", ArgonLog},
|
||||
"logN": builtinFunc{"logN", ArgonLogN},
|
||||
}
|
||||
|
||||
@@ -105,7 +105,7 @@ func parseOperations(code UNPARSEcode, index int, codelines []UNPARSEcode) (oper
|
||||
return operationType{}, false, ArErr{}, 0
|
||||
}
|
||||
|
||||
func compareValues(o operationType, stack stack) (bool, ArErr) {
|
||||
func compareValues(o operationType, stack stack, stacklevel int) (bool, ArErr) {
|
||||
if len(o.values) != 2 {
|
||||
return false, ArErr{
|
||||
"Runtime Error",
|
||||
@@ -119,6 +119,7 @@ func compareValues(o operationType, stack stack) (bool, ArErr) {
|
||||
resp, err := runVal(
|
||||
o.values[0],
|
||||
stack,
|
||||
stacklevel+1,
|
||||
)
|
||||
resp = classVal(resp)
|
||||
if err.EXISTS {
|
||||
@@ -128,6 +129,7 @@ func compareValues(o operationType, stack stack) (bool, ArErr) {
|
||||
resp2, err := runVal(
|
||||
o.values[1],
|
||||
stack,
|
||||
stacklevel+1,
|
||||
)
|
||||
resp2 = classVal(resp2)
|
||||
if err.EXISTS {
|
||||
@@ -198,11 +200,12 @@ func compareValues(o operationType, stack stack) (bool, ArErr) {
|
||||
}
|
||||
}
|
||||
|
||||
func calcNegative(o operationType, stack stack) (number, ArErr) {
|
||||
func calcNegative(o operationType, stack stack, stacklevel int) (number, ArErr) {
|
||||
|
||||
resp, err := runVal(
|
||||
o.values[0],
|
||||
stack,
|
||||
stacklevel+1,
|
||||
)
|
||||
resp = classVal(resp)
|
||||
if err.EXISTS {
|
||||
@@ -223,6 +226,7 @@ func calcNegative(o operationType, stack stack) (number, ArErr) {
|
||||
resp, err := runVal(
|
||||
o.values[i],
|
||||
stack,
|
||||
stacklevel+1,
|
||||
)
|
||||
resp = classVal(resp)
|
||||
if err.EXISTS {
|
||||
@@ -244,11 +248,12 @@ func calcNegative(o operationType, stack stack) (number, ArErr) {
|
||||
return output, ArErr{}
|
||||
}
|
||||
|
||||
func calcDivide(o operationType, stack stack) (number, ArErr) {
|
||||
func calcDivide(o operationType, stack stack, stacklevel int) (number, ArErr) {
|
||||
|
||||
resp, err := runVal(
|
||||
o.values[0],
|
||||
stack,
|
||||
stacklevel+1,
|
||||
)
|
||||
resp = classVal(resp)
|
||||
if err.EXISTS {
|
||||
@@ -269,6 +274,7 @@ func calcDivide(o operationType, stack stack) (number, ArErr) {
|
||||
resp, err := runVal(
|
||||
o.values[i],
|
||||
stack,
|
||||
stacklevel+1,
|
||||
)
|
||||
resp = classVal(resp)
|
||||
if err.EXISTS {
|
||||
@@ -290,11 +296,12 @@ func calcDivide(o operationType, stack stack) (number, ArErr) {
|
||||
return output, ArErr{}
|
||||
}
|
||||
|
||||
func calcAdd(o operationType, stack stack) (any, ArErr) {
|
||||
func calcAdd(o operationType, stack stack, stacklevel int) (any, ArErr) {
|
||||
|
||||
resp, err := runVal(
|
||||
o.values[0],
|
||||
stack,
|
||||
stacklevel+1,
|
||||
)
|
||||
resp = classVal(resp)
|
||||
if err.EXISTS {
|
||||
@@ -310,6 +317,7 @@ func calcAdd(o operationType, stack stack) (any, ArErr) {
|
||||
resp, err := runVal(
|
||||
o.values[i],
|
||||
stack,
|
||||
stacklevel+1,
|
||||
)
|
||||
resp = classVal(resp)
|
||||
if err.EXISTS {
|
||||
@@ -328,11 +336,12 @@ func calcAdd(o operationType, stack stack) (any, ArErr) {
|
||||
return output, ArErr{}
|
||||
}
|
||||
|
||||
func calcMul(o operationType, stack stack) (any, ArErr) {
|
||||
func calcMul(o operationType, stack stack, stacklevel int) (any, ArErr) {
|
||||
|
||||
resp, err := runVal(
|
||||
o.values[0],
|
||||
stack,
|
||||
stacklevel+1,
|
||||
)
|
||||
resp = classVal(resp)
|
||||
if err.EXISTS {
|
||||
@@ -348,6 +357,7 @@ func calcMul(o operationType, stack stack) (any, ArErr) {
|
||||
resp, err := runVal(
|
||||
o.values[i],
|
||||
stack,
|
||||
stacklevel+1,
|
||||
)
|
||||
resp = classVal(resp)
|
||||
if err.EXISTS {
|
||||
@@ -375,12 +385,13 @@ func calcMul(o operationType, stack stack) (any, ArErr) {
|
||||
return output, ArErr{}
|
||||
}
|
||||
|
||||
func calcAnd(o operationType, stack stack) (any, ArErr) {
|
||||
func calcAnd(o operationType, stack stack, stacklevel int) (any, ArErr) {
|
||||
var output any = false
|
||||
for i := 0; i < len(o.values); i++ {
|
||||
resp, err := runVal(
|
||||
o.values[i],
|
||||
stack,
|
||||
stacklevel+1,
|
||||
)
|
||||
resp = classVal(resp)
|
||||
if err.EXISTS {
|
||||
@@ -394,12 +405,13 @@ func calcAnd(o operationType, stack stack) (any, ArErr) {
|
||||
return output, ArErr{}
|
||||
}
|
||||
|
||||
func calcOr(o operationType, stack stack) (any, ArErr) {
|
||||
func calcOr(o operationType, stack stack, stacklevel int) (any, ArErr) {
|
||||
var output any = false
|
||||
for i := 0; i < len(o.values); i++ {
|
||||
resp, err := runVal(
|
||||
o.values[i],
|
||||
stack,
|
||||
stacklevel+1,
|
||||
)
|
||||
resp = classVal(resp)
|
||||
if err.EXISTS {
|
||||
@@ -422,7 +434,7 @@ func stringInSlice(a any, list []any) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func calcIn(o operationType, stack stack) (bool, ArErr) {
|
||||
func calcIn(o operationType, stack stack, stacklevel int) (bool, ArErr) {
|
||||
if len(o.values) != 2 {
|
||||
return false, ArErr{
|
||||
"Runtime Error",
|
||||
@@ -436,6 +448,7 @@ func calcIn(o operationType, stack stack) (bool, ArErr) {
|
||||
resp, err := runVal(
|
||||
o.values[0],
|
||||
stack,
|
||||
stacklevel+1,
|
||||
)
|
||||
resp = classVal(resp)
|
||||
if err.EXISTS {
|
||||
@@ -445,6 +458,7 @@ func calcIn(o operationType, stack stack) (bool, ArErr) {
|
||||
resp2, err := runVal(
|
||||
o.values[1],
|
||||
stack,
|
||||
stacklevel+1,
|
||||
)
|
||||
resp2 = classVal(resp2)
|
||||
if err.EXISTS {
|
||||
@@ -481,10 +495,11 @@ func equals(a any, b any) bool {
|
||||
return reflect.DeepEqual(a, b)
|
||||
}
|
||||
|
||||
func calcMod(o operationType, stack stack) (number, ArErr) {
|
||||
func calcMod(o operationType, stack stack, stacklevel int) (number, ArErr) {
|
||||
resp, err := runVal(
|
||||
o.values[0],
|
||||
stack,
|
||||
stacklevel+1,
|
||||
)
|
||||
resp = classVal(resp)
|
||||
if err.EXISTS {
|
||||
@@ -505,6 +520,7 @@ func calcMod(o operationType, stack stack) (number, ArErr) {
|
||||
resp, err := runVal(
|
||||
o.values[i],
|
||||
stack,
|
||||
stacklevel+1,
|
||||
)
|
||||
resp = classVal(resp)
|
||||
if err.EXISTS {
|
||||
@@ -528,17 +544,18 @@ func calcMod(o operationType, stack stack) (number, ArErr) {
|
||||
return output, ArErr{}
|
||||
}
|
||||
|
||||
func calcIntDiv(o operationType, stack stack) (number, ArErr) {
|
||||
resp, err := calcDivide(o, stack)
|
||||
func calcIntDiv(o operationType, stack stack, stacklevel int) (number, ArErr) {
|
||||
resp, err := calcDivide(o, stack, stacklevel+1)
|
||||
x, _ := resp.Float64()
|
||||
resp = newNumber().SetFloat64(math.Trunc(x))
|
||||
return resp, err
|
||||
}
|
||||
|
||||
func calcPower(o operationType, stack stack) (number, ArErr) {
|
||||
func calcPower(o operationType, stack stack, stacklevel int) (number, ArErr) {
|
||||
resp, err := runVal(
|
||||
o.values[0],
|
||||
stack,
|
||||
stacklevel+1,
|
||||
)
|
||||
resp = classVal(resp)
|
||||
if err.EXISTS {
|
||||
@@ -559,6 +576,7 @@ func calcPower(o operationType, stack stack) (number, ArErr) {
|
||||
resp, err := runVal(
|
||||
o.values[i],
|
||||
stack,
|
||||
stacklevel+1,
|
||||
)
|
||||
resp = classVal(resp)
|
||||
if err.EXISTS {
|
||||
@@ -585,44 +603,44 @@ func calcPower(o operationType, stack stack) (number, ArErr) {
|
||||
return output, ArErr{}
|
||||
}
|
||||
|
||||
func runOperation(o operationType, stack stack) (any, ArErr) {
|
||||
func runOperation(o operationType, stack stack, stacklevel int) (any, ArErr) {
|
||||
switch o.operation {
|
||||
case 0:
|
||||
return calcAnd(o, stack)
|
||||
return calcAnd(o, stack, stacklevel+1)
|
||||
case 1:
|
||||
return calcOr(o, stack)
|
||||
return calcOr(o, stack, stacklevel+1)
|
||||
case 2:
|
||||
resp, err := calcIn(o, stack)
|
||||
resp, err := calcIn(o, stack, stacklevel+1)
|
||||
resp = !resp
|
||||
return resp, err
|
||||
case 3:
|
||||
return calcIn(o, stack)
|
||||
return calcIn(o, stack, stacklevel+1)
|
||||
case 4:
|
||||
return compareValues(o, stack)
|
||||
return compareValues(o, stack, stacklevel+1)
|
||||
case 5:
|
||||
return compareValues(o, stack)
|
||||
return compareValues(o, stack, stacklevel+1)
|
||||
case 6:
|
||||
return compareValues(o, stack)
|
||||
return compareValues(o, stack, stacklevel+1)
|
||||
case 7:
|
||||
return compareValues(o, stack)
|
||||
return compareValues(o, stack, stacklevel+1)
|
||||
case 8:
|
||||
return compareValues(o, stack)
|
||||
return compareValues(o, stack, stacklevel+1)
|
||||
case 9:
|
||||
return compareValues(o, stack)
|
||||
return compareValues(o, stack, stacklevel+1)
|
||||
case 10:
|
||||
return calcAdd(o, stack)
|
||||
return calcAdd(o, stack, stacklevel+1)
|
||||
case 11:
|
||||
return calcNegative(o, stack)
|
||||
return calcNegative(o, stack, stacklevel+1)
|
||||
case 12:
|
||||
return calcMul(o, stack)
|
||||
return calcMul(o, stack, stacklevel+1)
|
||||
case 13:
|
||||
return calcMod(o, stack)
|
||||
return calcMod(o, stack, stacklevel+1)
|
||||
case 14:
|
||||
return calcIntDiv(o, stack)
|
||||
return calcIntDiv(o, stack, stacklevel+1)
|
||||
case 15:
|
||||
return calcDivide(o, stack)
|
||||
return calcDivide(o, stack, stacklevel+1)
|
||||
case 16:
|
||||
return calcPower(o, stack)
|
||||
return calcPower(o, stack, stacklevel+1)
|
||||
|
||||
}
|
||||
panic("Unknown operation: " + fmt.Sprint(o.operation))
|
||||
|
||||
33
src/run.go
33
src/run.go
@@ -6,11 +6,14 @@ import (
|
||||
)
|
||||
|
||||
// returns (number|string|nil), error
|
||||
func runVal(line any, stack stack) (any, ArErr) {
|
||||
if len(stack) > 500 {
|
||||
func runVal(line any, stack stack, stacklevel int) (any, ArErr) {
|
||||
if stacklevel > 10000 {
|
||||
return nil, ArErr{
|
||||
TYPE: "Stack overflow",
|
||||
message: "the stack has exceeded 500 levels",
|
||||
TYPE: "RuntimeError",
|
||||
message: "stack overflow",
|
||||
line: 0,
|
||||
path: "",
|
||||
code: "",
|
||||
EXISTS: true,
|
||||
}
|
||||
}
|
||||
@@ -20,19 +23,19 @@ func runVal(line any, stack stack) (any, ArErr) {
|
||||
case string:
|
||||
return x, ArErr{}
|
||||
case call:
|
||||
return runCall(x, stack)
|
||||
return runCall(x, stack, stacklevel+1)
|
||||
case factorial:
|
||||
return runFactorial(x, stack)
|
||||
return runFactorial(x, stack, stacklevel+1)
|
||||
case accessVariable:
|
||||
return readVariable(x, stack)
|
||||
case ArMapGet:
|
||||
return mapGet(x, stack)
|
||||
return mapGet(x, stack, stacklevel+1)
|
||||
case ArClass:
|
||||
return x.MAP, ArErr{}
|
||||
case setVariable:
|
||||
return setVariableValue(x, stack)
|
||||
return setVariableValue(x, stack, stacklevel+1)
|
||||
case negative:
|
||||
resp, err := runVal(x.VAL, stack)
|
||||
resp, err := runVal(x.VAL, stack, stacklevel+1)
|
||||
resp = classVal(resp)
|
||||
if err.EXISTS {
|
||||
return nil, err
|
||||
@@ -47,15 +50,15 @@ func runVal(line any, stack stack) (any, ArErr) {
|
||||
EXISTS: true,
|
||||
}
|
||||
case brackets:
|
||||
return runVal(x.VAL, stack)
|
||||
return runVal(x.VAL, stack, stacklevel+1)
|
||||
case operationType:
|
||||
return runOperation(x, stack)
|
||||
return runOperation(x, stack, stacklevel+1)
|
||||
case dowrap:
|
||||
return runDoWrap(x, stack)
|
||||
return runDoWrap(x, stack, stacklevel+1)
|
||||
case CallJumpStatment:
|
||||
return runJumpStatment(x, stack)
|
||||
return runJumpStatment(x, stack, stacklevel+1)
|
||||
case ArDelete:
|
||||
return runDelete(x, stack)
|
||||
return runDelete(x, stack, stacklevel+1)
|
||||
}
|
||||
fmt.Println("unreachable", reflect.TypeOf(line))
|
||||
panic("unreachable")
|
||||
@@ -65,7 +68,7 @@ func runVal(line any, stack stack) (any, ArErr) {
|
||||
func run(translated []any, stack stack) (any, ArErr, any) {
|
||||
var output any = nil
|
||||
for _, val := range translated {
|
||||
val, err := runVal(val, stack)
|
||||
val, err := runVal(val, stack, 0)
|
||||
output = val
|
||||
if err.EXISTS {
|
||||
return nil, err, output
|
||||
|
||||
22
src/shell.go
22
src/shell.go
@@ -6,6 +6,12 @@ import (
|
||||
"os/signal"
|
||||
)
|
||||
|
||||
var endingWithDoCompiled = makeRegex(`.*do( )*`)
|
||||
|
||||
func isEndingWithDo(str string) bool {
|
||||
return endingWithDoCompiled.MatchString(str)
|
||||
}
|
||||
|
||||
func shell() {
|
||||
global := stack{vars, scope{}}
|
||||
c := make(chan os.Signal, 1)
|
||||
@@ -19,9 +25,23 @@ func shell() {
|
||||
}
|
||||
}()
|
||||
for {
|
||||
indo := false
|
||||
totranslate := []UNPARSEcode{}
|
||||
code := input("\x1b[38;5;240m>>> \x1b[0m\x1b[1;5;240m")
|
||||
fmt.Print("\x1b[0m")
|
||||
translated, translationerr := translate([]UNPARSEcode{{code, code, 1, "<shell>"}})
|
||||
if isEndingWithDo(code) {
|
||||
indo = true
|
||||
}
|
||||
totranslate = append(totranslate, UNPARSEcode{code, code, 1, "<shell>"})
|
||||
for i := 2; indo; i++ {
|
||||
code := input("\x1b[38;5;240m... \x1b[0m\x1b[1;5;240m")
|
||||
fmt.Print("\x1b[0m")
|
||||
totranslate = append(totranslate, UNPARSEcode{code, code, i, "<shell>"})
|
||||
if code == "" {
|
||||
indo = false
|
||||
}
|
||||
}
|
||||
translated, translationerr := translate(totranslate)
|
||||
count := len(translated)
|
||||
if translationerr.EXISTS {
|
||||
panicErr(translationerr)
|
||||
|
||||
@@ -29,7 +29,7 @@ func ArThread(args ...any) (any, ArErr) {
|
||||
hasrun = true
|
||||
wg.Add(1)
|
||||
go func() {
|
||||
resp, err = runCall(call{tocall, []any{}, "", 0, ""}, currentscope)
|
||||
resp, err = runCall(call{tocall, []any{}, "", 0, ""}, currentscope, 0)
|
||||
wg.Done()
|
||||
}()
|
||||
return nil, ArErr{}
|
||||
|
||||
@@ -96,6 +96,10 @@ func translate(codelines []UNPARSEcode) ([]any, ArErr) {
|
||||
return nil, ArErr{"Syntax Error", "invalid indent", codelines[i].line, codelines[i].path, codelines[i].realcode, true}
|
||||
}
|
||||
val, _, err, step := translateVal(codelines[i], i, codelines, 2)
|
||||
switch val.(type) {
|
||||
case CallJumpStatment:
|
||||
return nil, ArErr{"Runtime Error", "Jump statment at top level", codelines[i].line, codelines[i].path, codelines[i].realcode, true}
|
||||
}
|
||||
i += step
|
||||
if err.EXISTS {
|
||||
return nil, err
|
||||
|
||||
@@ -184,12 +184,12 @@ func parseAutoAsignVariable(code UNPARSEcode, index int, lines []UNPARSEcode, is
|
||||
return setVariable{TYPE: "auto", toset: toset, value: value, function: function, params: params, line: code.line, code: code.code, path: code.path}, true, ArErr{}, i + namei - 1
|
||||
}
|
||||
|
||||
func setVariableValue(v setVariable, stack stack) (any, ArErr) {
|
||||
func setVariableValue(v setVariable, stack stack, stacklevel int) (any, ArErr) {
|
||||
var resp any
|
||||
if v.function {
|
||||
resp = Callable{v.params, v.value, v.code, stack, v.line}
|
||||
} else {
|
||||
respp, err := runVal(v.value, stack)
|
||||
respp, err := runVal(v.value, stack, stacklevel+1)
|
||||
if err.EXISTS {
|
||||
return nil, err
|
||||
}
|
||||
@@ -212,11 +212,11 @@ func setVariableValue(v setVariable, stack stack) (any, ArErr) {
|
||||
}
|
||||
stack[len(stack)-1][x.name] = resp
|
||||
case ArMapGet:
|
||||
respp, err := runVal(x.VAL, stack)
|
||||
respp, err := runVal(x.VAL, stack, stacklevel+1)
|
||||
if err.EXISTS {
|
||||
return nil, err
|
||||
}
|
||||
key, err := runVal(x.start, stack)
|
||||
key, err := runVal(x.start, stack, stacklevel+1)
|
||||
if err.EXISTS {
|
||||
return nil, err
|
||||
}
|
||||
@@ -251,7 +251,7 @@ func parseDelete(code UNPARSEcode, index int, lines []UNPARSEcode) (ArDelete, bo
|
||||
}, true, ArErr{}, i
|
||||
}
|
||||
|
||||
func runDelete(d ArDelete, stack stack) (any, ArErr) {
|
||||
func runDelete(d ArDelete, stack stack, stacklevel int) (any, ArErr) {
|
||||
switch x := d.value.(type) {
|
||||
case accessVariable:
|
||||
for i := len(stack) - 1; i >= 0; i-- {
|
||||
@@ -262,11 +262,11 @@ func runDelete(d ArDelete, stack stack) (any, ArErr) {
|
||||
}
|
||||
return nil, ArErr{"Runtime Error", "variable \"" + x.name + "\" does not exist", d.line, d.path, d.code, true}
|
||||
case ArMapGet:
|
||||
respp, err := runVal(x.VAL, stack)
|
||||
respp, err := runVal(x.VAL, stack, stacklevel+1)
|
||||
if err.EXISTS {
|
||||
return nil, err
|
||||
}
|
||||
key, err := runVal(x.start, stack)
|
||||
key, err := runVal(x.start, stack, stacklevel+1)
|
||||
if err.EXISTS {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
17
test.ar
17
test.ar
@@ -1,6 +1,13 @@
|
||||
f(x) = do
|
||||
y = number(input("what number? "))
|
||||
return (z) = do
|
||||
return maths.round(z) * y * x
|
||||
let ln(x) = do
|
||||
let n = 1e10
|
||||
return n * ((x^(1/n)) - 1)
|
||||
|
||||
term.log(f(5)(70))
|
||||
let __ln10cache = ln(10)
|
||||
|
||||
let log(x) = do
|
||||
return ln(x) / __ln10cache
|
||||
|
||||
let logN(n,x) = do
|
||||
return ln(x) / ln(n)
|
||||
|
||||
term.log(log(1000))
|
||||
Reference in New Issue
Block a user