server
This commit is contained in:
69
repl.go
69
repl.go
@@ -6,6 +6,7 @@ import (
|
||||
"github.com/tebeka/atexit"
|
||||
"io"
|
||||
"log"
|
||||
"monkey/internal/context"
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
@@ -21,10 +22,7 @@ import (
|
||||
// by lexing, parsing and evaluating the input in the interpreter
|
||||
|
||||
// REPL provides a read-eval-print loop for the monkey virtual machine.
|
||||
func REPL(args []string, debug, trace bool) error {
|
||||
var state = vm.NewState()
|
||||
|
||||
object.Args = args
|
||||
func REPL(args []string, opts *Options) error {
|
||||
|
||||
initState, err := term.MakeRaw(0)
|
||||
if err != nil {
|
||||
@@ -44,9 +42,14 @@ func REPL(args []string, debug, trace bool) error {
|
||||
t := term.NewTerminal(os.Stdin, ">>> ")
|
||||
t.AutoCompleteCallback = autoComplete
|
||||
|
||||
object.Args = args
|
||||
object.Stdout = t
|
||||
object.ExitFunction = atexit.Exit
|
||||
ctx := context.New(
|
||||
context.WithArgs(args),
|
||||
context.WithStdout(t),
|
||||
context.WithStderr(t),
|
||||
context.WithExit(atexit.Exit),
|
||||
)
|
||||
|
||||
state := vm.NewState()
|
||||
|
||||
PrintVersionInfo(t)
|
||||
for {
|
||||
@@ -67,25 +70,30 @@ func REPL(args []string, debug, trace bool) error {
|
||||
continue
|
||||
}
|
||||
|
||||
if debug {
|
||||
if opts.Debug {
|
||||
log.Printf("AST:\n%s\n", res)
|
||||
}
|
||||
|
||||
c := compiler.NewWithState(state.Symbols, &state.Constants)
|
||||
c.Debug = debug
|
||||
c.Debug = opts.Debug
|
||||
c.SetFileInfo("<stdin>", input)
|
||||
if err := c.Compile(res); err != nil {
|
||||
fmt.Fprintln(t, err)
|
||||
continue
|
||||
}
|
||||
|
||||
if debug {
|
||||
if opts.Debug {
|
||||
log.Printf("Bytecode:\n%s\n", c.Bytecode())
|
||||
}
|
||||
|
||||
mvm := vm.NewWithState("<stdin>", c.Bytecode(), state)
|
||||
mvm.Debug = debug
|
||||
mvm.Trace = trace
|
||||
opts := []vm.Option{
|
||||
vm.WithContext(ctx),
|
||||
vm.WithDebug(opts.Debug),
|
||||
vm.WithTrace(opts.Trace),
|
||||
vm.WithState(state),
|
||||
}
|
||||
|
||||
mvm := vm.New("<stdin>", c.Bytecode(), opts...)
|
||||
|
||||
if err := mvm.Run(); err != nil {
|
||||
fmt.Fprintf(t, "runtime error: %v\n", err)
|
||||
@@ -144,11 +152,8 @@ func acceptUntil(t *term.Terminal, start, end string) (string, error) {
|
||||
}
|
||||
|
||||
// SimpleREPL provides a simple read-eval-print loop for the monkey virtual machine.
|
||||
func SimpleREPL(args []string, debug, trace bool) {
|
||||
var (
|
||||
state = vm.NewState()
|
||||
reader = bufio.NewReader(os.Stdin)
|
||||
)
|
||||
func SimpleREPL(args []string, opts *Options) {
|
||||
var reader = bufio.NewReader(os.Stdin)
|
||||
|
||||
defer func() {
|
||||
if err := recover(); err != nil {
|
||||
@@ -159,9 +164,14 @@ func SimpleREPL(args []string, debug, trace bool) {
|
||||
t := term.NewTerminal(os.Stdin, ">>> ")
|
||||
t.AutoCompleteCallback = autoComplete
|
||||
|
||||
object.Args = args
|
||||
object.Stdout = t
|
||||
object.ExitFunction = atexit.Exit
|
||||
ctx := context.New(
|
||||
context.WithArgs(args),
|
||||
context.WithStdout(t),
|
||||
context.WithStderr(t),
|
||||
context.WithExit(atexit.Exit),
|
||||
)
|
||||
|
||||
state := vm.NewState()
|
||||
|
||||
PrintVersionInfo(os.Stdout)
|
||||
for {
|
||||
@@ -183,25 +193,30 @@ func SimpleREPL(args []string, debug, trace bool) {
|
||||
continue
|
||||
}
|
||||
|
||||
if debug {
|
||||
if opts.Debug {
|
||||
log.Printf("AST:\n%s\n", res)
|
||||
}
|
||||
|
||||
c := compiler.NewWithState(state.Symbols, &state.Constants)
|
||||
c.Debug = debug
|
||||
c.Debug = opts.Debug
|
||||
c.SetFileInfo("<stdin>", input)
|
||||
if err := c.Compile(res); err != nil {
|
||||
fmt.Println(err)
|
||||
continue
|
||||
}
|
||||
|
||||
if debug {
|
||||
if opts.Debug {
|
||||
log.Printf("Bytecode:\n%s\n", c.Bytecode())
|
||||
}
|
||||
|
||||
mvm := vm.NewWithState("<stdin>", c.Bytecode(), state)
|
||||
mvm.Debug = debug
|
||||
mvm.Trace = trace
|
||||
opts := []vm.Option{
|
||||
vm.WithContext(ctx),
|
||||
vm.WithDebug(opts.Debug),
|
||||
vm.WithTrace(opts.Trace),
|
||||
vm.WithState(state),
|
||||
}
|
||||
|
||||
mvm := vm.New("<stdin>", c.Bytecode(), opts...)
|
||||
|
||||
if err := mvm.Run(); err != nil {
|
||||
fmt.Printf("runtime error: %v\n", err)
|
||||
|
||||
Reference in New Issue
Block a user