|
1 | 1 | package main
|
2 | 2 |
|
3 | 3 | import (
|
4 |
| - "bufio" |
5 | 4 | "encoding/json"
|
6 | 5 | "errors"
|
7 | 6 | "fmt"
|
| 7 | + "go/ast" |
8 | 8 | "io"
|
9 | 9 | "io/ioutil"
|
10 | 10 | "log"
|
11 | 11 | "os"
|
12 | 12 | "runtime"
|
13 |
| - "strings" |
14 | 13 | "sync"
|
15 | 14 | "time"
|
16 | 15 |
|
| 16 | + "github.com/cosmos72/gomacro/ast2" |
17 | 17 | "github.com/cosmos72/gomacro/base"
|
18 | 18 | "github.com/cosmos72/gomacro/classic"
|
19 | 19 | zmq "github.com/pebbe/zmq4"
|
@@ -382,30 +382,44 @@ func doEval(ir *classic.Interp, code string) (val interface{}, err error) {
|
382 | 382 | }
|
383 | 383 | }()
|
384 | 384 |
|
385 |
| - in := bufio.NewReader(strings.NewReader(code)) |
386 |
| - |
387 | 385 | // Prepare and perform the multiline evaluation.
|
388 | 386 | env := ir.Env
|
389 | 387 | env.Options &^= base.OptShowPrompt
|
390 | 388 | env.Options &^= base.OptTrapPanic
|
391 | 389 | env.Line = 0
|
392 | 390 |
|
393 |
| - // Perform the first iteration manually, to collect comments. |
394 |
| - var comments string |
395 |
| - str, firstToken := env.ReadMultiline(in, base.ReadOptCollectAllComments) |
396 |
| - if firstToken >= 0 { |
397 |
| - comments = str[0:firstToken] |
398 |
| - if firstToken > 0 { |
399 |
| - str = str[firstToken:] |
400 |
| - env.IncLine(comments) |
| 391 | + // Parse the input code (and don't preform gomacro's macroexpansion). |
| 392 | + src := ir.ParseOnly(code) |
| 393 | + |
| 394 | + // Check if the last node is an expression. |
| 395 | + var srcEndsWithExpr bool |
| 396 | + if src != nil { |
| 397 | + if srcAstWithNode, ok := src.(ast2.AstWithNode); ok { |
| 398 | + _, srcEndsWithExpr = srcAstWithNode.Node().(ast.Expr) |
| 399 | + } else if srcNodeSlice, ok := src.(ast2.NodeSlice); ok { |
| 400 | + nodes := srcNodeSlice.X |
| 401 | + _, srcEndsWithExpr = nodes[len(nodes)-1].(ast.Expr) |
401 | 402 | }
|
402 | 403 | }
|
403 | 404 |
|
404 |
| - // TODO capture the value of the last expression and return it as val |
405 |
| - |
406 |
| - // Run the code. |
407 |
| - if ir.ParseEvalPrint(str, in) { |
408 |
| - ir.Repl(in) |
| 405 | + // Evaluate the code. |
| 406 | + result, results := ir.Eval(src) |
| 407 | + |
| 408 | + if srcEndsWithExpr { |
| 409 | + //TODO if value is a certain type like image then display it instead |
| 410 | + |
| 411 | + // `len(results) == 0` implies a single result stored in `result`. |
| 412 | + if len(results) == 0 { |
| 413 | + val = base.ValueInterface(result) |
| 414 | + } else { |
| 415 | + // Set `val` to be the first non-nil result. |
| 416 | + for _, result := range results { |
| 417 | + val = base.ValueInterface(result) |
| 418 | + if val != nil { |
| 419 | + break |
| 420 | + } |
| 421 | + } |
| 422 | + } |
409 | 423 | }
|
410 | 424 |
|
411 | 425 | return
|
|
0 commit comments