1 module antlr.v4.runtime.atn.AND; 2 3 import std.conv; 4 import std.algorithm.comparison; 5 import std.algorithm.iteration; 6 import antlr.v4.runtime.InterfaceRecognizer; 7 import antlr.v4.runtime.Token; 8 import antlr.v4.runtime.atn.Operator; 9 import antlr.v4.runtime.RuleContext; 10 import antlr.v4.runtime.atn.SemanticContext; 11 import antlr.v4.runtime.misc.MurmurHash; 12 13 // Class AND 14 /** 15 * TODO add class description 16 */ 17 class AND : Operator 18 { 19 20 public SemanticContext[] opnds; 21 22 public this(SemanticContext a, SemanticContext b) 23 { 24 } 25 26 /** 27 * @uml 28 * @override 29 */ 30 public override SemanticContext[] getOperands() 31 { 32 return opnds; 33 } 34 35 /** 36 * @uml 37 * @override 38 */ 39 public override bool opEquals(Object obj) 40 { 41 if (this is obj) return true; 42 if (obj.classinfo != AND.classinfo) return false; 43 AND other = cast(AND)obj; 44 return equal(this.opnds, other.opnds); 45 } 46 47 /** 48 * @uml 49 * @override 50 * @trusted 51 */ 52 public override size_t toHash() @trusted 53 { 54 return MurmurHash.hashCode(opnds, this.toHash); 55 } 56 57 /** 58 * @uml 59 * @override 60 */ 61 public override bool eval(InterfaceRecognizer parser, RuleContext parserCallStack) 62 { 63 foreach (SemanticContext opnd; opnds) { 64 if (!opnd.eval(parser, parserCallStack)) return false; 65 } 66 return true; 67 } 68 69 /** 70 * @uml 71 * @override 72 */ 73 public override SemanticContext evalPrecedence(InterfaceRecognizer parser, RuleContext parserCallStack) 74 { 75 bool differs = false; 76 SemanticContext[] operands; 77 foreach (SemanticContext context; opnds) { 78 SemanticContext evaluated = context.evalPrecedence(parser, parserCallStack); 79 differs |= (evaluated != context); 80 if (evaluated is null) { 81 // The AND context is false if any element is false 82 return null; 83 } 84 else if (evaluated != NONE) { 85 // Reduce the result by skipping true elements 86 operands ~= evaluated; 87 } 88 } 89 90 if (!differs) { 91 return this; 92 } 93 94 if (operands.length == 0) { 95 // all elements were true, so the AND context is true 96 return NONE; 97 } 98 99 SemanticContext result = operands[0]; 100 for (int i = 1; i < operands.length; i++) { 101 result = SemanticContext.and(result, operands[i]); 102 } 103 104 return result; 105 106 } 107 108 /** 109 * @uml 110 * @override 111 */ 112 public override string toString() 113 { 114 return to!string(map!(n => n.toString)(opnds).joiner(" && ")); 115 } 116 117 }