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},
})
vars["infinity"] = infinity
vars["eval"] = builtinFunc{"eval", AReval}
vars["map"] = builtinFunc{"map", func(a ...any) (any, ArErr) {
if len(a) == 0 {
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
const VERSION = "3.0.6"
const VERSION_NUM = 4
const VERSION = "3.0.7"
const VERSION_NUM = 5
func newscope() ArObject {
return Map(anymap{})
@@ -66,7 +66,5 @@ func main() {
panicErr(runimeErr)
os.Exit(1)
}
if threadCount > 0 {
<-threadChan
}
threadChan.Wait()
}

View File

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

View File

@@ -2,10 +2,10 @@ package main
import (
"fmt"
"sync"
)
var threadCount = 0
var threadChan = make(chan bool)
var threadChan = sync.WaitGroup{}
func ArThread(args ...any) (any, ArErr) {
if len(args) != 1 {
@@ -28,7 +28,7 @@ func ArThread(args ...any) (any, ArErr) {
hasrun := false
joined := false
var wg = make(chan bool)
var wg = sync.WaitGroup{}
threadMap := Map(anymap{
"start": builtinFunc{"start", func(args ...any) (any, ArErr) {
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}
}
hasrun = true
threadCount++
wg.Add(1)
threadChan.Add(1)
go func() {
resp, err = runCall(call{Callable: tocall, Args: []any{}}, nil, 0)
wg <- true
threadCount--
if threadCount == 0 {
threadChan <- true
}
wg.Done()
threadChan.Done()
}()
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}
}
joined = true
<-wg
wg.Wait()
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")