diff --git a/src/array.go b/src/array.go index 49f693b..dd68af2 100644 --- a/src/array.go +++ b/src/array.go @@ -351,7 +351,7 @@ func ArArray(arr []any) ArObject { return runCall(call{ args[1], []any{a}, "", 0, "", - }, stack{vars, newscope()}, 0) + }, stack{}, 0) }) if err.EXISTS { return nil, err @@ -400,7 +400,7 @@ func ArArray(arr []any) ArObject { vv, err := runCall(call{ args[0], []any{v}, "", 0, "", - }, stack{vars, newscope()}, 0) + }, stack{}, 0) if err.EXISTS { return nil, err } @@ -431,7 +431,7 @@ func ArArray(arr []any) ArObject { vv, err := runCall(call{ args[0], []any{v}, "", 0, "", - }, stack{vars, newscope()}, 0) + }, stack{}, 0) if err.EXISTS { return nil, err } @@ -448,7 +448,7 @@ func ArArray(arr []any) ArObject { if len(args) != 2 { return nil, ArErr{ TYPE: "TypeError", - message: "missing argument", + message: "missing argument, expected 2 got " + fmt.Sprint(len(args)), EXISTS: true, } } @@ -472,7 +472,7 @@ func ArArray(arr []any) ArObject { v, err = runCall(call{ args[0], []any{v, vv}, "", 0, "", - }, stack{vars, newscope()}, 0) + }, stack{}, 0) if err.EXISTS { return nil, err } diff --git a/src/built-ins.go b/src/built-ins.go index ca84e70..9cc09bd 100644 --- a/src/built-ins.go +++ b/src/built-ins.go @@ -2,9 +2,8 @@ package main import "fmt" -var vars = Map(anymap{}) - -func init() { +func makeGlobal() ArObject { + var vars = Map(anymap{}) vars.obj["global"] = vars vars.obj["term"] = ArTerm vars.obj["number"] = builtinFunc{"number", ArgonNumber} @@ -150,4 +149,5 @@ func init() { return ArArray([]any{}), ArErr{} }} vars.obj["subprocess"] = builtinFunc{"subprocess", ArSubprocess} + return vars } diff --git a/src/garbageCollect.go b/src/garbageCollect.go new file mode 100644 index 0000000..14b5b07 --- /dev/null +++ b/src/garbageCollect.go @@ -0,0 +1,15 @@ +package main + +import ( + "runtime" + "time" +) + +func garbageCollect() { + go func() { + for { + time.Sleep(10 * time.Second) + runtime.GC() + } + }() +} diff --git a/src/import.go b/src/import.go index 3254422..ef99282 100644 --- a/src/import.go +++ b/src/import.go @@ -46,7 +46,7 @@ func readFile(path string) []UNPARSEcode { return output } -func importMod(realpath string, origin string, main bool) (ArObject, ArErr) { +func importMod(realpath string, origin string, main bool, global ArObject) (ArObject, ArErr) { return ArObject{}, ArErr{ TYPE: "Import Error", message: "importing in WASM is currently not supported", diff --git a/src/main.go b/src/main.go index 8b1c2a8..6fe355f 100644 --- a/src/main.go +++ b/src/main.go @@ -19,6 +19,7 @@ func newscope() ArObject { func main() { c := make(chan ArObject) + garbageCollect() obj := js.Global().Get("Object").New() obj.Set("eval", js.FuncOf(func(this js.Value, args []js.Value) interface{} { code := "" diff --git a/src/parseImport.go b/src/parseImport.go index 324318e..2ec7ce7 100644 --- a/src/parseImport.go +++ b/src/parseImport.go @@ -58,7 +58,7 @@ func runImport(importOBJ ArImport, stack stack, stacklevel int) (any, ArErr) { 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, false) + stackMap, err := importMod(path, ex, false, stack[0]) if err.EXISTS { if err.line == 0 { err.line = importOBJ.line diff --git a/src/random.go b/src/random.go index 7fb6044..6af0650 100644 --- a/src/random.go +++ b/src/random.go @@ -97,7 +97,7 @@ var ArRandom = Map(anymap{ }}, }) -func init() { +func initRandom() { rand.Seed( time.Now().UnixMicro(), ) diff --git a/src/shell.go b/src/shell.go index f3d23be..7ce72a9 100644 --- a/src/shell.go +++ b/src/shell.go @@ -6,8 +6,8 @@ import ( "os/signal" ) -func shell() { - global := stack{vars, newscope()} +func shell(global ArObject) { + stack := stack{global, newscope()} c := make(chan os.Signal, 1) signal.Notify(c, os.Interrupt) go func() { @@ -41,7 +41,7 @@ func shell() { if translationerr.EXISTS { panicErr(translationerr) } - output, runimeErr := ThrowOnNonLoop(run(translated, global)) + output, runimeErr := ThrowOnNonLoop(run(translated, stack)) output = openReturn(output) if runimeErr.EXISTS { diff --git a/src/thread.go b/src/thread.go index 1e8b8c0..d9a8fba 100644 --- a/src/thread.go +++ b/src/thread.go @@ -23,7 +23,7 @@ func ArThread(args ...any) (any, ArErr) { } var resp any var err ArErr - currentscope := stack{vars, newscope()} + hasrun := false joined := false var wg sync.WaitGroup @@ -38,7 +38,7 @@ func ArThread(args ...any) (any, ArErr) { hasrun = true wg.Add(1) go func() { - resp, err = runCall(call{tocall, []any{}, "", 0, ""}, currentscope, 0) + resp, err = runCall(call{tocall, []any{}, "", 0, ""}, nil, 0) wg.Done() }() return nil, ArErr{} diff --git a/src/translate.go b/src/translate.go index e6d13a2..aafb8e8 100644 --- a/src/translate.go +++ b/src/translate.go @@ -61,7 +61,8 @@ func translateVal(code UNPARSEcode, index int, codelines []UNPARSEcode, isLine i if worked { return resp, worked, err, i } - } else if isnot(code) { + } + if isnot(code) { return parseNot(code, index, codelines, isLine) } if isSetVariable(code) { @@ -75,7 +76,8 @@ func translateVal(code UNPARSEcode, index int, codelines []UNPARSEcode, isLine i if worked { return resp, worked, err, i } - } else if isNumber(code) { + } + if isNumber(code) { return parseNumber(code) } else if isNegative(code) { return parseNegative(code, index, codelines) @@ -85,21 +87,26 @@ func translateVal(code UNPARSEcode, index int, codelines []UNPARSEcode, isLine i return parseSquareroot(code, index, codelines) } else if isFactorial(code) { return parseFactorial(code, index, codelines) - } else if isCall(code) { + } + if isCall(code) { resp, worked, err, i = parseCall(code, index, codelines) if worked { return resp, worked, err, i } - } else if isVariable(code) { + } + if isVariable(code) { return parseVariable(code) - } else if isArray(code) { + } + if isArray(code) { resp, worked, err, i = parseArray(code, index, codelines) if worked { return resp, worked, err, i } - } else if isMapGet(code) { + } + if isMapGet(code) { return mapGetParse(code, index, codelines) - } else if isIndexGet(code) { + } + if isIndexGet(code) { resp, worked, err, i = indexGetParse(code, index, codelines) if worked { return resp, worked, err, i diff --git a/tests/memoryLeakTest.ar b/tests/memoryLeakTest.ar new file mode 100644 index 0000000..00ecb63 --- /dev/null +++ b/tests/memoryLeakTest.ar @@ -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) \ No newline at end of file