From 6fcff33777b5e10e63dbcf47a6a82e3a5504287e Mon Sep 17 00:00:00 2001 From: Craig Silverstein Date: Thu, 21 Sep 2023 13:42:58 -0700 Subject: [PATCH] Honor the `-w` flag in REPL mode. Right now, `-w` (write-decls-and-statements) is only used when gomacro is called with file arguments. But it might be useful to save a record of what was run for interactive mode as well. For instance, you might want to play around with some code interactively, save the results, and then use that as the basis of writing a script. This PR makes it so `-w` is respected when run as a REPL. In the existing (file-based) usage, the output of `-w` is based on the filename. For the new, REPL case there's nothing to base the ouptut filename on, so I just hard-code a name. Test plan: I ran the following: ``` gomacro% go run . -w // Welcome to gomacro. Type :help for help, :copy for copyright and license. // This is free software with ABSOLUTELY NO WARRANTY. gomacro> func() { return 5; } repl.go:1:8: expected 'IDENT', found '{' gomacro> func a() { return 5; } return: expecting 0 expressions, found 1: return 5 gomacro> a := func() int { return 5 } gomacro> :exit gomacro% cat repl.go // ------------------------------------------------------------- // DO NOT EDIT! this file was generated automatically by gomacro // Any change will be lost when the file is re-generated // ------------------------------------------------------------- // REPL run: 2023-09-21T13:42:27-07:00 package main func a() { return 5 } var a = func() { return 5 } var a = func() int { return 5 } ``` which shows that the declarations are being saved and emitted as expected. --- cmd/cmd.go | 35 ++++++++++++++++++++++++++--------- 1 file changed, 26 insertions(+), 9 deletions(-) diff --git a/cmd/cmd.go b/cmd/cmd.go index d8417a5c..b0192e93 100644 --- a/cmd/cmd.go +++ b/cmd/cmd.go @@ -23,6 +23,7 @@ import ( "io/ioutil" "os" "strings" + "time" . "github.com/cosmos72/gomacro/base" "github.com/cosmos72/gomacro/base/genimport" @@ -69,7 +70,7 @@ func (cmd *Cmd) Main(args []string) (err error) { g := &ir.Comp.Globals var set, clear Options - var repl, forcerepl = true, false + repl, forcerepl := true, false cmd.WriteDeclsAndStmts = false cmd.OverwriteFiles = false @@ -147,9 +148,20 @@ func (cmd *Cmd) Main(args []string) (err error) { args = args[1:] } if repl || forcerepl { + if cmd.WriteDeclsAndStmts { + g.Options |= OptCollectDeclarations | OptCollectStatements + } g.Options |= OptShowPrompt | OptShowEval | OptShowEvalType // set by default, overridden by -s, -v and -vv g.Options = (g.Options | set) &^ clear ir.ReplStdin() + + if cmd.WriteDeclsAndStmts { + cmd.writeDeclAndStatements( + "repl.go", + fmt.Sprintf("// REPL run: %v\n", time.Now().Format(time.RFC3339)), + ) + } + } return nil } @@ -238,6 +250,18 @@ const disclaimer = `// --------------------------------------------------------- ` +func (cmd *Cmd) writeDeclAndStatements(outname string, comments string) { + g := &cmd.Interp.Comp.Globals + if !cmd.OverwriteFiles { + _, err := os.Stat(outname) + if err == nil { + g.Warnf("file exists already, use -f to force overwriting: %v", outname) + return + } + } + g.WriteDeclsToFile(outname, disclaimer, comments) +} + func (cmd *Cmd) EvalFile(filename string) error { g := &cmd.Interp.Comp.Globals g.Declarations = nil @@ -257,14 +281,7 @@ func (cmd *Cmd) EvalFile(filename string) error { } } outname += ".go" - if !cmd.OverwriteFiles { - _, err := os.Stat(outname) - if err == nil { - g.Warnf("file exists already, use -f to force overwriting: %v", outname) - return nil - } - } - g.WriteDeclsToFile(outname, disclaimer, comments) + cmd.writeDeclAndStatements(outname, comments) if g.Options&OptShowEval != 0 { fmt.Fprintf(g.Stdout, "// processed file: %v\t-> %v\n", filename, outname)