Added variables and variable setting
Just string variables for name
This commit is contained in:
parent
1506692198
commit
41a4d7fd25
|
@ -12,6 +12,7 @@ type astLiteral struct {
|
||||||
|
|
||||||
type astCmdArg struct {
|
type astCmdArg struct {
|
||||||
Literal *astLiteral `parser:"@@"`
|
Literal *astLiteral `parser:"@@"`
|
||||||
|
Var *string `parser:"| '$' @Ident"`
|
||||||
Sub *astPipeline `parser:"| '(' @@ ')'"`
|
Sub *astPipeline `parser:"| '(' @@ ')'"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -25,6 +25,23 @@ func echoBuiltin(ctx context.Context, args invocationArgs) (object, error) {
|
||||||
return asStream(line.String()), nil
|
return asStream(line.String()), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func setBuiltin(ctx context.Context, args invocationArgs) (object, error) {
|
||||||
|
if err := args.expectArgn(2); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
name, err := args.stringArg(0)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
newVal := args.args[1]
|
||||||
|
|
||||||
|
// TODO: if the value is a stream, consume the stream and save it as a list
|
||||||
|
args.ec.setVar(name, newVal)
|
||||||
|
return newVal, nil
|
||||||
|
}
|
||||||
|
|
||||||
func toUpperBuiltin(ctx context.Context, inStream stream, args invocationArgs) (object, error) {
|
func toUpperBuiltin(ctx context.Context, inStream stream, args invocationArgs) (object, error) {
|
||||||
// Handle args
|
// Handle args
|
||||||
return mapFilterStream{
|
return mapFilterStream{
|
||||||
|
|
|
@ -8,6 +8,7 @@ type evalCtx struct {
|
||||||
parent *evalCtx
|
parent *evalCtx
|
||||||
currentStream stream
|
currentStream stream
|
||||||
commands map[string]invokable
|
commands map[string]invokable
|
||||||
|
vars map[string]object
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ec *evalCtx) withCurrentStream(s stream) *evalCtx {
|
func (ec *evalCtx) withCurrentStream(s stream) *evalCtx {
|
||||||
|
@ -25,6 +26,27 @@ func (ec *evalCtx) addCmd(name string, inv invokable) {
|
||||||
ec.commands[name] = inv
|
ec.commands[name] = inv
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (ec *evalCtx) setVar(name string, val object) {
|
||||||
|
if ec.vars == nil {
|
||||||
|
ec.vars = make(map[string]object)
|
||||||
|
}
|
||||||
|
ec.vars[name] = val
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ec *evalCtx) getVar(name string) (object, bool) {
|
||||||
|
if ec.vars == nil {
|
||||||
|
return nil, false
|
||||||
|
}
|
||||||
|
|
||||||
|
if v, ok := ec.vars[name]; ok {
|
||||||
|
return v, true
|
||||||
|
} else if ec.parent != nil {
|
||||||
|
return ec.parent.getVar(name)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil, false
|
||||||
|
}
|
||||||
|
|
||||||
func (ec *evalCtx) lookupCmd(name string) (invokable, error) {
|
func (ec *evalCtx) lookupCmd(name string) (invokable, error) {
|
||||||
for e := ec; e != nil; e = e.parent {
|
for e := ec; e != nil; e = e.parent {
|
||||||
if e.commands == nil {
|
if e.commands == nil {
|
||||||
|
|
|
@ -45,9 +45,11 @@ func (e evaluator) evalCmd(ctx context.Context, ec *evalCtx, ast *astCmd) (objec
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
invArgs := invocationArgs{ec: ec, args: args}
|
||||||
|
|
||||||
if ec.currentStream != nil {
|
if ec.currentStream != nil {
|
||||||
if si, ok := cmd.(streamInvokable); ok {
|
if si, ok := cmd.(streamInvokable); ok {
|
||||||
return si.invokeWithStream(ctx, ec.currentStream, invocationArgs{args: args})
|
return si.invokeWithStream(ctx, ec.currentStream, invArgs)
|
||||||
} else {
|
} else {
|
||||||
if err := ec.currentStream.close(); err != nil {
|
if err := ec.currentStream.close(); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
@ -55,13 +57,19 @@ func (e evaluator) evalCmd(ctx context.Context, ec *evalCtx, ast *astCmd) (objec
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return cmd.invoke(ctx, invocationArgs{args: args})
|
return cmd.invoke(ctx, invArgs)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e evaluator) evalArg(ctx context.Context, ec *evalCtx, n astCmdArg) (object, error) {
|
func (e evaluator) evalArg(ctx context.Context, ec *evalCtx, n astCmdArg) (object, error) {
|
||||||
switch {
|
switch {
|
||||||
case n.Literal != nil:
|
case n.Literal != nil:
|
||||||
return e.evalLiteral(ctx, ec, n.Literal)
|
return e.evalLiteral(ctx, ec, n.Literal)
|
||||||
|
case n.Var != nil:
|
||||||
|
v, ok := ec.getVar(*n.Var)
|
||||||
|
if !ok {
|
||||||
|
return nil, fmt.Errorf("unknown variable %s", *n.Var)
|
||||||
|
}
|
||||||
|
return v, nil
|
||||||
case n.Sub != nil:
|
case n.Sub != nil:
|
||||||
return e.evalSub(ctx, ec, n.Sub)
|
return e.evalSub(ctx, ec, n.Sub)
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,11 +13,14 @@ type Inst struct {
|
||||||
func New() *Inst {
|
func New() *Inst {
|
||||||
rootEC := evalCtx{}
|
rootEC := evalCtx{}
|
||||||
rootEC.addCmd("echo", invokableFunc(echoBuiltin))
|
rootEC.addCmd("echo", invokableFunc(echoBuiltin))
|
||||||
|
rootEC.addCmd("set", invokableFunc(setBuiltin))
|
||||||
rootEC.addCmd("toUpper", invokableStreamFunc(toUpperBuiltin))
|
rootEC.addCmd("toUpper", invokableStreamFunc(toUpperBuiltin))
|
||||||
rootEC.addCmd("cat", invokableFunc(catBuiltin))
|
rootEC.addCmd("cat", invokableFunc(catBuiltin))
|
||||||
|
|
||||||
rootEC.addCmd("testTimebomb", invokableStreamFunc(errorTestBuiltin))
|
rootEC.addCmd("testTimebomb", invokableStreamFunc(errorTestBuiltin))
|
||||||
|
|
||||||
|
rootEC.setVar("hello", strObject("world"))
|
||||||
|
|
||||||
return &Inst{
|
return &Inst{
|
||||||
rootEC: &rootEC,
|
rootEC: &rootEC,
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,6 +17,7 @@ func (s strObject) String() string {
|
||||||
}
|
}
|
||||||
|
|
||||||
type invocationArgs struct {
|
type invocationArgs struct {
|
||||||
|
ec *evalCtx
|
||||||
args []object
|
args []object
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue