// run runs until EOF or error. The return value says whether we completed without error. func run(p *parse.Parser, writer io.Writer, context value.Context, interactive bool) (success bool) { defer func() { if conf.Debug("panic") { return } err := recover() if err == nil { return } p.FlushToNewline() if err, ok := err.(value.Error); ok { fmt.Fprintf(os.Stderr, "%s: %s\n", p.Loc(), err) if interactive { fmt.Fprintln(writer) } success = false return } panic(err) }() for { if interactive { fmt.Fprint(writer, conf.Prompt()) } exprs, ok := p.Line() var values []value.Value if exprs != nil { values = context.Eval(exprs) } if values != nil { if conf.Debug("types") { for i, v := range values { if i > 0 { fmt.Fprint(writer, ",") } fmt.Fprintf(writer, "%T", v) } fmt.Fprintln(writer) } for i, v := range values { s := v.String() if i > 0 && len(s) > 0 && s[len(s)-1] != '\n' { fmt.Fprint(writer, " ") } fmt.Fprint(writer, v) } fmt.Fprintln(writer) context.Assign("_", values[len(values)-1]) } if !ok { return true } if interactive { fmt.Fprintln(writer) } } }
func (b *binary) Eval(context value.Context) value.Value { rhs := b.right.Eval(context) if b.op == "=" { // Special handling as we cannot evaluate the left. // We know the left is a variableExpr. lhs := b.left.(variableExpr) context.Assign(lhs.name, rhs) return Assignment{Value: rhs} } lhs := b.left.Eval(context) return context.EvalBinary(lhs, b.op, rhs) }
// Run runs the parser/evaluator until EOF or error. // The return value says whether we completed without error. If the return // value is true, it means we ran out of data (EOF) and the run was successful. // Typical execution is therefore to loop calling Run until it succeeds. // Error details are reported to the configured error output stream. func Run(p *parse.Parser, context value.Context, interactive bool) (success bool) { conf := context.Config() writer := conf.Output() defer func() { if conf.Debug("panic") { return } err := recover() if err == nil { return } p.FlushToNewline() if err, ok := err.(value.Error); ok { fmt.Fprintf(conf.ErrOutput(), "%s%s\n", p.Loc(), err) if interactive { fmt.Fprintln(writer) } success = false return } panic(err) }() for { if interactive { fmt.Fprint(writer, conf.Prompt()) } exprs, ok := p.Line() var values []value.Value if exprs != nil { if interactive { start := time.Now() values = context.Eval(exprs) conf.SetCPUTime(time.Now().Sub(start)) } else { values = context.Eval(exprs) } } if printValues(conf, writer, values) { context.Assign("_", values[len(values)-1]) } if !ok { return true } if interactive { if exprs != nil && conf.Debug("cpu") && conf.CPUTime() != 0 { fmt.Printf("(%s)\n", conf.PrintCPUTime()) } fmt.Fprintln(writer) } } }
// run runs until EOF or error. The return value says whether we completed without error. func run(p *parse.Parser, context value.Context, interactive bool) (success bool) { writer := conf.Output() defer func() { if conf.Debug("panic") { return } err := recover() if err == nil { return } p.FlushToNewline() if err, ok := err.(value.Error); ok { fmt.Fprintf(os.Stderr, "%s%s\n", p.Loc(), err) if interactive { fmt.Fprintln(writer) } success = false return } panic(err) }() for { if interactive { fmt.Fprint(writer, conf.Prompt()) } exprs, ok := p.Line() var values []value.Value if exprs != nil { values = context.Eval(exprs) } if values != nil { printValues(writer, values) context.Assign("_", values[len(values)-1]) } if !ok { return true } if interactive { fmt.Fprintln(writer) } } }
func (a *assignment) Eval(context value.Context) value.Value { context.Assign(a.variable.name, a.expr.Eval(context)) return nil }