create logarithm functions

This commit is contained in:
2023-03-11 12:22:33 +00:00
parent f5d8eb6d70
commit 42de489ca5
17 changed files with 235 additions and 89 deletions

View File

@@ -24,7 +24,7 @@ func ArgonNumber(args ...any) (any, ArErr) {
switch x := args[0].(type) { switch x := args[0].(type) {
case string: case string:
if !numberCompile.MatchString(x) { 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) N, _ := newNumber().SetString(x)
return N, ArErr{} return N, ArErr{}
@@ -44,7 +44,7 @@ func ArgonNumber(args ...any) (any, ArErr) {
func ArgonSqrt(a ...any) (any, ArErr) { func ArgonSqrt(a ...any) (any, ArErr) {
if len(a) == 0 { 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} EXISTS: true}
} }
if typeof(a[0]) != "number" { if typeof(a[0]) != "number" {
@@ -55,12 +55,12 @@ func ArgonSqrt(a ...any) (any, ArErr) {
r := a[0].(number) r := a[0].(number)
if r.Sign() < 0 { 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} EXISTS: true}
} }
var x big.Float 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) x.SetRat(r)
var s big.Float var s big.Float

View File

@@ -66,6 +66,7 @@ func init() {
return nil, ArErr{TYPE: "TypeError", message: "Cannot create array from '" + typeof(a[0]) + "'", EXISTS: true} return nil, ArErr{TYPE: "TypeError", message: "Cannot create array from '" + typeof(a[0]) + "'", EXISTS: true}
}} }}
vars["maths"] = maths vars["maths"] = maths
vars["math"] = maths
vars["time"] = ArTime vars["time"] = ArTime
vars["PI"] = PI vars["PI"] = PI
vars["π"] = PI vars["π"] = PI

View File

@@ -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 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 var callable any
switch x := c.callable.(type) { switch x := c.callable.(type) {
case builtinFunc: case builtinFunc:
@@ -63,7 +63,7 @@ func runCall(c call, stack stack) (any, ArErr) {
case Callable: case Callable:
callable = x callable = x
default: default:
callable_, err := runVal(c.callable, stack) callable_, err := runVal(c.callable, stack, stacklevel+1)
if err.EXISTS { if err.EXISTS {
return nil, err return nil, err
} }
@@ -72,7 +72,7 @@ func runCall(c call, stack stack) (any, ArErr) {
args := []any{} args := []any{}
level := append(stack, scope{}) level := append(stack, scope{})
for _, arg := range c.args { for _, arg := range c.args {
resp, err := runVal(arg, level) resp, err := runVal(arg, level, stacklevel+1)
if err.EXISTS { if err.EXISTS {
return nil, err return nil, err
} }
@@ -93,7 +93,7 @@ func runCall(c call, stack stack) (any, ArErr) {
for i, param := range x.params { for i, param := range x.params {
level[param] = args[i] 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 openJump(resp), err
} }
return nil, ArErr{"Runtime Error", "type '" + typeof(callable) + "' is not callable", c.line, c.path, c.code, true} return nil, ArErr{"Runtime Error", "type '" + typeof(callable) + "' is not callable", c.line, c.path, c.code, true}

View File

@@ -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 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{}) newstack := append(stack, scope{})
for _, v := range d.run { for _, v := range d.run {
val, err := runVal(v, newstack) val, err := runVal(v, newstack, stacklevel+1)
if err.EXISTS { if err.EXISTS {
return nil, err return nil, err
} }

View File

@@ -16,7 +16,7 @@ type factorial struct {
func parseFactorial(code UNPARSEcode, index int, codeline []UNPARSEcode) (factorial, bool, ArErr, int) { func parseFactorial(code UNPARSEcode, index int, codeline []UNPARSEcode) (factorial, bool, ArErr, int) {
trim := strings.TrimSpace(code.code) trim := strings.TrimSpace(code.code)
trim = trim[:len(trim)-1] 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 { if !success {
return factorial{}, false, err, i return factorial{}, false, err, i
} }
@@ -29,7 +29,11 @@ func isFactorial(code UNPARSEcode) bool {
} }
func fact(n number) number { 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) return newNumber().SetInt64(1)
} }
result := newNumber().SetInt64(1) result := newNumber().SetInt64(1)
@@ -39,8 +43,8 @@ func fact(n number) number {
return result return result
} }
func runFactorial(f factorial, stack stack) (any, ArErr) { func runFactorial(f factorial, stack stack, stacklevel int) (any, ArErr) {
val, err := runVal(f.value, stack) val, err := runVal(f.value, stack, stacklevel+1)
if err.EXISTS { if err.EXISTS {
return nil, err return nil, err
} }

View File

@@ -40,10 +40,10 @@ func parseReturn(code UNPARSEcode, index int, codeline []UNPARSEcode) (CallJumpS
}, worked, err, i }, worked, err, i
} }
func runJumpStatment(code CallJumpStatment, stack stack) (any, ArErr) { func runJumpStatment(code CallJumpStatment, stack stack, stacklevel int) (any, ArErr) {
var val any var val any
if code.value != nil { if code.value != nil {
v, err := runVal(code.value, stack) v, err := runVal(code.value, stack, stacklevel+1)
if err.EXISTS { if err.EXISTS {
return nil, err return nil, err
} }

View File

@@ -18,7 +18,7 @@ func getValuesFromLetter(str string, splitstr string, index int, codelines []UNP
arguments = append(arguments, nil) arguments = append(arguments, nil)
temp = []string{} temp = []string{}
} else { } 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 { if worked {
arguments = append(arguments, resp) arguments = append(arguments, resp)
temp = []string{} temp = []string{}

86
src/logarithms.go Normal file
View 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{}
}

View File

@@ -28,8 +28,8 @@ type ArMapGet struct {
path string path string
} }
func mapGet(r ArMapGet, stack stack) (any, ArErr) { func mapGet(r ArMapGet, stack stack, stacklevel int) (any, ArErr) {
resp, err := runVal(r.VAL, stack) resp, err := runVal(r.VAL, stack, stacklevel+1)
if err.EXISTS { if err.EXISTS {
return nil, err return nil, err
} }
@@ -45,7 +45,7 @@ func mapGet(r ArMapGet, stack stack) (any, ArErr) {
true, true,
} }
} }
key, err := runVal(r.start, stack) key, err := runVal(r.start, stack, stacklevel+1)
if err.EXISTS { if err.EXISTS {
return nil, err return nil, err
} }
@@ -67,7 +67,7 @@ func mapGet(r ArMapGet, stack stack) (any, ArErr) {
step := 1 step := 1
if !r.index { if !r.index {
key, err := runVal(r.start, stack) key, err := runVal(r.start, stack, stacklevel+1)
if err.EXISTS { if err.EXISTS {
return nil, err return nil, err
} }
@@ -76,7 +76,7 @@ func mapGet(r ArMapGet, stack stack) (any, ArErr) {
} }
} }
if r.start != nil { if r.start != nil {
sindex, err := runVal(r.start, stack) sindex, err := runVal(r.start, stack, stacklevel+1)
if err.EXISTS { if err.EXISTS {
return nil, err return nil, err
} }
@@ -105,7 +105,7 @@ func mapGet(r ArMapGet, stack stack) (any, ArErr) {
endindex = startindex + 1 endindex = startindex + 1
} }
if r.end != nil { if r.end != nil {
eindex, err := runVal(r.end, stack) eindex, err := runVal(r.end, stack, stacklevel+1)
if err.EXISTS { if err.EXISTS {
return nil, err return nil, err
} }
@@ -135,7 +135,7 @@ func mapGet(r ArMapGet, stack stack) (any, ArErr) {
endindex = len(m) endindex = len(m)
} }
if r.step != nil { if r.step != nil {
step, err := runVal(r.step, stack) step, err := runVal(r.step, stack, stacklevel+1)
if err.EXISTS { if err.EXISTS {
return nil, err return nil, err
} }
@@ -214,7 +214,7 @@ func mapGet(r ArMapGet, stack stack) (any, ArErr) {
true, true,
} }
} }
key, err := runVal(r.start, stack) key, err := runVal(r.start, stack, stacklevel+1)
if err.EXISTS { if err.EXISTS {
return nil, err return nil, err
} }
@@ -235,7 +235,7 @@ func mapGet(r ArMapGet, stack stack) (any, ArErr) {
step := 1 step := 1
if !r.index { if !r.index {
key, err := runVal(r.start, stack) key, err := runVal(r.start, stack, stacklevel+1)
if err.EXISTS { if err.EXISTS {
return nil, err return nil, err
} }
@@ -244,7 +244,7 @@ func mapGet(r ArMapGet, stack stack) (any, ArErr) {
} }
} }
if r.start != nil { if r.start != nil {
sindex, err := runVal(r.start, stack) sindex, err := runVal(r.start, stack, stacklevel+1)
if err.EXISTS { if err.EXISTS {
return nil, err return nil, err
} }
@@ -273,7 +273,7 @@ func mapGet(r ArMapGet, stack stack) (any, ArErr) {
endindex = startindex + 1 endindex = startindex + 1
} }
if r.end != nil { if r.end != nil {
eindex, err := runVal(r.end, stack) eindex, err := runVal(r.end, stack, stacklevel+1)
if err.EXISTS { if err.EXISTS {
return nil, err return nil, err
} }
@@ -303,7 +303,7 @@ func mapGet(r ArMapGet, stack stack) (any, ArErr) {
endindex = len(m) endindex = len(m)
} }
if r.step != nil { if r.step != nil {
step, err := runVal(r.step, stack) step, err := runVal(r.step, stack, stacklevel+1)
if err.EXISTS { if err.EXISTS {
return nil, err return nil, err
} }
@@ -373,7 +373,7 @@ func mapGet(r ArMapGet, stack stack) (any, ArErr) {
return string(([]byte(m))[startindex:endindex:step]), 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 { if err.EXISTS {
return nil, err return nil, err
} }

View File

@@ -61,4 +61,7 @@ var maths = ArMap{
return nil, ArErr{TYPE: "TypeError", message: "Cannot ceil '" + typeof(a[0]) + "'", EXISTS: true} return nil, ArErr{TYPE: "TypeError", message: "Cannot ceil '" + typeof(a[0]) + "'", EXISTS: true}
}}, }},
"sqrt": builtinFunc{"sqrt", ArgonSqrt}, "sqrt": builtinFunc{"sqrt", ArgonSqrt},
"ln": builtinFunc{"ln", ArgonLn},
"log": builtinFunc{"log", ArgonLog},
"logN": builtinFunc{"logN", ArgonLogN},
} }

View File

@@ -105,7 +105,7 @@ func parseOperations(code UNPARSEcode, index int, codelines []UNPARSEcode) (oper
return operationType{}, false, ArErr{}, 0 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 { if len(o.values) != 2 {
return false, ArErr{ return false, ArErr{
"Runtime Error", "Runtime Error",
@@ -119,6 +119,7 @@ func compareValues(o operationType, stack stack) (bool, ArErr) {
resp, err := runVal( resp, err := runVal(
o.values[0], o.values[0],
stack, stack,
stacklevel+1,
) )
resp = classVal(resp) resp = classVal(resp)
if err.EXISTS { if err.EXISTS {
@@ -128,6 +129,7 @@ func compareValues(o operationType, stack stack) (bool, ArErr) {
resp2, err := runVal( resp2, err := runVal(
o.values[1], o.values[1],
stack, stack,
stacklevel+1,
) )
resp2 = classVal(resp2) resp2 = classVal(resp2)
if err.EXISTS { 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( resp, err := runVal(
o.values[0], o.values[0],
stack, stack,
stacklevel+1,
) )
resp = classVal(resp) resp = classVal(resp)
if err.EXISTS { if err.EXISTS {
@@ -223,6 +226,7 @@ func calcNegative(o operationType, stack stack) (number, ArErr) {
resp, err := runVal( resp, err := runVal(
o.values[i], o.values[i],
stack, stack,
stacklevel+1,
) )
resp = classVal(resp) resp = classVal(resp)
if err.EXISTS { if err.EXISTS {
@@ -244,11 +248,12 @@ func calcNegative(o operationType, stack stack) (number, ArErr) {
return output, 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( resp, err := runVal(
o.values[0], o.values[0],
stack, stack,
stacklevel+1,
) )
resp = classVal(resp) resp = classVal(resp)
if err.EXISTS { if err.EXISTS {
@@ -269,6 +274,7 @@ func calcDivide(o operationType, stack stack) (number, ArErr) {
resp, err := runVal( resp, err := runVal(
o.values[i], o.values[i],
stack, stack,
stacklevel+1,
) )
resp = classVal(resp) resp = classVal(resp)
if err.EXISTS { if err.EXISTS {
@@ -290,11 +296,12 @@ func calcDivide(o operationType, stack stack) (number, ArErr) {
return output, 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( resp, err := runVal(
o.values[0], o.values[0],
stack, stack,
stacklevel+1,
) )
resp = classVal(resp) resp = classVal(resp)
if err.EXISTS { if err.EXISTS {
@@ -310,6 +317,7 @@ func calcAdd(o operationType, stack stack) (any, ArErr) {
resp, err := runVal( resp, err := runVal(
o.values[i], o.values[i],
stack, stack,
stacklevel+1,
) )
resp = classVal(resp) resp = classVal(resp)
if err.EXISTS { if err.EXISTS {
@@ -328,11 +336,12 @@ func calcAdd(o operationType, stack stack) (any, ArErr) {
return output, 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( resp, err := runVal(
o.values[0], o.values[0],
stack, stack,
stacklevel+1,
) )
resp = classVal(resp) resp = classVal(resp)
if err.EXISTS { if err.EXISTS {
@@ -348,6 +357,7 @@ func calcMul(o operationType, stack stack) (any, ArErr) {
resp, err := runVal( resp, err := runVal(
o.values[i], o.values[i],
stack, stack,
stacklevel+1,
) )
resp = classVal(resp) resp = classVal(resp)
if err.EXISTS { if err.EXISTS {
@@ -375,12 +385,13 @@ func calcMul(o operationType, stack stack) (any, ArErr) {
return output, 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 var output any = false
for i := 0; i < len(o.values); i++ { for i := 0; i < len(o.values); i++ {
resp, err := runVal( resp, err := runVal(
o.values[i], o.values[i],
stack, stack,
stacklevel+1,
) )
resp = classVal(resp) resp = classVal(resp)
if err.EXISTS { if err.EXISTS {
@@ -394,12 +405,13 @@ func calcAnd(o operationType, stack stack) (any, ArErr) {
return output, 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 var output any = false
for i := 0; i < len(o.values); i++ { for i := 0; i < len(o.values); i++ {
resp, err := runVal( resp, err := runVal(
o.values[i], o.values[i],
stack, stack,
stacklevel+1,
) )
resp = classVal(resp) resp = classVal(resp)
if err.EXISTS { if err.EXISTS {
@@ -422,7 +434,7 @@ func stringInSlice(a any, list []any) bool {
return false 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 { if len(o.values) != 2 {
return false, ArErr{ return false, ArErr{
"Runtime Error", "Runtime Error",
@@ -436,6 +448,7 @@ func calcIn(o operationType, stack stack) (bool, ArErr) {
resp, err := runVal( resp, err := runVal(
o.values[0], o.values[0],
stack, stack,
stacklevel+1,
) )
resp = classVal(resp) resp = classVal(resp)
if err.EXISTS { if err.EXISTS {
@@ -445,6 +458,7 @@ func calcIn(o operationType, stack stack) (bool, ArErr) {
resp2, err := runVal( resp2, err := runVal(
o.values[1], o.values[1],
stack, stack,
stacklevel+1,
) )
resp2 = classVal(resp2) resp2 = classVal(resp2)
if err.EXISTS { if err.EXISTS {
@@ -481,10 +495,11 @@ func equals(a any, b any) bool {
return reflect.DeepEqual(a, b) 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( resp, err := runVal(
o.values[0], o.values[0],
stack, stack,
stacklevel+1,
) )
resp = classVal(resp) resp = classVal(resp)
if err.EXISTS { if err.EXISTS {
@@ -505,6 +520,7 @@ func calcMod(o operationType, stack stack) (number, ArErr) {
resp, err := runVal( resp, err := runVal(
o.values[i], o.values[i],
stack, stack,
stacklevel+1,
) )
resp = classVal(resp) resp = classVal(resp)
if err.EXISTS { if err.EXISTS {
@@ -528,17 +544,18 @@ func calcMod(o operationType, stack stack) (number, ArErr) {
return output, ArErr{} return output, ArErr{}
} }
func calcIntDiv(o operationType, stack stack) (number, ArErr) { func calcIntDiv(o operationType, stack stack, stacklevel int) (number, ArErr) {
resp, err := calcDivide(o, stack) resp, err := calcDivide(o, stack, stacklevel+1)
x, _ := resp.Float64() x, _ := resp.Float64()
resp = newNumber().SetFloat64(math.Trunc(x)) resp = newNumber().SetFloat64(math.Trunc(x))
return resp, err return resp, err
} }
func calcPower(o operationType, stack stack) (number, ArErr) { func calcPower(o operationType, stack stack, stacklevel int) (number, ArErr) {
resp, err := runVal( resp, err := runVal(
o.values[0], o.values[0],
stack, stack,
stacklevel+1,
) )
resp = classVal(resp) resp = classVal(resp)
if err.EXISTS { if err.EXISTS {
@@ -559,6 +576,7 @@ func calcPower(o operationType, stack stack) (number, ArErr) {
resp, err := runVal( resp, err := runVal(
o.values[i], o.values[i],
stack, stack,
stacklevel+1,
) )
resp = classVal(resp) resp = classVal(resp)
if err.EXISTS { if err.EXISTS {
@@ -585,44 +603,44 @@ func calcPower(o operationType, stack stack) (number, ArErr) {
return output, 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 { switch o.operation {
case 0: case 0:
return calcAnd(o, stack) return calcAnd(o, stack, stacklevel+1)
case 1: case 1:
return calcOr(o, stack) return calcOr(o, stack, stacklevel+1)
case 2: case 2:
resp, err := calcIn(o, stack) resp, err := calcIn(o, stack, stacklevel+1)
resp = !resp resp = !resp
return resp, err return resp, err
case 3: case 3:
return calcIn(o, stack) return calcIn(o, stack, stacklevel+1)
case 4: case 4:
return compareValues(o, stack) return compareValues(o, stack, stacklevel+1)
case 5: case 5:
return compareValues(o, stack) return compareValues(o, stack, stacklevel+1)
case 6: case 6:
return compareValues(o, stack) return compareValues(o, stack, stacklevel+1)
case 7: case 7:
return compareValues(o, stack) return compareValues(o, stack, stacklevel+1)
case 8: case 8:
return compareValues(o, stack) return compareValues(o, stack, stacklevel+1)
case 9: case 9:
return compareValues(o, stack) return compareValues(o, stack, stacklevel+1)
case 10: case 10:
return calcAdd(o, stack) return calcAdd(o, stack, stacklevel+1)
case 11: case 11:
return calcNegative(o, stack) return calcNegative(o, stack, stacklevel+1)
case 12: case 12:
return calcMul(o, stack) return calcMul(o, stack, stacklevel+1)
case 13: case 13:
return calcMod(o, stack) return calcMod(o, stack, stacklevel+1)
case 14: case 14:
return calcIntDiv(o, stack) return calcIntDiv(o, stack, stacklevel+1)
case 15: case 15:
return calcDivide(o, stack) return calcDivide(o, stack, stacklevel+1)
case 16: case 16:
return calcPower(o, stack) return calcPower(o, stack, stacklevel+1)
} }
panic("Unknown operation: " + fmt.Sprint(o.operation)) panic("Unknown operation: " + fmt.Sprint(o.operation))

View File

@@ -6,11 +6,14 @@ import (
) )
// returns (number|string|nil), error // returns (number|string|nil), error
func runVal(line any, stack stack) (any, ArErr) { func runVal(line any, stack stack, stacklevel int) (any, ArErr) {
if len(stack) > 500 { if stacklevel > 10000 {
return nil, ArErr{ return nil, ArErr{
TYPE: "Stack overflow", TYPE: "RuntimeError",
message: "the stack has exceeded 500 levels", message: "stack overflow",
line: 0,
path: "",
code: "",
EXISTS: true, EXISTS: true,
} }
} }
@@ -20,19 +23,19 @@ func runVal(line any, stack stack) (any, ArErr) {
case string: case string:
return x, ArErr{} return x, ArErr{}
case call: case call:
return runCall(x, stack) return runCall(x, stack, stacklevel+1)
case factorial: case factorial:
return runFactorial(x, stack) return runFactorial(x, stack, stacklevel+1)
case accessVariable: case accessVariable:
return readVariable(x, stack) return readVariable(x, stack)
case ArMapGet: case ArMapGet:
return mapGet(x, stack) return mapGet(x, stack, stacklevel+1)
case ArClass: case ArClass:
return x.MAP, ArErr{} return x.MAP, ArErr{}
case setVariable: case setVariable:
return setVariableValue(x, stack) return setVariableValue(x, stack, stacklevel+1)
case negative: case negative:
resp, err := runVal(x.VAL, stack) resp, err := runVal(x.VAL, stack, stacklevel+1)
resp = classVal(resp) resp = classVal(resp)
if err.EXISTS { if err.EXISTS {
return nil, err return nil, err
@@ -47,15 +50,15 @@ func runVal(line any, stack stack) (any, ArErr) {
EXISTS: true, EXISTS: true,
} }
case brackets: case brackets:
return runVal(x.VAL, stack) return runVal(x.VAL, stack, stacklevel+1)
case operationType: case operationType:
return runOperation(x, stack) return runOperation(x, stack, stacklevel+1)
case dowrap: case dowrap:
return runDoWrap(x, stack) return runDoWrap(x, stack, stacklevel+1)
case CallJumpStatment: case CallJumpStatment:
return runJumpStatment(x, stack) return runJumpStatment(x, stack, stacklevel+1)
case ArDelete: case ArDelete:
return runDelete(x, stack) return runDelete(x, stack, stacklevel+1)
} }
fmt.Println("unreachable", reflect.TypeOf(line)) fmt.Println("unreachable", reflect.TypeOf(line))
panic("unreachable") panic("unreachable")
@@ -65,7 +68,7 @@ func runVal(line any, stack stack) (any, ArErr) {
func run(translated []any, stack stack) (any, ArErr, any) { func run(translated []any, stack stack) (any, ArErr, any) {
var output any = nil var output any = nil
for _, val := range translated { for _, val := range translated {
val, err := runVal(val, stack) val, err := runVal(val, stack, 0)
output = val output = val
if err.EXISTS { if err.EXISTS {
return nil, err, output return nil, err, output

View File

@@ -6,6 +6,12 @@ import (
"os/signal" "os/signal"
) )
var endingWithDoCompiled = makeRegex(`.*do( )*`)
func isEndingWithDo(str string) bool {
return endingWithDoCompiled.MatchString(str)
}
func shell() { func shell() {
global := stack{vars, scope{}} global := stack{vars, scope{}}
c := make(chan os.Signal, 1) c := make(chan os.Signal, 1)
@@ -19,9 +25,23 @@ func shell() {
} }
}() }()
for { for {
indo := false
totranslate := []UNPARSEcode{}
code := input("\x1b[38;5;240m>>> \x1b[0m\x1b[1;5;240m") code := input("\x1b[38;5;240m>>> \x1b[0m\x1b[1;5;240m")
fmt.Print("\x1b[0m") 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) count := len(translated)
if translationerr.EXISTS { if translationerr.EXISTS {
panicErr(translationerr) panicErr(translationerr)

View File

@@ -29,7 +29,7 @@ func ArThread(args ...any) (any, ArErr) {
hasrun = true hasrun = true
wg.Add(1) wg.Add(1)
go func() { go func() {
resp, err = runCall(call{tocall, []any{}, "", 0, ""}, currentscope) resp, err = runCall(call{tocall, []any{}, "", 0, ""}, currentscope, 0)
wg.Done() wg.Done()
}() }()
return nil, ArErr{} return nil, ArErr{}

View File

@@ -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} 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) 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 i += step
if err.EXISTS { if err.EXISTS {
return nil, err return nil, err

View File

@@ -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 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 var resp any
if v.function { if v.function {
resp = Callable{v.params, v.value, v.code, stack, v.line} resp = Callable{v.params, v.value, v.code, stack, v.line}
} else { } else {
respp, err := runVal(v.value, stack) respp, err := runVal(v.value, stack, stacklevel+1)
if err.EXISTS { if err.EXISTS {
return nil, err return nil, err
} }
@@ -212,11 +212,11 @@ func setVariableValue(v setVariable, stack stack) (any, ArErr) {
} }
stack[len(stack)-1][x.name] = resp stack[len(stack)-1][x.name] = resp
case ArMapGet: case ArMapGet:
respp, err := runVal(x.VAL, stack) respp, err := runVal(x.VAL, stack, stacklevel+1)
if err.EXISTS { if err.EXISTS {
return nil, err return nil, err
} }
key, err := runVal(x.start, stack) key, err := runVal(x.start, stack, stacklevel+1)
if err.EXISTS { if err.EXISTS {
return nil, err return nil, err
} }
@@ -251,7 +251,7 @@ func parseDelete(code UNPARSEcode, index int, lines []UNPARSEcode) (ArDelete, bo
}, true, ArErr{}, i }, 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) { switch x := d.value.(type) {
case accessVariable: case accessVariable:
for i := len(stack) - 1; i >= 0; i-- { 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} return nil, ArErr{"Runtime Error", "variable \"" + x.name + "\" does not exist", d.line, d.path, d.code, true}
case ArMapGet: case ArMapGet:
respp, err := runVal(x.VAL, stack) respp, err := runVal(x.VAL, stack, stacklevel+1)
if err.EXISTS { if err.EXISTS {
return nil, err return nil, err
} }
key, err := runVal(x.start, stack) key, err := runVal(x.start, stack, stacklevel+1)
if err.EXISTS { if err.EXISTS {
return nil, err return nil, err
} }

17
test.ar
View File

@@ -1,6 +1,13 @@
f(x) = do let ln(x) = do
y = number(input("what number? ")) let n = 1e10
return (z) = do return n * ((x^(1/n)) - 1)
return maths.round(z) * y * x
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))