impliment garbage collection and move init

This commit is contained in:
2023-03-25 18:19:48 +00:00
parent fa32f7b824
commit bfad2775ee
11 changed files with 64 additions and 31 deletions

View File

@@ -351,7 +351,7 @@ func ArArray(arr []any) ArObject {
return runCall(call{ return runCall(call{
args[1], args[1],
[]any{a}, "", 0, "", []any{a}, "", 0, "",
}, stack{vars, newscope()}, 0) }, stack{}, 0)
}) })
if err.EXISTS { if err.EXISTS {
return nil, err return nil, err
@@ -400,7 +400,7 @@ func ArArray(arr []any) ArObject {
vv, err := runCall(call{ vv, err := runCall(call{
args[0], args[0],
[]any{v}, "", 0, "", []any{v}, "", 0, "",
}, stack{vars, newscope()}, 0) }, stack{}, 0)
if err.EXISTS { if err.EXISTS {
return nil, err return nil, err
} }
@@ -431,7 +431,7 @@ func ArArray(arr []any) ArObject {
vv, err := runCall(call{ vv, err := runCall(call{
args[0], args[0],
[]any{v}, "", 0, "", []any{v}, "", 0, "",
}, stack{vars, newscope()}, 0) }, stack{}, 0)
if err.EXISTS { if err.EXISTS {
return nil, err return nil, err
} }
@@ -448,7 +448,7 @@ func ArArray(arr []any) ArObject {
if len(args) != 2 { if len(args) != 2 {
return nil, ArErr{ return nil, ArErr{
TYPE: "TypeError", TYPE: "TypeError",
message: "missing argument", message: "missing argument, expected 2 got " + fmt.Sprint(len(args)),
EXISTS: true, EXISTS: true,
} }
} }
@@ -472,7 +472,7 @@ func ArArray(arr []any) ArObject {
v, err = runCall(call{ v, err = runCall(call{
args[0], args[0],
[]any{v, vv}, "", 0, "", []any{v, vv}, "", 0, "",
}, stack{vars, newscope()}, 0) }, stack{}, 0)
if err.EXISTS { if err.EXISTS {
return nil, err return nil, err
} }

View File

@@ -2,9 +2,8 @@ package main
import "fmt" import "fmt"
func makeGlobal() ArObject {
var vars = Map(anymap{}) var vars = Map(anymap{})
func init() {
vars.obj["global"] = vars vars.obj["global"] = vars
vars.obj["term"] = ArTerm vars.obj["term"] = ArTerm
vars.obj["number"] = builtinFunc{"number", ArgonNumber} vars.obj["number"] = builtinFunc{"number", ArgonNumber}
@@ -150,4 +149,5 @@ func init() {
return ArArray([]any{}), ArErr{} return ArArray([]any{}), ArErr{}
}} }}
vars.obj["subprocess"] = builtinFunc{"subprocess", ArSubprocess} vars.obj["subprocess"] = builtinFunc{"subprocess", ArSubprocess}
return vars
} }

15
src/garbageCollect.go Normal file
View File

@@ -0,0 +1,15 @@
package main
import (
"runtime"
"time"
)
func garbageCollect() {
go func() {
for {
time.Sleep(10 * time.Second)
runtime.GC()
}
}()
}

View File

@@ -47,7 +47,7 @@ func readFile(path string) []UNPARSEcode {
return output return output
} }
func importMod(realpath string, origin string, main bool) (ArObject, ArErr) { func importMod(realpath string, origin string, main bool, global ArObject) (ArObject, ArErr) {
extention := filepath.Ext(realpath) extention := filepath.Ext(realpath)
path := realpath path := realpath
if extention == "" { if extention == "" {
@@ -114,7 +114,7 @@ func importMod(realpath string, origin string, main bool) (ArObject, ArErr) {
for _, arg := range withoutarfile { for _, arg := range withoutarfile {
ArgsArArray = append(ArgsArArray, arg) ArgsArArray = append(ArgsArArray, arg)
} }
global := newscope() local := newscope()
localvars := Map(anymap{ localvars := Map(anymap{
"program": Map(anymap{ "program": Map(anymap{
"args": ArArray(ArgsArArray), "args": ArArray(ArgsArArray),
@@ -126,7 +126,7 @@ func importMod(realpath string, origin string, main bool) (ArObject, ArErr) {
if _, ok := args[0].(string); !ok { if _, ok := args[0].(string); !ok {
return nil, ArErr{"Import Error", "Invalid argument type", 0, realpath, "", true} return nil, ArErr{"Import Error", "Invalid argument type", 0, realpath, "", true}
} }
return importMod(args[0].(string), filepath.Dir(p), false) return importMod(args[0].(string), filepath.Dir(p), false, global)
}}, }},
"cwd": ex, "cwd": ex,
"exc": exc, "exc": exc,
@@ -138,7 +138,7 @@ func importMod(realpath string, origin string, main bool) (ArObject, ArErr) {
"scope": global, "scope": global,
}), }),
}) })
_, runimeErr := ThrowOnNonLoop(run(translated, stack{vars, localvars, global})) _, runimeErr := ThrowOnNonLoop(run(translated, stack{global, localvars, local}))
importing[p] = false importing[p] = false
if runimeErr.EXISTS { if runimeErr.EXISTS {
return ArObject{}, runimeErr return ArObject{}, runimeErr

View File

@@ -17,15 +17,18 @@ func newscope() ArObject {
} }
func main() { func main() {
initRandom()
garbageCollect()
global := makeGlobal()
if len(Args) == 0 {
shell(global)
os.Exit(0)
}
ex, e := os.Getwd() ex, e := os.Getwd()
if e != nil { if e != nil {
panic(e) panic(e)
} }
if len(Args) == 0 { _, err := importMod(Args[0], ex, true, global)
shell()
os.Exit(0)
}
_, err := importMod(Args[0], ex, true)
if err.EXISTS { if err.EXISTS {
panicErr(err) panicErr(err)
os.Exit(1) os.Exit(1)

View File

@@ -57,7 +57,7 @@ func runImport(importOBJ ArImport, stack stack, stacklevel int) (any, ArErr) {
if e != nil { if e != nil {
return nil, ArErr{"File Error", "could not get current working directory", importOBJ.line, importOBJ.path, importOBJ.code, true} return nil, ArErr{"File Error", "could not get current working directory", importOBJ.line, importOBJ.path, importOBJ.code, true}
} }
stackMap, err := importMod(path, ex, false) stackMap, err := importMod(path, ex, false, stack[0])
if err.EXISTS { if err.EXISTS {
if err.line == 0 { if err.line == 0 {
err.line = importOBJ.line err.line = importOBJ.line

View File

@@ -97,7 +97,7 @@ var ArRandom = Map(anymap{
}}, }},
}) })
func init() { func initRandom() {
rand.Seed( rand.Seed(
time.Now().UnixMicro(), time.Now().UnixMicro(),
) )

View File

@@ -6,8 +6,8 @@ import (
"os/signal" "os/signal"
) )
func shell() { func shell(global ArObject) {
global := stack{vars, newscope()} stack := stack{global, newscope()}
c := make(chan os.Signal, 1) c := make(chan os.Signal, 1)
signal.Notify(c, os.Interrupt) signal.Notify(c, os.Interrupt)
go func() { go func() {
@@ -41,7 +41,7 @@ func shell() {
if translationerr.EXISTS { if translationerr.EXISTS {
panicErr(translationerr) panicErr(translationerr)
} }
output, runimeErr := ThrowOnNonLoop(run(translated, global)) output, runimeErr := ThrowOnNonLoop(run(translated, stack))
output = openReturn(output) output = openReturn(output)
if runimeErr.EXISTS { if runimeErr.EXISTS {

View File

@@ -23,7 +23,7 @@ func ArThread(args ...any) (any, ArErr) {
} }
var resp any var resp any
var err ArErr var err ArErr
currentscope := stack{vars, newscope()}
hasrun := false hasrun := false
joined := false joined := false
var wg sync.WaitGroup var wg sync.WaitGroup
@@ -38,7 +38,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, 0) resp, err = runCall(call{tocall, []any{}, "", 0, ""}, nil, 0)
wg.Done() wg.Done()
}() }()
return nil, ArErr{} return nil, ArErr{}

View File

@@ -62,7 +62,8 @@ func translateVal(code UNPARSEcode, index int, codelines []UNPARSEcode, isLine i
if worked { if worked {
return resp, worked, err, i return resp, worked, err, i
} }
} else if isnot(code) { }
if isnot(code) {
return parseNot(code, index, codelines, isLine) return parseNot(code, index, codelines, isLine)
} }
if isSetVariable(code) { if isSetVariable(code) {
@@ -76,7 +77,8 @@ func translateVal(code UNPARSEcode, index int, codelines []UNPARSEcode, isLine i
if worked { if worked {
return resp, worked, err, i return resp, worked, err, i
} }
} else if isNumber(code) { }
if isNumber(code) {
return parseNumber(code) return parseNumber(code)
} else if isNegative(code) { } else if isNegative(code) {
return parseNegative(code, index, codelines) return parseNegative(code, index, codelines)
@@ -86,21 +88,26 @@ func translateVal(code UNPARSEcode, index int, codelines []UNPARSEcode, isLine i
return parseSquareroot(code, index, codelines) return parseSquareroot(code, index, codelines)
} else if isFactorial(code) { } else if isFactorial(code) {
return parseFactorial(code, index, codelines) return parseFactorial(code, index, codelines)
} else if isCall(code) { }
if isCall(code) {
resp, worked, err, i = parseCall(code, index, codelines) resp, worked, err, i = parseCall(code, index, codelines)
if worked { if worked {
return resp, worked, err, i return resp, worked, err, i
} }
} else if isVariable(code) { }
if isVariable(code) {
return parseVariable(code) return parseVariable(code)
} else if isArray(code) { }
if isArray(code) {
resp, worked, err, i = parseArray(code, index, codelines) resp, worked, err, i = parseArray(code, index, codelines)
if worked { if worked {
return resp, worked, err, i return resp, worked, err, i
} }
} else if isMapGet(code) { }
if isMapGet(code) {
return mapGetParse(code, index, codelines) return mapGetParse(code, index, codelines)
} else if isIndexGet(code) { }
if isIndexGet(code) {
resp, worked, err, i = indexGetParse(code, index, codelines) resp, worked, err, i = indexGetParse(code, index, codelines)
if worked { if worked {
return resp, worked, err, i return resp, worked, err, i

8
tests/memoryLeakTest.ar Normal file
View File

@@ -0,0 +1,8 @@
f() = do
a = []
for (i from 0 to 10000000) a.append(i)
term.log("start")
f()
term.log("end")
time.snooze(100000000)