Skip to content

Commit

Permalink
fix context not being shared across repl invocations
Browse files Browse the repository at this point in the history
  • Loading branch information
xrstf committed Nov 17, 2023
1 parent 5b1aa39 commit 270ce92
Show file tree
Hide file tree
Showing 3 changed files with 27 additions and 20 deletions.
26 changes: 14 additions & 12 deletions cmd/otti/repl.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,9 @@ func replRun(opts *options, args []string) error {
return fmt.Errorf("failed to read %q: %w", args[0], err)
}

vars := eval.NewVariables()
ctx := eval.NewContext(document, builtin.Functions, vars)

fmt.Println("Welcome to Otti 🐘")
fmt.Println("Type `help` fore more information, `exit` or Ctrl-C to exit.")
fmt.Println("")
Expand All @@ -61,53 +64,52 @@ func replRun(opts *options, args []string) error {
for reader.Scan() {
input := cleanInput(reader.Text())

stop, err := processReplInput(opts, &document, input)
newCtx, stop, err := processReplInput(ctx, opts, &document, input)
if err != nil {
fmt.Printf("Error: %v\n", err)
}
if stop {
break
}
printPrompt()

ctx = newCtx
}

fmt.Println()

return nil
}

func processReplInput(opts *options, doc *types.Document, input string) (stop bool, err error) {
func processReplInput(ctx types.Context, opts *options, doc *types.Document, input string) (newCtx types.Context, stop bool, err error) {
if command, exists := replCommands[input]; exists {
return false, command()
return ctx, false, command()
}

if strings.EqualFold("exit", input) {
return true, nil
return ctx, true, nil
}

// parse input
got, err := parser.Parse("(repl)", []byte(input))
if err != nil {
return false, err
return ctx, false, err
// fmt.Println(caretError(err, string(content)))
// os.Exit(1)
}

program, ok := got.(ast.Program)
if !ok {
return false, fmt.Errorf("parsed input is not a ast.Program, but %T", got)
return ctx, false, fmt.Errorf("parsed input is not a ast.Program, but %T", got)
}

vars := eval.NewVariables()
ctx := eval.NewContext(*doc, builtin.Functions, vars)

evaluated, err := eval.Run(ctx, program)
newCtx, evaluated, err := eval.Run(ctx, program)
if err != nil {
return false, err
return ctx, false, err
}

encoder := json.NewEncoder(os.Stdout)
encoder.Encode(evaluated)

return false, nil
return newCtx, false, nil
}
13 changes: 9 additions & 4 deletions pkg/lang/eval/eval.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,16 @@ import (
"go.xrstf.de/otto/pkg/lang/eval/types"
)

func Run(ctx types.Context, p ast.Program) (any, error) {
result, err := EvalProgram(ctx, p)
func Run(ctx types.Context, p ast.Program) (types.Context, any, error) {
newCtx, result, err := EvalProgram(ctx, p)
if err != nil {
return nil, err
return ctx, nil, err
}

return types.UnwrapType(result)
unwrapped, err := types.UnwrapType(result)
if err != nil {
return ctx, nil, err
}

return newCtx, unwrapped, nil
}
8 changes: 4 additions & 4 deletions pkg/lang/eval/eval_program.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,12 @@ import (
"go.xrstf.de/otto/pkg/lang/eval/types"
)

func EvalProgram(ctx types.Context, p ast.Program) (any, error) {
func EvalProgram(ctx types.Context, p ast.Program) (types.Context, any, error) {
innerCtx := ctx

if p.Expression != nil {
_, result, err := EvalExpression(innerCtx, p.Expression)
return result, err
return ctx, result, err
}

var (
Expand All @@ -26,9 +26,9 @@ func EvalProgram(ctx types.Context, p ast.Program) (any, error) {
for _, stmt := range p.Statements {
innerCtx, result, err = EvalStatement(innerCtx, stmt)
if err != nil {
return nil, fmt.Errorf("failed to eval statement %s: %w", stmt.String(), err)
return ctx, nil, fmt.Errorf("failed to eval statement %s: %w", stmt.String(), err)
}
}

return result, nil
return innerCtx, result, nil
}

0 comments on commit 270ce92

Please sign in to comment.