mirror of
https://github.com/dragonheim/gagent.git
synced 2025-01-18 09:36:28 -08:00
refactor: cleaning up some old issues and stndardizing.
This commit is contained in:
parent
b95d3950c5
commit
8640d42132
6 changed files with 190 additions and 113 deletions
|
@ -1,10 +1,10 @@
|
||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
fmt "fmt"
|
|
||||||
log "log"
|
log "log"
|
||||||
http "net/http"
|
http "net/http"
|
||||||
os "os"
|
os "os"
|
||||||
|
strconv "strconv"
|
||||||
sync "sync"
|
sync "sync"
|
||||||
|
|
||||||
autorestart "github.com/slayer/autorestart"
|
autorestart "github.com/slayer/autorestart"
|
||||||
|
@ -290,7 +290,7 @@ func init() {
|
||||||
if config.MonitorPort != 0 {
|
if config.MonitorPort != 0 {
|
||||||
go func() {
|
go func() {
|
||||||
log.Printf("[INFO] Starting Prometheus metrics exporter on port %d\n", config.MonitorPort)
|
log.Printf("[INFO] Starting Prometheus metrics exporter on port %d\n", config.MonitorPort)
|
||||||
log.Fatal(http.ListenAndServe(fmt.Sprintf("%s:%d", config.ListenAddr, config.MonitorPort), nil))
|
log.Fatal(http.ListenAndServe(string(config.ListenAddr)+strconv.FormatInt(config.MonitorPort, 10), nil))
|
||||||
}()
|
}()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,8 +7,8 @@ type GagentConfig struct {
|
||||||
Name string `hcl:"name,optional"`
|
Name string `hcl:"name,optional"`
|
||||||
Mode string `hcl:"mode,attr"`
|
Mode string `hcl:"mode,attr"`
|
||||||
UUID string `hcl:"uuid,optional"`
|
UUID string `hcl:"uuid,optional"`
|
||||||
MonitorPort int `hcl:"monitorport,optional"`
|
|
||||||
ListenAddr string `hcl:"listenaddr,optional"`
|
ListenAddr string `hcl:"listenaddr,optional"`
|
||||||
|
MonitorPort int64 `hcl:"monitorport,optional"`
|
||||||
ClientPort int64 `hcl:"clientport,optional"`
|
ClientPort int64 `hcl:"clientport,optional"`
|
||||||
RouterPort int64 `hcl:"routerport,optional"`
|
RouterPort int64 `hcl:"routerport,optional"`
|
||||||
WorkerPort int64 `hcl:"workerport,optional"`
|
WorkerPort int64 `hcl:"workerport,optional"`
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
package worker
|
package worker
|
||||||
|
|
||||||
import (
|
import (
|
||||||
fmt "fmt"
|
|
||||||
log "log"
|
log "log"
|
||||||
|
strconv "strconv"
|
||||||
sync "sync"
|
sync "sync"
|
||||||
|
|
||||||
gstructs "github.com/dragonheim/gagent/internal/gstructs"
|
gstructs "github.com/dragonheim/gagent/internal/gstructs"
|
||||||
|
@ -43,13 +43,13 @@ func Main(wg *sync.WaitGroup, config gstructs.GagentConfig) {
|
||||||
/*
|
/*
|
||||||
* Generate connect string for this router.
|
* Generate connect string for this router.
|
||||||
*/
|
*/
|
||||||
connectString := fmt.Sprintf("tcp://%s:%d", config.Routers[key].RouterAddr, rport)
|
connectString := "tcp://" + config.Routers[key].RouterAddr + ":" + strconv.FormatInt(rport, 10)
|
||||||
|
|
||||||
wg.Add(1)
|
wg.Add(1)
|
||||||
go getAgent(wg, config.UUID, connectString)
|
go getAgent(wg, config.UUID, connectString)
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
* workerListener := fmt.Sprintf("tcp://%s:%d", config.ListenAddr, config.WorkerPort)
|
* workerListener := "tcp://" + config.ListenAddr + ":" + strconv.FormatInt(config.WorkerPort, 10)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,13 +7,18 @@ import (
|
||||||
"testing"
|
"testing"
|
||||||
)
|
)
|
||||||
|
|
||||||
func arityErr(i *Interp, name string, argv []string) error {
|
/*
|
||||||
|
* incorrectArgCountError returns an error message indicating the incorrect
|
||||||
|
* number of arguments provided for a given function. It takes an interpreter
|
||||||
|
* instance 'i', the function name 'name', and a slice of argument values 'argv'.
|
||||||
|
*/
|
||||||
|
func incorrectArgCountError(i *Interpreter, name string, argv []string) error {
|
||||||
return fmt.Errorf("wrong number of args for %s %s", name, argv)
|
return fmt.Errorf("wrong number of args for %s %s", name, argv)
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
needleInHaystack returns true if the string is in a slice
|
* needleInHaystack returns true if the string is in a slice
|
||||||
*/
|
*/
|
||||||
func needleInHaystack(needle string, haystack []string) bool {
|
func needleInHaystack(needle string, haystack []string) bool {
|
||||||
for _, haystackMember := range haystack {
|
for _, haystackMember := range haystack {
|
||||||
if haystackMember == needle {
|
if haystackMember == needle {
|
||||||
|
@ -24,9 +29,9 @@ func needleInHaystack(needle string, haystack []string) bool {
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
TestneedleInHaystack tests the return value of needleInHaystack
|
* Test_needleInHaystack tests the return value of needleInHaystack
|
||||||
*/
|
*/
|
||||||
func TestneedleInHaystack(t *testing.T) {
|
func Test_needleInHaystack(t *testing.T) {
|
||||||
var haystack = []string{"a", "b", "c"}
|
var haystack = []string{"a", "b", "c"}
|
||||||
var needle = "a"
|
var needle = "a"
|
||||||
if !needleInHaystack(needle, haystack) {
|
if !needleInHaystack(needle, haystack) {
|
||||||
|
@ -44,10 +49,12 @@ func TestneedleInHaystack(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// CommandMath is the math command for TCL
|
/*
|
||||||
func CommandMath(i *Interp, argv []string, pd interface{}) (string, error) {
|
* CommandMath is the math command for TCL
|
||||||
|
*/
|
||||||
|
func CommandMath(i *Interpreter, argv []string, pd interface{}) (string, error) {
|
||||||
if len(argv) != 3 {
|
if len(argv) != 3 {
|
||||||
return "", arityErr(i, argv[0], argv)
|
return "", incorrectArgCountError(i, argv[0], argv)
|
||||||
}
|
}
|
||||||
a, _ := strconv.Atoi(argv[1])
|
a, _ := strconv.Atoi(argv[1])
|
||||||
b, _ := strconv.Atoi(argv[2])
|
b, _ := strconv.Atoi(argv[2])
|
||||||
|
@ -91,28 +98,34 @@ func CommandMath(i *Interp, argv []string, pd interface{}) (string, error) {
|
||||||
return fmt.Sprintf("%d", c), nil
|
return fmt.Sprintf("%d", c), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// CommandSet is the set command for TCL
|
/*
|
||||||
func CommandSet(i *Interp, argv []string, pd interface{}) (string, error) {
|
* CommandSet is the set command for TCL
|
||||||
|
*/
|
||||||
|
func CommandSet(i *Interpreter, argv []string, pd interface{}) (string, error) {
|
||||||
if len(argv) != 3 {
|
if len(argv) != 3 {
|
||||||
return "", arityErr(i, argv[0], argv)
|
return "", incorrectArgCountError(i, argv[0], argv)
|
||||||
}
|
}
|
||||||
i.SetVar(argv[1], argv[2])
|
i.SetVariable(argv[1], argv[2])
|
||||||
return argv[2], nil
|
return argv[2], nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// CommandUnset is the unset command for TCL
|
/*
|
||||||
func CommandUnset(i *Interp, argv []string, pd interface{}) (string, error) {
|
* CommandUnset is the unset command for TCL
|
||||||
|
*/
|
||||||
|
func CommandUnset(i *Interpreter, argv []string, pd interface{}) (string, error) {
|
||||||
if len(argv) != 2 {
|
if len(argv) != 2 {
|
||||||
return "", arityErr(i, argv[0], argv)
|
return "", incorrectArgCountError(i, argv[0], argv)
|
||||||
}
|
}
|
||||||
i.UnsetVar(argv[1])
|
i.UnsetVariable(argv[1])
|
||||||
return "", nil
|
return "", nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// CommandIf is the if command for TCL
|
/*
|
||||||
func CommandIf(i *Interp, argv []string, pd interface{}) (string, error) {
|
* CommandIf is the if command for TCL
|
||||||
|
*/
|
||||||
|
func CommandIf(i *Interpreter, argv []string, pd interface{}) (string, error) {
|
||||||
if len(argv) != 3 && len(argv) != 5 {
|
if len(argv) != 3 && len(argv) != 5 {
|
||||||
return "", arityErr(i, argv[0], argv)
|
return "", incorrectArgCountError(i, argv[0], argv)
|
||||||
}
|
}
|
||||||
|
|
||||||
result, err := i.Eval(argv[1])
|
result, err := i.Eval(argv[1])
|
||||||
|
@ -129,10 +142,12 @@ func CommandIf(i *Interp, argv []string, pd interface{}) (string, error) {
|
||||||
return result, nil
|
return result, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// CommandWhile is the while command for TCL
|
/*
|
||||||
func CommandWhile(i *Interp, argv []string, pd interface{}) (string, error) {
|
* CommandWhile is the while command for TCL
|
||||||
|
*/
|
||||||
|
func CommandWhile(i *Interpreter, argv []string, pd interface{}) (string, error) {
|
||||||
if len(argv) != 3 {
|
if len(argv) != 3 {
|
||||||
return "", arityErr(i, argv[0], argv)
|
return "", incorrectArgCountError(i, argv[0], argv)
|
||||||
}
|
}
|
||||||
|
|
||||||
for {
|
for {
|
||||||
|
@ -143,9 +158,11 @@ func CommandWhile(i *Interp, argv []string, pd interface{}) (string, error) {
|
||||||
if r, _ := strconv.Atoi(result); r != 0 {
|
if r, _ := strconv.Atoi(result); r != 0 {
|
||||||
result, err := i.Eval(argv[2])
|
result, err := i.Eval(argv[2])
|
||||||
switch err {
|
switch err {
|
||||||
case errContinue, nil:
|
case ErrContinue, nil:
|
||||||
//pass
|
/*
|
||||||
case errBreak:
|
* pass
|
||||||
|
*/
|
||||||
|
case ErrBreak:
|
||||||
return result, nil
|
return result, nil
|
||||||
default:
|
default:
|
||||||
return result, err
|
return result, err
|
||||||
|
@ -156,22 +173,26 @@ func CommandWhile(i *Interp, argv []string, pd interface{}) (string, error) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// CommandRetCodes is a function to get the return codes for TCL
|
/*
|
||||||
func CommandRetCodes(i *Interp, argv []string, pd interface{}) (string, error) {
|
* CommandRetCodes is a function to get the return codes for TCL
|
||||||
|
*/
|
||||||
|
func CommandRetCodes(i *Interpreter, argv []string, pd interface{}) (string, error) {
|
||||||
if len(argv) != 1 {
|
if len(argv) != 1 {
|
||||||
return "", arityErr(i, argv[0], argv)
|
return "", incorrectArgCountError(i, argv[0], argv)
|
||||||
}
|
}
|
||||||
switch argv[0] {
|
switch argv[0] {
|
||||||
case "break":
|
case "break":
|
||||||
return "", errBreak
|
return "", ErrBreak
|
||||||
case "continue":
|
case "continue":
|
||||||
return "", errContinue
|
return "", ErrContinue
|
||||||
}
|
}
|
||||||
return "", nil
|
return "", nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// CommandCallProc is a function to call proc commands for TCL
|
/*
|
||||||
func CommandCallProc(i *Interp, argv []string, pd interface{}) (string, error) {
|
* CommandCallProc is a function to call proc commands for TCL
|
||||||
|
*/
|
||||||
|
func CommandCallProc(i *Interpreter, argv []string, pd interface{}) (string, error) {
|
||||||
var x []string
|
var x []string
|
||||||
|
|
||||||
if pd, ok := pd.([]string); ok {
|
if pd, ok := pd.([]string); ok {
|
||||||
|
@ -180,7 +201,7 @@ func CommandCallProc(i *Interp, argv []string, pd interface{}) (string, error) {
|
||||||
return "", nil
|
return "", nil
|
||||||
}
|
}
|
||||||
|
|
||||||
i.callframe = &CallFrame{vars: make(map[string]Var), parent: i.callframe}
|
i.callframe = &CallFrame{vars: make(map[string]Variable), parent: i.callframe}
|
||||||
defer func() { i.callframe = i.callframe.parent }() // remove the called proc callframe
|
defer func() { i.callframe = i.callframe.parent }() // remove the called proc callframe
|
||||||
|
|
||||||
arity := 0
|
arity := 0
|
||||||
|
@ -189,7 +210,7 @@ func CommandCallProc(i *Interp, argv []string, pd interface{}) (string, error) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
arity++
|
arity++
|
||||||
i.SetVar(arg, argv[arity])
|
i.SetVariable(arg, argv[arity])
|
||||||
}
|
}
|
||||||
|
|
||||||
if arity != len(argv)-1 {
|
if arity != len(argv)-1 {
|
||||||
|
@ -198,42 +219,50 @@ func CommandCallProc(i *Interp, argv []string, pd interface{}) (string, error) {
|
||||||
|
|
||||||
body := x[1]
|
body := x[1]
|
||||||
result, err := i.Eval(body)
|
result, err := i.Eval(body)
|
||||||
if err == errReturn {
|
if err == ErrReturn {
|
||||||
err = nil
|
err = nil
|
||||||
}
|
}
|
||||||
return result, err
|
return result, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// CommandProc is a function to register proc commands for TCL
|
/*
|
||||||
func CommandProc(i *Interp, argv []string, pd interface{}) (string, error) {
|
* CommandProc is a function to register proc commands for TCL
|
||||||
|
*/
|
||||||
|
func CommandProc(i *Interpreter, argv []string, pd interface{}) (string, error) {
|
||||||
if len(argv) != 4 {
|
if len(argv) != 4 {
|
||||||
return "", arityErr(i, argv[0], argv)
|
return "", incorrectArgCountError(i, argv[0], argv)
|
||||||
}
|
}
|
||||||
return "", i.RegisterCommand(argv[1], CommandCallProc, []string{argv[2], argv[3]})
|
return "", i.RegisterCommand(argv[1], CommandCallProc, []string{argv[2], argv[3]})
|
||||||
}
|
}
|
||||||
|
|
||||||
// CommandReturn is a function to register return codes for commands for TCL
|
/*
|
||||||
func CommandReturn(i *Interp, argv []string, pd interface{}) (string, error) {
|
* CommandReturn is a function to register return codes for commands for TCL
|
||||||
|
*/
|
||||||
|
func CommandReturn(i *Interpreter, argv []string, pd interface{}) (string, error) {
|
||||||
if len(argv) != 1 && len(argv) != 2 {
|
if len(argv) != 1 && len(argv) != 2 {
|
||||||
return "", arityErr(i, argv[0], argv)
|
return "", incorrectArgCountError(i, argv[0], argv)
|
||||||
}
|
}
|
||||||
var r string
|
var r string
|
||||||
if len(argv) == 2 {
|
if len(argv) == 2 {
|
||||||
r = argv[1]
|
r = argv[1]
|
||||||
}
|
}
|
||||||
return r, errReturn
|
return r, ErrReturn
|
||||||
}
|
}
|
||||||
|
|
||||||
// CommandError is a function to return error codes for commands for TCL
|
/*
|
||||||
func CommandError(i *Interp, argv []string, pd interface{}) (string, error) {
|
* CommandError is a function to return error codes for commands for TCL
|
||||||
|
*/
|
||||||
|
func CommandError(i *Interpreter, argv []string, pd interface{}) (string, error) {
|
||||||
if len(argv) != 1 && len(argv) != 2 {
|
if len(argv) != 1 && len(argv) != 2 {
|
||||||
return "", arityErr(i, argv[0], argv)
|
return "", incorrectArgCountError(i, argv[0], argv)
|
||||||
}
|
}
|
||||||
return "", fmt.Errorf(argv[1])
|
return "", fmt.Errorf(argv[1])
|
||||||
}
|
}
|
||||||
|
|
||||||
// CommandPuts is a function to print strings for TCL
|
/*
|
||||||
func CommandPuts(i *Interp, argv []string, pd interface{}) (string, error) {
|
* CommandPuts is a function to print strings for TCL
|
||||||
|
*/
|
||||||
|
func CommandPuts(i *Interpreter, argv []string, pd interface{}) (string, error) {
|
||||||
if len(argv) != 2 {
|
if len(argv) != 2 {
|
||||||
return "", fmt.Errorf("wrong number of args for %s %s", argv[0], argv)
|
return "", fmt.Errorf("wrong number of args for %s %s", argv[0], argv)
|
||||||
}
|
}
|
||||||
|
@ -241,8 +270,10 @@ func CommandPuts(i *Interp, argv []string, pd interface{}) (string, error) {
|
||||||
return "", nil
|
return "", nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// RegisterCoreCommands is a callable to register TCL commands.
|
/*
|
||||||
func (i *Interp) RegisterCoreCommands() {
|
* RegisterCoreCommands is a callable to register TCL commands.
|
||||||
|
*/
|
||||||
|
func (i *Interpreter) RegisterCoreCommands() {
|
||||||
name := [...]string{"+", "-", "*", "/", ">", ">=", "<", "<=", "==", "!="}
|
name := [...]string{"+", "-", "*", "/", ">", ">=", "<", "<=", "==", "!="}
|
||||||
for _, n := range name {
|
for _, n := range name {
|
||||||
_ = i.RegisterCommand(n, CommandMath, nil)
|
_ = i.RegisterCommand(n, CommandMath, nil)
|
||||||
|
|
|
@ -6,38 +6,66 @@ import (
|
||||||
"strings"
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Error variables
|
||||||
|
*/
|
||||||
var (
|
var (
|
||||||
errReturn = errors.New("RETURN")
|
ErrReturn = errors.New("RETURN")
|
||||||
errBreak = errors.New("BREAK")
|
ErrBreak = errors.New("BREAK")
|
||||||
errContinue = errors.New("CONTINUE")
|
ErrContinue = errors.New("CONTINUE")
|
||||||
)
|
)
|
||||||
|
|
||||||
type Var string
|
/*
|
||||||
type CmdFunc func(i *Interp, argv []string, privdata interface{}) (string, error)
|
* Variable type
|
||||||
type Cmd struct {
|
*/
|
||||||
fn CmdFunc
|
type Variable string
|
||||||
|
|
||||||
|
/*
|
||||||
|
* CommandFunc type
|
||||||
|
*/
|
||||||
|
type CommandFunc func(interp *Interpreter, argv []string, privdata interface{}) (string, error)
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Command structure
|
||||||
|
*/
|
||||||
|
type Command struct {
|
||||||
|
fn CommandFunc
|
||||||
privdata interface{}
|
privdata interface{}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* CallFrame structure
|
||||||
|
*/
|
||||||
type CallFrame struct {
|
type CallFrame struct {
|
||||||
vars map[string]Var
|
vars map[string]Variable
|
||||||
parent *CallFrame
|
parent *CallFrame
|
||||||
}
|
}
|
||||||
type Interp struct {
|
|
||||||
|
/*
|
||||||
|
* Interpreter structure
|
||||||
|
*/
|
||||||
|
type Interpreter struct {
|
||||||
level int
|
level int
|
||||||
callframe *CallFrame
|
callframe *CallFrame
|
||||||
commands map[string]Cmd
|
commands map[string]Command
|
||||||
}
|
}
|
||||||
|
|
||||||
func InitInterp() *Interp {
|
/*
|
||||||
return &Interp{
|
* NewInterpreter initializes a new Interpreter
|
||||||
|
*/
|
||||||
|
func NewInterpreter() *Interpreter {
|
||||||
|
return &Interpreter{
|
||||||
level: 0,
|
level: 0,
|
||||||
callframe: &CallFrame{vars: make(map[string]Var)},
|
callframe: &CallFrame{vars: make(map[string]Variable)},
|
||||||
commands: make(map[string]Cmd),
|
commands: make(map[string]Command),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (i *Interp) Var(name string) (Var, bool) {
|
/*
|
||||||
for frame := i.callframe; frame != nil; frame = frame.parent {
|
* Variable retrieves a variable's value
|
||||||
|
*/
|
||||||
|
func (interp *Interpreter) Variable(name string) (Variable, bool) {
|
||||||
|
for frame := interp.callframe; frame != nil; frame = frame.parent {
|
||||||
v, ok := frame.vars[name]
|
v, ok := frame.vars[name]
|
||||||
if ok {
|
if ok {
|
||||||
return v, ok
|
return v, ok
|
||||||
|
@ -45,94 +73,112 @@ func (i *Interp) Var(name string) (Var, bool) {
|
||||||
}
|
}
|
||||||
return "", false
|
return "", false
|
||||||
}
|
}
|
||||||
func (i *Interp) SetVar(name, val string) {
|
|
||||||
i.callframe.vars[name] = Var(val)
|
/*
|
||||||
|
* SetVariable sets a variable's value
|
||||||
|
*/
|
||||||
|
func (interp *Interpreter) SetVariable(name, val string) {
|
||||||
|
interp.callframe.vars[name] = Variable(val)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (i *Interp) UnsetVar(name string) {
|
/*
|
||||||
delete(i.callframe.vars, name)
|
* UnsetVariable removes a variable
|
||||||
|
*/
|
||||||
|
func (interp *Interpreter) UnsetVariable(name string) {
|
||||||
|
delete(interp.callframe.vars, name)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (i *Interp) Command(name string) *Cmd {
|
/*
|
||||||
v, ok := i.commands[name]
|
* Command retrieves a command
|
||||||
|
*/
|
||||||
|
func (interp *Interpreter) Command(name string) *Command {
|
||||||
|
v, ok := interp.commands[name]
|
||||||
if !ok {
|
if !ok {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
return &v
|
return &v
|
||||||
}
|
}
|
||||||
|
|
||||||
func (i *Interp) RegisterCommand(name string, fn CmdFunc, privdata interface{}) error {
|
/*
|
||||||
c := i.Command(name)
|
* RegisterCommand registers a new command
|
||||||
if c != nil {
|
*/
|
||||||
|
func (interp *Interpreter) RegisterCommand(name string, fn CommandFunc, privdata interface{}) error {
|
||||||
|
cmd := interp.Command(name)
|
||||||
|
if cmd != nil {
|
||||||
return fmt.Errorf("Command '%s' already defined", name)
|
return fmt.Errorf("Command '%s' already defined", name)
|
||||||
}
|
}
|
||||||
|
|
||||||
i.commands[name] = Cmd{fn, privdata}
|
interp.commands[name] = Command{fn, privdata}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
/* EVAL! */
|
/*
|
||||||
func (i *Interp) Eval(t string) (string, error) {
|
* Eval evaluates a script
|
||||||
p := initParser(t)
|
*/
|
||||||
|
func (interp *Interpreter) Eval(script string) (string, error) {
|
||||||
|
parser := initParser(script)
|
||||||
var result string
|
var result string
|
||||||
var err error
|
var err error
|
||||||
|
|
||||||
argv := []string{}
|
argv := []string{}
|
||||||
|
|
||||||
for {
|
for {
|
||||||
prevtype := p.Type
|
prevType := parser.Type
|
||||||
// XXX
|
token := parser.GetToken()
|
||||||
t = p.GetToken()
|
if parser.Type == ptEOF {
|
||||||
if p.Type == ptEOF {
|
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|
||||||
switch p.Type {
|
switch parser.Type {
|
||||||
case ptVAR:
|
case ptVAR:
|
||||||
v, ok := i.Var(t)
|
v, ok := interp.Variable(token)
|
||||||
if !ok {
|
if !ok {
|
||||||
return "", fmt.Errorf("no such variable '%s'", t)
|
return "", fmt.Errorf("no such variable '%s'", token)
|
||||||
}
|
}
|
||||||
t = string(v)
|
token = string(v)
|
||||||
case ptCMD:
|
case ptCMD:
|
||||||
result, err = i.Eval(t)
|
result, err = interp.Eval(token)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return result, err
|
return result, err
|
||||||
} else {
|
|
||||||
t = result
|
|
||||||
}
|
}
|
||||||
|
token = result
|
||||||
case ptESC:
|
case ptESC:
|
||||||
// XXX: escape handling missing!
|
/*
|
||||||
|
* TODO: escape handling missing!
|
||||||
|
*/
|
||||||
case ptSEP:
|
case ptSEP:
|
||||||
prevtype = p.Type
|
prevType = parser.Type
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
// We have a complete command + args. Call it!
|
if parser.Type == ptEOL {
|
||||||
if p.Type == ptEOL {
|
prevType = parser.Type
|
||||||
prevtype = p.Type
|
|
||||||
if len(argv) != 0 {
|
if len(argv) != 0 {
|
||||||
c := i.Command(argv[0])
|
cmd := interp.Command(argv[0])
|
||||||
if c == nil {
|
if cmd == nil {
|
||||||
return "", fmt.Errorf("no such command '%s'", argv[0])
|
return "", fmt.Errorf("no such command '%s'", argv[0])
|
||||||
}
|
}
|
||||||
result, err = c.fn(i, argv, c.privdata)
|
result, err = cmd.fn(interp, argv, cmd.privdata)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return result, err
|
return result, err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Prepare for the next command
|
/*
|
||||||
|
* Prepare for the next command
|
||||||
|
*/
|
||||||
argv = []string{}
|
argv = []string{}
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
// We have a new token, append to the previous or as new arg?
|
/*
|
||||||
if prevtype == ptSEP || prevtype == ptEOL {
|
* We have a new token, append to the previous or as new arg?
|
||||||
argv = append(argv, t)
|
*/
|
||||||
|
if prevType == ptSEP || prevType == ptEOL {
|
||||||
|
argv = append(argv, token)
|
||||||
} else { // Interpolation
|
} else { // Interpolation
|
||||||
argv[len(argv)-1] = strings.Join([]string{argv[len(argv)-1], t}, "")
|
argv[len(argv)-1] = strings.Join([]string{argv[len(argv)-1], token}, "")
|
||||||
}
|
}
|
||||||
prevtype = p.Type
|
prevType = parser.Type
|
||||||
}
|
}
|
||||||
return result, nil
|
return result, nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,13 +7,13 @@ import (
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"os"
|
"os"
|
||||||
|
|
||||||
picol "github.com/dragonheim/gagent/src/picol"
|
picol "github.com/dragonheim/gagent/pkg/picol"
|
||||||
)
|
)
|
||||||
|
|
||||||
var fname = flag.String("f", "", "file name")
|
var fname = flag.String("f", "", "file name")
|
||||||
|
|
||||||
// CommandPuts is a simple version of the TCL puts function.
|
// CommandPuts is a simple version of the TCL puts function.
|
||||||
func CommandPuts(i *picol.Interp, argv []string, pd interface{}) (string, error) {
|
func CommandPuts(i *picol.Interpreter, argv []string, pd interface{}) (string, error) {
|
||||||
if len(argv) != 2 {
|
if len(argv) != 2 {
|
||||||
return "", fmt.Errorf("wrong number of args for %s %s", argv[0], argv)
|
return "", fmt.Errorf("wrong number of args for %s %s", argv[0], argv)
|
||||||
}
|
}
|
||||||
|
@ -23,7 +23,7 @@ func CommandPuts(i *picol.Interp, argv []string, pd interface{}) (string, error)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
flag.Parse()
|
flag.Parse()
|
||||||
interp := picol.InitInterp()
|
interp := picol.NewInterpreter()
|
||||||
interp.RegisterCoreCommands()
|
interp.RegisterCoreCommands()
|
||||||
interp.RegisterCommand("puts", CommandPuts, nil)
|
interp.RegisterCommand("puts", CommandPuts, nil)
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue