@@ -15,7 +15,7 @@ import (
1515
1616 "github.com/cosmos72/gomacro/ast2"
1717 "github.com/cosmos72/gomacro/base"
18- "github.com/cosmos72/gomacro/classic "
18+ interp "github.com/cosmos72/gomacro/fast "
1919 zmq "github.com/pebbe/zmq4"
2020)
2121
@@ -88,12 +88,12 @@ const (
8888// runKernel is the main entry point to start the kernel.
8989func runKernel (connectionFile string ) {
9090
91- // Set up the "Session" with the replpkg .
92- ir := classic .New ()
91+ // Create a new interpreter for evaluating notebook code .
92+ ir := interp .New ()
9393
9494 // Throw out the error/warning messages that gomacro outputs writes to these streams.
95- ir .Stdout = ioutil .Discard
96- ir .Stderr = ioutil .Discard
95+ ir .Comp . Stdout = ioutil .Discard
96+ ir .Comp . Stderr = ioutil .Discard
9797
9898 // Parse the connection info.
9999 var connInfo ConnectionInfo
@@ -242,7 +242,7 @@ func prepareSockets(connInfo ConnectionInfo) (SocketGroup, error) {
242242}
243243
244244// handleShellMsg responds to a message on the shell ROUTER socket.
245- func handleShellMsg (ir * classic .Interp , receipt msgReceipt ) {
245+ func handleShellMsg (ir * interp .Interp , receipt msgReceipt ) {
246246 switch receipt .Msg .Header .MsgType {
247247 case "kernel_info_request" :
248248 if err := sendKernelInfo (receipt ); err != nil {
@@ -282,7 +282,7 @@ func sendKernelInfo(receipt msgReceipt) error {
282282
283283// handleExecuteRequest runs code from an execute_request method,
284284// and sends the various reply messages.
285- func handleExecuteRequest (ir * classic .Interp , receipt msgReceipt ) error {
285+ func handleExecuteRequest (ir * interp .Interp , receipt msgReceipt ) error {
286286
287287 // Extract the data from the request.
288288 reqcontent := receipt .Msg .Content .(map [string ]interface {})
@@ -386,7 +386,7 @@ func handleExecuteRequest(ir *classic.Interp, receipt msgReceipt) error {
386386
387387// doEval evaluates the code in the interpreter. This function captures an uncaught panic
388388// as well as the values of the last statement/expression.
389- func doEval (ir * classic .Interp , code string ) (_ []interface {}, err error ) {
389+ func doEval (ir * interp .Interp , code string ) (val []interface {}, err error ) {
390390
391391 // Capture a panic from the evaluation if one occurs and store it in the `err` return parameter.
392392 defer func () {
@@ -399,39 +399,41 @@ func doEval(ir *classic.Interp, code string) (_ []interface{}, err error) {
399399 }()
400400
401401 // Prepare and perform the multiline evaluation.
402- env := ir .Env
402+ compiler := ir .Comp
403403
404404 // Don't show the gomacro prompt.
405- env .Options &^= base .OptShowPrompt
405+ compiler .Options &^= base .OptShowPrompt
406406
407407 // Don't swallow panics as they are recovered above and handled with a Jupyter `error` message instead.
408- env .Options &^= base .OptTrapPanic
408+ compiler .Options &^= base .OptTrapPanic
409409
410410 // Reset the error line so that error messages correspond to the lines from the cell.
411- env .Line = 0
411+ compiler .Line = 0
412412
413413 // Parse the input code (and don't preform gomacro's macroexpansion).
414- src := ir .ParseOnly (code )
414+ // These may panic but this will be recovered by the deferred recover() above so that the error
415+ // may be returned instead.
416+ nodes := compiler .ParseBytes ([]byte (code ))
417+ srcAst := ast2 .AnyToAst (nodes , "doEval" )
415418
416- if src == nil {
419+ // If there is no srcAst then we must be evaluating nothing. The result must be nil then.
420+ if srcAst == nil {
417421 return nil , nil
418422 }
419423
420- // Check if the last node is an expression.
424+ // Check if the last node is an expression. If the last node is not an expression then nothing
425+ // is returned as a value. For example evaluating a function declaration shouldn't return a value but
426+ // just have the side effect of declaring the function.
421427 var srcEndsWithExpr bool
422-
423- // If the parsed ast is a single node, check if the node implements `ast.Expr`. Otherwise if the is multiple
424- // nodes then just check if the last one is an expression. These are currently the 2 cases to consider from
425- // gomacro's `ParseOnly`.
426- if srcAstWithNode , ok := src .(ast2.AstWithNode ); ok {
427- _ , srcEndsWithExpr = srcAstWithNode .Node ().(ast.Expr )
428- } else if srcNodeSlice , ok := src .(ast2.NodeSlice ); ok {
429- nodes := srcNodeSlice .X
428+ if len (nodes ) > 0 {
430429 _ , srcEndsWithExpr = nodes [len (nodes )- 1 ].(ast.Expr )
431430 }
432431
432+ // Compile the ast.
433+ compiledSrc := ir .CompileAst (srcAst )
434+
433435 // Evaluate the code.
434- result , results := ir .EvalAst ( src )
436+ result , results := ir .RunExpr ( compiledSrc )
435437
436438 // If the source ends with an expression, then the result of the execution is the value of the expression. In the
437439 // event that all return values are nil, the result is also nil.
0 commit comments