From 0880e88fa5b1d258fb4e3aa08a97798c66e1f280 Mon Sep 17 00:00:00 2001 From: Anthony De Meulemeester Date: Sat, 20 Oct 2018 07:11:00 +0200 Subject: [PATCH] Fixed bug in else stmts (CityOfZion/neo-storm#42) * Fixed bug in else stmts * Fixed if else bug * Back to %v for formatting instructions Imported from CityOfZion/neo-storm (ea8440e1454207753c8d209ce7c2cf724fd4ea16). --- cli/smartcontract/smart_contract.go | 3 +-- pkg/vm/compiler/codegen.go | 18 ++++++++++-------- 2 files changed, 11 insertions(+), 10 deletions(-) diff --git a/cli/smartcontract/smart_contract.go b/cli/smartcontract/smart_contract.go index 0ae5e2585..2c7a7b12a 100644 --- a/cli/smartcontract/smart_contract.go +++ b/cli/smartcontract/smart_contract.go @@ -173,8 +173,7 @@ func testInvoke(ctx *cli.Context) error { // On the long term the internal VM will run the script. // TODO: remove RPC dependency, hardcoded node. endpoint := "http://seed5.bridgeprotocol.io:10332" - opts := rpc.ClientOptions{} - client, err := rpc.NewClient(context.TODO(), endpoint, opts) + client, err := rpc.NewClient(context.TODO(), endpoint, rpc.ClientOptions{}) if err != nil { return cli.NewExitError(err, 1) } diff --git a/pkg/vm/compiler/codegen.go b/pkg/vm/compiler/codegen.go index 0c4d3b991..9457c4130 100644 --- a/pkg/vm/compiler/codegen.go +++ b/pkg/vm/compiler/codegen.go @@ -257,11 +257,7 @@ func (c *codegen) Visit(node ast.Node) ast.Visitor { log.Fatal("multiple returns not supported.") } - // @OPTIMIZE: We could skip these 3 instructions for each return statement. - // To be backwards compatible we will put them them in. - // See issue #65 (https://github.com/CityOfZion/neo-go/issues/65) l := c.newLabel() - // emitJmp(c.prog, vm.JMP, int16(l)) c.setLabel(l) if len(n.Results) > 0 { @@ -276,6 +272,8 @@ func (c *codegen) Visit(node ast.Node) ast.Visitor { case *ast.IfStmt: lIf := c.newLabel() lElse := c.newLabel() + lElseEnd := c.newLabel() + if n.Cond != nil { ast.Walk(c, n.Cond) emitJmp(c.prog, vm.JMPIFNOT, int16(lElse)) @@ -283,15 +281,15 @@ func (c *codegen) Visit(node ast.Node) ast.Visitor { c.setLabel(lIf) ast.Walk(c, n.Body) - if n.Else != nil { - // TODO: handle else statements. - // emitJmp(c.prog, vm.JMP, int16(lEnd)) + emitJmp(c.prog, vm.JMP, int16(lElseEnd)) } + c.setLabel(lElse) if n.Else != nil { ast.Walk(c, n.Else) } + c.setLabel(lElseEnd) return nil case *ast.BasicLit: @@ -659,7 +657,11 @@ func (c *codegen) convertToken(tok token.Token) { case token.GEQ: emitOpcode(c.prog, vm.GTE) case token.EQL: - emitOpcode(c.prog, vm.NUMEQUAL) + // It seems that (looking to the python compiler) that comparing for + // equal (==) needs to return the instruction EQUAL. Where comparing + // (anything) to not equal (!=) needs to use the opcode NUMNOTEQUAL + // even for comparing strings. + emitOpcode(c.prog, vm.EQUAL) case token.NEQ: emitOpcode(c.prog, vm.NUMNOTEQUAL) case token.DEC: