add eval and potentially speed up variable access speeds when multi threading. fix bug in threading count

This commit is contained in:
2024-05-30 12:46:25 +01:00
parent 051581c84b
commit d48b0ab7b6
6 changed files with 69 additions and 18 deletions

View File

@@ -19,6 +19,7 @@ func makeGlobal() ArObject {
"client": builtinFunc{"client", ArSocketClient}, "client": builtinFunc{"client", ArSocketClient},
}) })
vars["infinity"] = infinity vars["infinity"] = infinity
vars["eval"] = builtinFunc{"eval", AReval}
vars["map"] = builtinFunc{"map", func(a ...any) (any, ArErr) { vars["map"] = builtinFunc{"map", func(a ...any) (any, ArErr) {
if len(a) == 0 { if len(a) == 0 {
return Map(anymap{}), ArErr{} return Map(anymap{}), ArErr{}

41
src/eval_function.go Normal file
View File

@@ -0,0 +1,41 @@
package main
import "fmt"
func AReval(a ...any) (any, ArErr) {
if len(a) < 1 || len(a) > 2 {
return nil, ArErr{TYPE: "Type Error", message: "expected 1 or 2 argument, got " + fmt.Sprint(len(a)), EXISTS: true}
}
var expression string
if typeof(a[0]) != "string" {
return nil, ArErr{TYPE: "Type Error", message: "expected string as first argument, got " + typeof(a[0]), EXISTS: true}
}
expression = ArValidToAny(a[0]).(string)
// translate the expression
var code UNPARSEcode = UNPARSEcode{
code: expression,
realcode: expression,
line: 0,
path: "eval",
}
translated, err := translate([]UNPARSEcode{code})
if err.EXISTS {
return nil, err
}
var scope ArObject
if len(a) == 2 {
if typeof(a[1]) != "map" {
return nil, ArErr{TYPE: "Type Error", message: "expected map as second argument, got " + typeof(a[1]), EXISTS: true}
}
scope = a[1].(ArObject)
} else {
scope = newscope()
}
var stack stack = []ArObject{scope}
// run the translated expression
return run(translated, stack)
}

View File

@@ -10,8 +10,8 @@ var Args = os.Args[1:]
type stack = []ArObject type stack = []ArObject
const VERSION = "3.0.6" const VERSION = "3.0.7"
const VERSION_NUM = 4 const VERSION_NUM = 5
func newscope() ArObject { func newscope() ArObject {
return Map(anymap{}) return Map(anymap{})
@@ -66,7 +66,5 @@ func main() {
panicErr(runimeErr) panicErr(runimeErr)
os.Exit(1) os.Exit(1)
} }
if threadCount > 0 { threadChan.Wait()
<-threadChan
}
} }

View File

@@ -114,10 +114,9 @@ func parseMap(code UNPARSEcode, index int, codelines []UNPARSEcode) (any, bool,
}, true, ArErr{}, countIndex }, true, ArErr{}, countIndex
} }
func Map(m anymap) ArObject {
var mutex = sync.RWMutex{} var mutex = sync.RWMutex{}
var listenersMutex = sync.RWMutex{} var listenersMutex = sync.RWMutex{}
func Map(m anymap) ArObject {
var currentID uint32 = 0 var currentID uint32 = 0
listeners := map[any]map[uint32]any{} listeners := map[any]map[uint32]any{}
obj := ArObject{ obj := ArObject{

View File

@@ -2,10 +2,10 @@ package main
import ( import (
"fmt" "fmt"
"sync"
) )
var threadCount = 0 var threadChan = sync.WaitGroup{}
var threadChan = make(chan bool)
func ArThread(args ...any) (any, ArErr) { func ArThread(args ...any) (any, ArErr) {
if len(args) != 1 { if len(args) != 1 {
@@ -28,7 +28,7 @@ func ArThread(args ...any) (any, ArErr) {
hasrun := false hasrun := false
joined := false joined := false
var wg = make(chan bool) var wg = sync.WaitGroup{}
threadMap := Map(anymap{ threadMap := Map(anymap{
"start": builtinFunc{"start", func(args ...any) (any, ArErr) { "start": builtinFunc{"start", func(args ...any) (any, ArErr) {
if hasrun { if hasrun {
@@ -38,14 +38,12 @@ func ArThread(args ...any) (any, ArErr) {
return nil, ArErr{TYPE: "Type Error", message: "Invalid number of arguments, expected 0, got " + fmt.Sprint(len(args)), EXISTS: true} return nil, ArErr{TYPE: "Type Error", message: "Invalid number of arguments, expected 0, got " + fmt.Sprint(len(args)), EXISTS: true}
} }
hasrun = true hasrun = true
threadCount++ wg.Add(1)
threadChan.Add(1)
go func() { go func() {
resp, err = runCall(call{Callable: tocall, Args: []any{}}, nil, 0) resp, err = runCall(call{Callable: tocall, Args: []any{}}, nil, 0)
wg <- true wg.Done()
threadCount-- threadChan.Done()
if threadCount == 0 {
threadChan <- true
}
}() }()
return nil, ArErr{} return nil, ArErr{}
}}, }},
@@ -59,7 +57,7 @@ func ArThread(args ...any) (any, ArErr) {
return nil, ArErr{TYPE: "Type Error", message: "Invalid number of arguments, expected 0, got " + fmt.Sprint(len(args)), EXISTS: true} return nil, ArErr{TYPE: "Type Error", message: "Invalid number of arguments, expected 0, got " + fmt.Sprint(len(args)), EXISTS: true}
} }
joined = true joined = true
<-wg wg.Wait()
return resp, err return resp, err
}}, }},
}) })

14
tests/multi_threading.ar Normal file
View File

@@ -0,0 +1,14 @@
let mythread(threadID) = do
term.log(threadID, "start")
let mynumber = 10
for (i from 0 to 1e4) do
mynumber += 1
mynumber
return term.log(threadID, "done")
let threads = []
term.time("start")
for (i from 0 to 100) do
threads.append(thread(()=mythread(i)))
threads[i].start()
term.timeEnd("start")