Skip to content

Commit 57ad008

Browse files
authored
Merge pull request #97 from SpencerPark/gomacro-fast
Switch from the classic to fast interpreter
2 parents bc76420 + 4cf4c6e commit 57ad008

File tree

1 file changed

+26
-24
lines changed

1 file changed

+26
-24
lines changed

kernel.go

Lines changed: 26 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -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.
8989
func 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

Comments
 (0)