@@ -336,7 +336,7 @@ func handleExecuteRequest(ir *classic.Interp, receipt msgReceipt) error {
336336 io .Copy (& jupyterStdErr , rErr )
337337 }()
338338
339- val , executionErr := doEval (ir , code )
339+ vals , executionErr := doEval (ir , code )
340340
341341 //TODO if value is a certain type like image then display it instead
342342
@@ -354,9 +354,9 @@ func handleExecuteRequest(ir *classic.Interp, receipt msgReceipt) error {
354354 content ["status" ] = "ok"
355355 content ["user_expressions" ] = make (map [string ]string )
356356
357- if ! silent && val != nil {
357+ if ! silent && vals != nil {
358358 // Publish the result of the execution.
359- if err := receipt .PublishExecutionResult (ExecCounter , fmt .Sprint (val )); err != nil {
359+ if err := receipt .PublishExecutionResult (ExecCounter , fmt .Sprint (vals ... )); err != nil {
360360 log .Printf ("Error publishing execution result: %v\n " , err )
361361 }
362362 }
@@ -376,8 +376,8 @@ func handleExecuteRequest(ir *classic.Interp, receipt msgReceipt) error {
376376}
377377
378378// doEval evaluates the code in the interpreter. This function captures an uncaught panic
379- // as well as the value of the last statement/expression.
380- func doEval (ir * classic.Interp , code string ) (_ interface {}, err error ) {
379+ // as well as the values of the last statement/expression.
380+ func doEval (ir * classic.Interp , code string ) (_ [] interface {}, err error ) {
381381 // Capture a panic from the evaluation if one occurs and store it in the `err` return parameter.
382382 defer func () {
383383 if r := recover (); r != nil {
@@ -390,8 +390,11 @@ func doEval(ir *classic.Interp, code string) (_ interface{}, err error) {
390390
391391 // Prepare and perform the multiline evaluation.
392392 env := ir .Env
393+ // Don't show the gomacro prompt.
393394 env .Options &^= base .OptShowPrompt
395+ // Don't swallow panics as they are recovered above and handled with a Jupyter `error` message instead.
394396 env .Options &^= base .OptTrapPanic
397+ // Reset the error line so that error messages correspond to the lines from the cell
395398 env .Line = 0
396399
397400 // Parse the input code (and don't preform gomacro's macroexpansion).
@@ -405,7 +408,8 @@ func doEval(ir *classic.Interp, code string) (_ interface{}, err error) {
405408 var srcEndsWithExpr bool
406409
407410 // If the parsed ast is a single node, check if the node implements `ast.Expr`. Otherwise if the is multiple
408- // nodes then just check if the last one is an expression.
411+ // nodes then just check if the last one is an expression. These are currently the 2 cases to consider from
412+ // gomacro's `ParseOnly`.
409413 if srcAstWithNode , ok := src .(ast2.AstWithNode ); ok {
410414 _ , srcEndsWithExpr = srcAstWithNode .Node ().(ast.Expr )
411415 } else if srcNodeSlice , ok := src .(ast2.NodeSlice ); ok {
@@ -417,20 +421,31 @@ func doEval(ir *classic.Interp, code string) (_ interface{}, err error) {
417421 result , results := ir .EvalAst (src )
418422
419423 // If the source ends with an expression, then the result of the execution is the value of the expression. In the
420- // case of multiple return values (from a function call for example), the first non-nil value is the result.
424+ // event that all return values are nil, then the
421425 if srcEndsWithExpr {
422426 // `len(results) == 0` implies a single result stored in `result`.
423427 if len (results ) == 0 {
424- return base .ValueInterface (result ), nil
428+ if val := base .ValueInterface (result ); val != nil {
429+ return []interface {}{val }, nil
430+ }
431+ return nil , nil
425432 }
426433
427- // Set `val` to be the first non-nil result.
434+ // Count the number of non-nil values in the output. If they are all nil then the output is skipped.
435+ nonNilCount := 0
436+ var values []interface {}
428437 for _ , result := range results {
429438 val := base .ValueInterface (result )
430439 if val != nil {
431- return val , nil
440+ nonNilCount ++
432441 }
442+ values = append (values , val )
443+ }
444+
445+ if nonNilCount > 0 {
446+ return values , nil
433447 }
448+ return nil , nil
434449 }
435450
436451 return nil , nil
0 commit comments