Skip to content

Commit 910ee8a

Browse files
committed
Set execute_result value to the first non-nil value returned by the last
expression in a code cell.
1 parent a32b5af commit 910ee8a

File tree

1 file changed

+31
-17
lines changed

1 file changed

+31
-17
lines changed

kernel.go

Lines changed: 31 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,19 @@
11
package main
22

33
import (
4-
"bufio"
54
"encoding/json"
65
"errors"
76
"fmt"
7+
"go/ast"
88
"io"
99
"io/ioutil"
1010
"log"
1111
"os"
1212
"runtime"
13-
"strings"
1413
"sync"
1514
"time"
1615

16+
"github.com/cosmos72/gomacro/ast2"
1717
"github.com/cosmos72/gomacro/base"
1818
"github.com/cosmos72/gomacro/classic"
1919
zmq "github.com/pebbe/zmq4"
@@ -382,30 +382,44 @@ func doEval(ir *classic.Interp, code string) (val interface{}, err error) {
382382
}
383383
}()
384384

385-
in := bufio.NewReader(strings.NewReader(code))
386-
387385
// Prepare and perform the multiline evaluation.
388386
env := ir.Env
389387
env.Options &^= base.OptShowPrompt
390388
env.Options &^= base.OptTrapPanic
391389
env.Line = 0
392390

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)
401402
}
402403
}
403404

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+
}
409423
}
410424

411425
return

0 commit comments

Comments
 (0)