Files
argon-v3/src/thread.go

68 lines
1.9 KiB
Go

package main
import (
"fmt"
)
var threadCount = 0
var threadChan = make(chan bool)
func ArThread(args ...any) (any, ArErr) {
if len(args) != 1 {
return nil, ArErr{TYPE: "Type Error", message: "Invalid number of arguments, expected 1, got " + fmt.Sprint(len(args)), EXISTS: true}
}
var tocall any
switch x := args[0].(type) {
case anymap:
if _, ok := x["__call__"]; !ok {
return nil, ArErr{TYPE: "Type Error", message: "Cannot call thread with a '" + typeof(args[0]) + "'", EXISTS: true}
}
tocall = x["__call__"]
case builtinFunc, Callable:
tocall = x
default:
return nil, ArErr{TYPE: "Type Error", message: "Cannot call thread with a '" + typeof(args[0]) + "'", EXISTS: true}
}
var resp any
var err ArErr
hasrun := false
joined := false
var wg = make(chan bool)
threadMap := Map(anymap{
"start": builtinFunc{"start", func(args ...any) (any, ArErr) {
if hasrun {
return nil, ArErr{TYPE: "Runtime Error", message: "Cannot start a thread twice", EXISTS: true}
}
if len(args) != 0 {
return nil, ArErr{TYPE: "Type Error", message: "Invalid number of arguments, expected 0, got " + fmt.Sprint(len(args)), EXISTS: true}
}
hasrun = true
threadCount++
go func() {
resp, err = runCall(call{Callable: tocall, Args: []any{}}, nil, 0)
wg <- true
threadCount--
if threadCount == 0 {
threadChan <- true
}
}()
return nil, ArErr{}
}},
"join": builtinFunc{"join", func(args ...any) (any, ArErr) {
if !hasrun {
return nil, ArErr{TYPE: "Runtime Error", message: "Cannot join a thread that has not started", EXISTS: true}
} else if joined {
return nil, ArErr{TYPE: "Runtime Error", message: "Cannot join a thread twice", EXISTS: true}
}
if len(args) != 0 {
return nil, ArErr{TYPE: "Type Error", message: "Invalid number of arguments, expected 0, got " + fmt.Sprint(len(args)), EXISTS: true}
}
joined = true
<-wg
return resp, err
}},
})
return threadMap, ArErr{}
}