repl

package
v0.12.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 16, 2020 License: MIT Imports: 6 Imported by: 0

Documentation

Overview

Package repl provides a layer intended to help with the development of a read-eval-print loop.

Example
package main

import (
	"fmt"
	"os"
	"reflect"

	"github.com/DeedleFake/wdte/repl"
	"github.com/DeedleFake/wdte/std"
	_ "github.com/DeedleFake/wdte/std/all"
	"github.com/peterh/liner"
)

var (
	mode = ">>> "
)

func next(lr *liner.State) repl.NextFunc {
	return func() ([]byte, error) {
		line, err := lr.Prompt(mode)
		return []byte(line + "\n"), err
	}
}

func main() {
	lr := liner.NewLiner()
	lr.SetCtrlCAborts(true)
	defer lr.Close()

	r := repl.New(next(lr), std.Import, nil, std.Scope)

	for {
		ret, err := r.Next()
		if err != nil {
			if err == repl.ErrIncomplete {
				mode = "... "
				continue
			}

			if err == liner.ErrPromptAborted {
				r.Cancel()
				mode = ">>> "
				continue
			}

			fmt.Fprintf(os.Stderr, "Error: %v\n", err)
			continue
		}
		if ret == nil {
			break
		}

		switch reflect.Indirect(reflect.ValueOf(ret)).Kind() {
		case reflect.Struct:
			fmt.Printf(": complex value\n")

		default:
			fmt.Printf(": %v\n", ret)
		}

		mode = ">>> "
	}
}
Output:

Index

Examples

Constants

This section is empty.

Variables

View Source
var (
	// ErrIncomplete is returned by REPL.Next() if it expects more input
	// before it will begin evaluation.
	ErrIncomplete = errors.New("input incomplete")
)

Functions

func Partial

func Partial(r io.Reader, stack []string, macros scanner.MacroMap) ([]string, bool)

Partial checks if an expression, read from r, is incomplete. The initial value of stack should be nil, and subsequent values should be the value of the first return. The second return is true if the expression was incomplete.

Example
package main

import (
	"fmt"
	"strings"

	"github.com/DeedleFake/wdte/repl"
)

func main() {
	stack, partial := repl.Partial(strings.NewReader("let io =>"), nil, nil)
	fmt.Println(partial)

	stack, partial = repl.Partial(strings.NewReader("import 'io'"), stack, nil)
	fmt.Println(partial)

	_, partial = repl.Partial(strings.NewReader(";"), stack, nil)
	fmt.Println(partial)
}
Output:

true
true
false

Types

type NextFunc

type NextFunc func() ([]byte, error)

A NextFunc returns the next piece of code to be interpreted. When reading from stdin, this is likely the next line entered.

If NextFunc should not be called again, it should return nil, io.EOF.

func SimpleNext

func SimpleNext(r io.Reader) NextFunc

SimpleNext returns a next func that scans lines from r.

type REPL

type REPL struct {
	// Scope is the scope that the next line will be executed in. It is
	// automatically updated every time an executed line changes the
	// scope.
	Scope *wdte.Scope
	// contains filtered or unexported fields
}

REPL provides a means to track a global state and interpret separate lines of a WDTE script, allowing for the implementation of a read-eval-print loop.

func New

func New(next NextFunc, im wdte.Importer, macros scanner.MacroMap, start *wdte.Scope) *REPL

New creates a new REPL which reads with next, imports using im, and executes the first line with the scope start.

func (*REPL) Cancel

func (r *REPL) Cancel()

Cancel cancels a partial expression. This is useful if, for example, a user sends an interrupt to a command-line REPL while entering a subsequent line of a multi-line expression.

If a partial expression is not in progress, this has no effect.

func (*REPL) Next

func (r *REPL) Next() (ret wdte.Func, err error)

Next reads and evaluates the next line of input. It returns the value returned from that line, or an error if one is encountered. If the end of the input has been reached, it will return nil, nil.

If an input ends in a partial expression, such as a single line of a mult-line expression, nil, ErrIncomplete is returned.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL