@@ -224,11 +224,6 @@ func (c *compiler) IdentifierNode(node *ast.IdentifierNode) {
224224 } else {
225225 c .emit (OpLoadConst , c .addConstant (node .Value ))
226226 }
227- if node .Deref {
228- c .emit (OpDeref )
229- } else if node .Type () == nil {
230- c .emit (OpDeref )
231- }
232227}
233228
234229func (c * compiler ) IntegerNode (node * ast.IntegerNode ) {
@@ -289,6 +284,7 @@ func (c *compiler) ConstantNode(node *ast.ConstantNode) {
289284
290285func (c * compiler ) UnaryNode (node * ast.UnaryNode ) {
291286 c .compile (node .Node )
287+ c .derefInNeeded (node .Node )
292288
293289 switch node .Operator {
294290
@@ -313,7 +309,9 @@ func (c *compiler) BinaryNode(node *ast.BinaryNode) {
313309 switch node .Operator {
314310 case "==" :
315311 c .compile (node .Left )
312+ c .derefInNeeded (node .Left )
316313 c .compile (node .Right )
314+ c .derefInNeeded (node .Left )
317315
318316 if l == r && l == reflect .Int {
319317 c .emit (OpEqualInt )
@@ -325,114 +323,155 @@ func (c *compiler) BinaryNode(node *ast.BinaryNode) {
325323
326324 case "!=" :
327325 c .compile (node .Left )
326+ c .derefInNeeded (node .Left )
328327 c .compile (node .Right )
328+ c .derefInNeeded (node .Left )
329329 c .emit (OpEqual )
330330 c .emit (OpNot )
331331
332332 case "or" , "||" :
333333 c .compile (node .Left )
334+ c .derefInNeeded (node .Left )
334335 end := c .emit (OpJumpIfTrue , placeholder )
335336 c .emit (OpPop )
336337 c .compile (node .Right )
338+ c .derefInNeeded (node .Right )
337339 c .patchJump (end )
338340
339341 case "and" , "&&" :
340342 c .compile (node .Left )
343+ c .derefInNeeded (node .Left )
341344 end := c .emit (OpJumpIfFalse , placeholder )
342345 c .emit (OpPop )
343346 c .compile (node .Right )
347+ c .derefInNeeded (node .Right )
344348 c .patchJump (end )
345349
346350 case "<" :
347351 c .compile (node .Left )
352+ c .derefInNeeded (node .Left )
348353 c .compile (node .Right )
354+ c .derefInNeeded (node .Right )
349355 c .emit (OpLess )
350356
351357 case ">" :
352358 c .compile (node .Left )
359+ c .derefInNeeded (node .Left )
353360 c .compile (node .Right )
361+ c .derefInNeeded (node .Right )
354362 c .emit (OpMore )
355363
356364 case "<=" :
357365 c .compile (node .Left )
366+ c .derefInNeeded (node .Left )
358367 c .compile (node .Right )
368+ c .derefInNeeded (node .Right )
359369 c .emit (OpLessOrEqual )
360370
361371 case ">=" :
362372 c .compile (node .Left )
373+ c .derefInNeeded (node .Left )
363374 c .compile (node .Right )
375+ c .derefInNeeded (node .Right )
364376 c .emit (OpMoreOrEqual )
365377
366378 case "+" :
367379 c .compile (node .Left )
380+ c .derefInNeeded (node .Left )
368381 c .compile (node .Right )
382+ c .derefInNeeded (node .Right )
369383 c .emit (OpAdd )
370384
371385 case "-" :
372386 c .compile (node .Left )
387+ c .derefInNeeded (node .Left )
373388 c .compile (node .Right )
389+ c .derefInNeeded (node .Right )
374390 c .emit (OpSubtract )
375391
376392 case "*" :
377393 c .compile (node .Left )
394+ c .derefInNeeded (node .Left )
378395 c .compile (node .Right )
396+ c .derefInNeeded (node .Right )
379397 c .emit (OpMultiply )
380398
381399 case "/" :
382400 c .compile (node .Left )
401+ c .derefInNeeded (node .Left )
383402 c .compile (node .Right )
403+ c .derefInNeeded (node .Right )
384404 c .emit (OpDivide )
385405
386406 case "%" :
387407 c .compile (node .Left )
408+ c .derefInNeeded (node .Left )
388409 c .compile (node .Right )
410+ c .derefInNeeded (node .Right )
389411 c .emit (OpModulo )
390412
391413 case "**" , "^" :
392414 c .compile (node .Left )
415+ c .derefInNeeded (node .Left )
393416 c .compile (node .Right )
417+ c .derefInNeeded (node .Right )
394418 c .emit (OpExponent )
395419
396420 case "in" :
397421 c .compile (node .Left )
422+ c .derefInNeeded (node .Left )
398423 c .compile (node .Right )
424+ c .derefInNeeded (node .Right )
399425 c .emit (OpIn )
400426
401427 case "matches" :
402428 if node .Regexp != nil {
403429 c .compile (node .Left )
430+ c .derefInNeeded (node .Left )
404431 c .emit (OpMatchesConst , c .addConstant (node .Regexp ))
405432 } else {
406433 c .compile (node .Left )
434+ c .derefInNeeded (node .Left )
407435 c .compile (node .Right )
436+ c .derefInNeeded (node .Right )
408437 c .emit (OpMatches )
409438 }
410439
411440 case "contains" :
412441 c .compile (node .Left )
442+ c .derefInNeeded (node .Left )
413443 c .compile (node .Right )
444+ c .derefInNeeded (node .Right )
414445 c .emit (OpContains )
415446
416447 case "startsWith" :
417448 c .compile (node .Left )
449+ c .derefInNeeded (node .Left )
418450 c .compile (node .Right )
451+ c .derefInNeeded (node .Right )
419452 c .emit (OpStartsWith )
420453
421454 case "endsWith" :
422455 c .compile (node .Left )
456+ c .derefInNeeded (node .Left )
423457 c .compile (node .Right )
458+ c .derefInNeeded (node .Right )
424459 c .emit (OpEndsWith )
425460
426461 case ".." :
427462 c .compile (node .Left )
463+ c .derefInNeeded (node .Left )
428464 c .compile (node .Right )
465+ c .derefInNeeded (node .Right )
429466 c .emit (OpRange )
430467
431468 case "??" :
432469 c .compile (node .Left )
470+ c .derefInNeeded (node .Left )
433471 end := c .emit (OpJumpIfNotNil , placeholder )
434472 c .emit (OpPop )
435473 c .compile (node .Right )
474+ c .derefInNeeded (node .Right )
436475 c .patchJump (end )
437476
438477 default :
@@ -461,7 +500,6 @@ func (c *compiler) MemberNode(node *ast.MemberNode) {
461500 return
462501 }
463502 op := OpFetch
464- original := node
465503 index := node .FieldIndex
466504 path := []string {node .Name }
467505 base := node .Node
@@ -470,21 +508,15 @@ func (c *compiler) MemberNode(node *ast.MemberNode) {
470508 for ! node .Optional {
471509 ident , ok := base .(* ast.IdentifierNode )
472510 if ok && len (ident .FieldIndex ) > 0 {
473- if ident .Deref {
474- panic ("IdentifierNode should not be dereferenced" )
475- }
476511 index = append (ident .FieldIndex , index ... )
477512 path = append ([]string {ident .Value }, path ... )
478513 c .emitLocation (ident .Location (), OpLoadField , c .addConstant (
479514 & runtime.Field {Index : index , Path : path },
480515 ))
481- goto deref
516+ return
482517 }
483518 member , ok := base .(* ast.MemberNode )
484519 if ok && len (member .FieldIndex ) > 0 {
485- if member .Deref {
486- panic ("MemberNode should not be dereferenced" )
487- }
488520 index = append (member .FieldIndex , index ... )
489521 path = append ([]string {member .Name }, path ... )
490522 node = member
@@ -509,13 +541,6 @@ func (c *compiler) MemberNode(node *ast.MemberNode) {
509541 & runtime.Field {Index : index , Path : path },
510542 ))
511543 }
512-
513- deref:
514- if original .Deref {
515- c .emit (OpDeref )
516- } else if original .Type () == nil {
517- c .emit (OpDeref )
518- }
519544}
520545
521546func (c * compiler ) SliceNode (node * ast.SliceNode ) {
@@ -734,6 +759,13 @@ func (c *compiler) PairNode(node *ast.PairNode) {
734759 c .compile (node .Value )
735760}
736761
762+ func (c * compiler ) derefInNeeded (node ast.Node ) {
763+ switch kind (node ) {
764+ case reflect .Ptr , reflect .Interface :
765+ c .emit (OpDeref )
766+ }
767+ }
768+
737769func kind (node ast.Node ) reflect.Kind {
738770 t := node .Type ()
739771 if t == nil {
0 commit comments