@@ -92,6 +92,13 @@ type scope struct {
9292 index int
9393}
9494
95+ func (c * compiler ) nodeParent () ast.Node {
96+ if len (c .nodes ) > 1 {
97+ return c .nodes [len (c .nodes )- 2 ]
98+ }
99+ return nil
100+ }
101+
95102func (c * compiler ) emitLocation (loc file.Location , op Opcode , arg int ) int {
96103 c .bytecode = append (c .bytecode , op )
97104 current := len (c .bytecode )
@@ -594,9 +601,21 @@ func isSimpleType(node ast.Node) bool {
594601func (c * compiler ) ChainNode (node * ast.ChainNode ) {
595602 c .chains = append (c .chains , []int {})
596603 c .compile (node .Node )
597- // Chain activate (got nit somewhere)
598604 for _ , ph := range c .chains [len (c .chains )- 1 ] {
599- c .patchJump (ph )
605+ c .patchJump (ph ) // If chain activated jump here (got nit somewhere).
606+ }
607+ parent := c .nodeParent ()
608+ if binary , ok := parent .(* ast.BinaryNode ); ok && binary .Operator == "??" {
609+ // If chain is used in nil coalescing operator, we can omit
610+ // nil push at the end of the chain. The ?? operator will
611+ // handle it.
612+ } else {
613+ // We need to put the nil on the stack, otherwise "typed"
614+ // nil will be used as a result of the chain.
615+ j := c .emit (OpJumpIfNotNil , placeholder )
616+ c .emit (OpPop )
617+ c .emit (OpNil )
618+ c .patchJump (j )
600619 }
601620 c .chains = c .chains [:len (c .chains )- 1 ]
602621}
0 commit comments