This commit is contained in:
2023-03-13 19:27:16 +00:00
parent 7220d12fb6
commit 0a85087bb9
15 changed files with 335 additions and 132 deletions

View File

@@ -18,8 +18,6 @@ func anyToBool(x any) bool {
return true
case Callable:
return true
case ArClass:
return true
default:
return true
}

View File

@@ -165,4 +165,6 @@ func init() {
vars["file"] = ArFile
vars["random"] = ArRandom
vars["json"] = ArJSON
vars["sin"] = ArSin
vars["arcsin"] = ArArcsin
}

View File

@@ -8,11 +8,6 @@ import (
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)+\]( *)`)
@@ -219,32 +214,6 @@ func mapGet(r ArMapGet, stack stack, stacklevel int) (any, ArErr) {
}
fmt.Println(startindex, endindex, step)
return m[startindex:endindex], 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, stacklevel+1)
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
@@ -404,8 +373,10 @@ func mapGet(r ArMapGet, stack stack, stacklevel int) (any, ArErr) {
}
func classVal(r any) any {
if _, ok := r.(ArClass); ok {
return r.(ArClass).value
if _, ok := r.(ArMap); ok {
if _, ok := r.(ArMap)["__value__"]; ok {
return r.(ArMap)["__value__"]
}
}
return r
}

View File

@@ -44,7 +44,7 @@ func readFile(path string) []UNPARSEcode {
return output
}
func importMod(realpath string, origin string, main bool) (scope, ArErr) {
func importMod(realpath string, origin string) (scope, ArErr) {
extention := filepath.Ext(realpath)
path := realpath
if extention == "" {

View File

@@ -41,6 +41,7 @@ func parse(str string) any {
func stringify(obj any) (string, error) {
output := []string{}
obj = classVal(obj)
switch x := obj.(type) {
case ArMap:
for key, value := range x {
@@ -65,14 +66,13 @@ func stringify(obj any) (string, error) {
case string:
return strconv.Quote(x), nil
case number:
num, _ := x.Float64()
return strconv.FormatFloat(num, 'f', -1, 64), nil
return anyToArgon(x, true, false, 1, 0, false, 0), nil
case bool:
return strconv.FormatBool(x), nil
case nil:
return "null", nil
}
err := errors.New("Cannot stringify " + typeof(obj))
err := errors.New("Cannot stringify '" + typeof(obj) + "'")
return "", err
}

View File

@@ -19,7 +19,7 @@ func main() {
shell()
os.Exit(0)
}
_, err := importMod(Args[0], ex, true)
_, err := importMod(Args[0], ex)
if err.EXISTS {
panicErr(err)
os.Exit(1)

76
src/parseImport.go Normal file
View File

@@ -0,0 +1,76 @@
package main
import (
"os"
"strings"
)
var genericImportCompiled = makeRegex(`import( )+(.|\n)+( )+as( )+([a-zA-Z_]|(\p{L}\p{M}*))([a-zA-Z0-9_]|(\p{L}\p{M}*))*( *)`)
type ArImport struct {
filePath any
values any
code string
line int
path string
}
func isGenericImport(code UNPARSEcode) bool {
return genericImportCompiled.MatchString(code.code)
}
func parseGenericImport(code UNPARSEcode, index int, codeline []UNPARSEcode) (ArImport, bool, ArErr, int) {
trim := strings.Trim(code.code, " ")
pathAndAs := trim[6:]
split := strings.SplitN(pathAndAs, " as ", 2)
toImportstr := strings.TrimSpace(split[0])
asStr := strings.TrimSpace(split[1])
toImport, worked, err, i := translateVal(UNPARSEcode{
code: toImportstr,
realcode: code.realcode,
line: code.line,
path: code.path,
}, index, codeline, 0)
if !worked {
return ArImport{}, false, err, i
}
return ArImport{
toImport,
asStr,
code.realcode,
code.line,
code.path,
}, true, ArErr{}, i
}
func runImport(importOBJ ArImport, stack stack, stacklevel int) (any, ArErr) {
val, err := runVal(importOBJ.filePath, stack, stacklevel+1)
if err.EXISTS {
return nil, err
}
if typeof(val) != "string" {
return nil, ArErr{"Type Error", "import requires a string, got type '" + typeof(val) + "'", importOBJ.line, importOBJ.path, importOBJ.code, true}
}
path := val.(string)
ex, e := os.Getwd()
if e != nil {
return nil, ArErr{"File Error", "could not get current working directory", importOBJ.line, importOBJ.path, importOBJ.code, true}
}
stackMap, err := importMod(path, ex)
if err.EXISTS {
return nil, err
}
switch x := importOBJ.values.(type) {
case []string:
for _, v := range x {
val, ok := stackMap[v]
if !ok {
return nil, ArErr{"Import Error", "could not find value " + anyToArgon(v, true, false, 3, 0, false, 0) + " in module " + anyToArgon(path, true, false, 3, 0, false, 0), importOBJ.line, importOBJ.path, importOBJ.code, true}
}
stack[len(stack)-1][v] = val
}
case string:
stack[len(stack)-1][x] = stackMap
}
return nil, ArErr{}
}

View File

@@ -7,6 +7,7 @@ import (
// returns (number|string|nil), error
func runVal(line any, stack stack, stacklevel int) (any, ArErr) {
fmt.Println(stack)
if stacklevel > 10000 {
return nil, ArErr{
TYPE: "RuntimeError",
@@ -30,8 +31,6 @@ func runVal(line any, stack stack, stacklevel int) (any, ArErr) {
return readVariable(x, stack)
case ArMapGet:
return mapGet(x, stack, stacklevel+1)
case ArClass:
return x.MAP, ArErr{}
case setVariable:
return setVariableValue(x, stack, stacklevel+1)
case negative:
@@ -69,6 +68,10 @@ func runVal(line any, stack stack, stacklevel int) (any, ArErr) {
return runWhileLoop(x, stack, stacklevel+1)
case CreateArray:
return runArray(x, stack, stacklevel+1)
case squareroot:
return runSquareroot(x, stack, stacklevel+1)
case ArImport:
return runImport(x, stack, stacklevel+1)
case bool:
return x, ArErr{}
case nil:

74
src/squareroot.go Normal file
View File

@@ -0,0 +1,74 @@
package main
import (
"math/big"
"strings"
)
var squarerootcompiled = makeRegex(`(.|\n)*√(.|\n)+`)
type squareroot struct {
first any
second any
code string
line int
path string
}
func issquareroot(code UNPARSEcode) bool {
return squarerootcompiled.MatchString(code.code)
}
func parseSquareroot(code UNPARSEcode, index int, lines []UNPARSEcode) (squareroot, bool, ArErr, int) {
split := strings.SplitN(code.code, "√", 2)
first := strings.TrimSpace(split[0])
second := strings.TrimSpace(split[1])
var firstparsed any = newNumber().SetInt64(1)
outputlen := 0
if first != "" {
val, worked, err, i := translateVal(UNPARSEcode{code: first, realcode: code.realcode, line: code.line, path: code.path}, index, lines, 0)
if !worked {
return squareroot{}, false, err, i
}
outputlen += i - 1
firstparsed = val
}
secondparsed, worked, err, i := translateVal(UNPARSEcode{code: second, realcode: code.realcode, line: code.line, path: code.path}, index, lines, 0)
if !worked {
return squareroot{}, false, err, i
}
outputlen += i
return squareroot{
firstparsed,
secondparsed,
code.realcode,
code.line,
code.path,
}, true, ArErr{}, outputlen
}
func runSquareroot(squareroot squareroot, stack stack, stacklevel int) (number, ArErr) {
val1, err := runVal(squareroot.first, stack, stacklevel+1)
if err.EXISTS {
return nil, err
}
val2, err := runVal(squareroot.second, stack, stacklevel+1)
if err.EXISTS {
return nil, err
}
if typeof(val1) != "number" || typeof(val2) != "number" {
return nil, ArErr{"Type Error", "Cannot take the square root of a non-number", squareroot.line, squareroot.path, squareroot.code, true}
}
var x big.Float
x.SetPrec(30)
x.SetRat(val2.(number))
var s big.Float
s.SetPrec(15)
s.Sqrt(&x)
r, _ := s.Rat(nil)
r.Mul(r, val1.(number))
return r, ArErr{}
}

View File

@@ -6,10 +6,9 @@ import (
var MicroSeconds = newNumber().SetInt64(1000000)
func ArTimeClass(N time.Time) ArClass {
return ArClass{
newNumber().Quo(newNumber().SetInt64(N.UnixMicro()), MicroSeconds),
ArMap{
func ArTimeClass(N time.Time) ArMap {
return ArMap{
"__value__": newNumber().Quo(newNumber().SetInt64(N.UnixMicro()), MicroSeconds),
"year": builtinFunc{
"year",
func(a ...any) (any, ArErr) {
@@ -97,7 +96,7 @@ func ArTimeClass(N time.Time) ArClass {
return N.Format(a[0].(string)), ArErr{}
},
},
}}
}
}
var ArTime = map[any]any{

View File

@@ -73,6 +73,9 @@ func anyToArgon(x any, quote bool, simplify bool, depth int, indent int, colored
output = append(output, "\x1b[0m")
}
case ArMap:
if _, ok := x["__value__"]; ok {
return anyToArgon(x["__value__"], quote, simplify, depth, indent, colored, plain)
}
if len(x) == 0 {
return "{}"
}
@@ -85,7 +88,22 @@ func anyToArgon(x any, quote bool, simplify bool, depth int, indent int, colored
}
output := []string{}
for _, key := range keys {
output = append(output, anyToArgon(key, true, true, depth, (indent+1)*plain, colored, plain)+": "+anyToArgon(x[key], true, true, depth-1, indent+1, colored, plain))
keyval := ""
if typeof(key) != "string" || !SpacelessVariableCompiled.MatchString(key.(string)) {
keyval = anyToArgon(key, true, true, depth-1, indent+1, colored, plain)
} else {
outputkeyval := []string{}
if colored {
outputkeyval = append(outputkeyval, "\x1b[36;5;240m")
}
outputkeyval = append(outputkeyval, key.(string))
if colored {
outputkeyval = append(outputkeyval, "\x1b[0m")
}
keyval = strings.Join(outputkeyval, "")
}
output = append(output, keyval+": "+anyToArgon(x[key], true, true, depth-1, indent+1, colored, plain))
}
return "{" + maybenewline + (strings.Repeat(" ", (indent+1)*plain)) + strings.Join(output, ","+maybenewline+(strings.Repeat(" ", (indent+1)*plain))) + maybenewline + (strings.Repeat(" ", indent*plain)) + "}"
case ArArray:
@@ -130,8 +148,6 @@ func anyToArgon(x any, quote bool, simplify bool, depth int, indent int, colored
if colored {
output = append(output, "\x1b[0m")
}
case ArClass:
return anyToArgon(x.value, quote, simplify, depth, indent, colored, plain)
default:
return fmt.Sprint(x)
}

View File

@@ -1,6 +1,7 @@
package main
import (
"fmt"
"strings"
)
@@ -13,7 +14,7 @@ type UNPARSEcode struct {
// returns (number | string | nil), success, error, step
func translateVal(code UNPARSEcode, index int, codelines []UNPARSEcode, isLine int) (any, bool, ArErr, int) {
fmt.Println(code)
if isLine == 2 {
if isDeleteVariable(code) {
return parseDelete(code, index, codelines)
@@ -32,6 +33,8 @@ func translateVal(code UNPARSEcode, index int, codelines []UNPARSEcode, isLine i
return parseWhileLoop(code, index, codelines)
} else if isForeverLoop(code) {
return parseForeverLoop(code, index, codelines)
} else if isGenericImport(code) {
return parseGenericImport(code, index, codelines)
}
}
@@ -95,6 +98,8 @@ func translateVal(code UNPARSEcode, index int, codelines []UNPARSEcode, isLine i
return indexGetParse(code, index, codelines)
} else if isString(code) {
return parseString(code)
} else if issquareroot(code) {
return parseSquareroot(code, index, codelines)
}
return nil, false, ArErr{"Syntax Error", "invalid syntax", code.line, code.path, code.realcode, true}, 1
}

59
src/trig.go Normal file
View File

@@ -0,0 +1,59 @@
package main
import (
"fmt"
"math"
)
var PIFloatInaccuracy number = newNumber()
func init() {
PIFloatInaccuracy.SetFloat64(math.Asin(1) * 2)
}
var ArSin = builtinFunc{"sin", func(args ...any) (any, ArErr) {
if len(args) != 1 {
return nil, ArErr{TYPE: "Runtime Error",
message: fmt.Sprintf("sin expected 1 argument, got %d", len(args)),
EXISTS: true,
}
}
if typeof(args[0]) != "number" {
return nil, ArErr{TYPE: "Runtime Error",
message: fmt.Sprintf("sin expected number, got %s", typeof(args[0])),
EXISTS: true,
}
}
num := newNumber().Set(args[0].(number))
num.Quo(num, PI)
num.Mul(num, PIFloatInaccuracy)
n, _ := num.Float64()
outputnum := newNumber().SetFloat64(math.Sin(n))
return outputnum, ArErr{}
}}
var ArArcsin = builtinFunc{"arcsin", func(args ...any) (any, ArErr) {
if len(args) != 1 {
return nil, ArErr{TYPE: "Runtime Error",
message: fmt.Sprintf("arcsin expected 1 argument, got %d", len(args)),
EXISTS: true,
}
}
if typeof(args[0]) != "number" {
return nil, ArErr{TYPE: "Runtime Error",
message: fmt.Sprintf("arcsin expected number, got %s", typeof(args[0])),
EXISTS: true,
}
}
num := args[0].(number)
n, _ := num.Float64()
if n < -1 || n > 1 {
return nil, ArErr{TYPE: "Runtime Error",
message: fmt.Sprintf("arcsin expected number between -1 and 1, got %s", anyToArgon(n, true, true, 3, 0, false, 0)),
EXISTS: true,
}
}
outputnum := newNumber().SetFloat64(math.Asin(n))
outputnum.Quo(outputnum, PIFloatInaccuracy)
outputnum.Mul(outputnum, PI)
return outputnum, ArErr{}
}}

View File

@@ -1,10 +1,12 @@
package main
import (
"fmt"
"strings"
"sync"
)
var SpacelessVariableCompiled = 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 setVariableCompile = makeRegex(`( *)(let( +))(.|\n)+( *)=(.|\n)+`)
@@ -162,6 +164,7 @@ func parseSetVariable(code UNPARSEcode, index int, lines []UNPARSEcode, isLine i
}
func parseAutoAsignVariable(code UNPARSEcode, index int, lines []UNPARSEcode, isLine int) (setVariable, bool, ArErr, int) {
fmt.Println("autoasign", code.code)
trim := strings.TrimSpace(code.code)
equalsplit := strings.SplitN(trim, "=", 2)
name := strings.TrimSpace(equalsplit[0])
@@ -190,6 +193,7 @@ func parseAutoAsignVariable(code UNPARSEcode, index int, lines []UNPARSEcode, is
if !success {
return setVariable{}, false, err, i
}
fmt.Println("autoasign", code.code, "success")
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
}

12
test.ar
View File

@@ -1,8 +1,4 @@
a = array()
i = 0
forever do
a = append(a, i)
i = i + 1
if (i % 1000000 == 0) do
term.log(i)
test = 10
poo = do
term.log("ran")
return "lol"