public override void ExitOrexp1(ssuplParser.Orexp1Context context) { //orexp -> orexp OR andexp #orexp1 if (type(context.orexp()) != VarType.INT) { throw new Exception("First operand to OR must be integer"); } if (type(context.andexp()) != VarType.INT) { throw new Exception("Second operand to OR must be integer"); } typeAttr.Put(context, VarType.INT); var firstWasFalse = label(); var done = label(); code.Put(context, code.Get(context.orexp()), //first term "pop rax", //result of first term "cmp rax,0", //see if it's zero $"je {firstWasFalse}", //if so, do second test "push qword 1", //if not, push 1 to stack $"jmp {done}", //skip second test $"{firstWasFalse}:", //start of second test code.Get(context.andexp()), //second term "pop rax", //result of second term "cmp rax,0", //see if it's zero "setne al", //if not, set al to 1 "movzx qword rax,al", //zero extend "push rax", //push result $"{done}:" ); }
public override void ExitOrexp1(ssuplParser.Orexp1Context context) { //orexp : orexp OR andexp #orexp1 var firstWasFalse = label(); var done = label(); code.Put(context, code.Get(context.orexp()), //first term "pop rax", //result of first term "cmp rax,0", //see if it's zero $"je {firstWasFalse}", //if so, do second test "push qword 1", //if not, push 1 to stack $"jmp {done}", //skip second test $"{firstWasFalse}:", //start of second test code.Get(context.andexp()), //second term "pop rax", //result of second term "cmp rax,0", //see if it's zero "setne al", //if not, set al to 1 "movzx qword rax,al", //zero extend "push rax", //push result $"{done}:" ); }
/// <summary> /// Exit a parse tree produced by the <c>orexp1</c> /// labeled alternative in <see cref="ssuplParser.orexp"/>. /// <para>The default implementation does nothing.</para> /// </summary> /// <param name="context">The parse tree.</param> public virtual void ExitOrexp1([NotNull] ssuplParser.Orexp1Context context) { }