/src/org/ooc/frontend/model/Compare.java

http://github.com/nddrylliog/ooc · Java · 110 lines · 88 code · 22 blank · 0 comment · 15 complexity · 44839da39fff95bf69c34e2602822ac2 MD5 · raw file

  1. package org.ooc.frontend.model;
  2. import java.io.IOException;
  3. import org.ooc.frontend.Visitor;
  4. import org.ooc.frontend.model.IntLiteral.Format;
  5. import org.ooc.frontend.model.OpDecl.OpType;
  6. import org.ooc.frontend.model.tokens.Token;
  7. import org.ooc.middle.OocCompilationError;
  8. import org.ooc.middle.hobgoblins.Resolver;
  9. public class Compare extends BinaryOperation {
  10. public static enum CompareType {
  11. GREATER,
  12. GREATER_OR_EQUAL,
  13. LESSER,
  14. LESSER_OR_EQUAL,
  15. EQUAL,
  16. NOT_EQUAL,
  17. }
  18. protected CompareType compareType;
  19. public Compare(Expression left, Expression right, CompareType compareType, Token token) {
  20. super(left, right, token);
  21. this.compareType = compareType;
  22. }
  23. public CompareType getCompareType() {
  24. return compareType;
  25. }
  26. public void setCompareType(CompareType compareType) {
  27. this.compareType = compareType;
  28. }
  29. public void accept(Visitor visitor) throws IOException {
  30. visitor.visit(this);
  31. }
  32. @Override
  33. public OpType getOpType() {
  34. switch(compareType) {
  35. case EQUAL:
  36. return OpType.EQ;
  37. case GREATER:
  38. return OpType.GT;
  39. case GREATER_OR_EQUAL:
  40. return OpType.GTE;
  41. case LESSER:
  42. return OpType.LT;
  43. case LESSER_OR_EQUAL:
  44. return OpType.LTE;
  45. case NOT_EQUAL:
  46. return OpType.NE;
  47. }
  48. return null;
  49. }
  50. @Override
  51. public Response resolve(NodeList<Node> stack, Resolver res, boolean fatal) {
  52. Response response = super.resolve(stack, res, fatal);
  53. if(response != Response.OK) return response;
  54. if(left.getType() == null || !left.getType().isResolved()) {
  55. if(fatal) throw new OocCompilationError(left, stack, "Left type of assignment unresolved: "+left+" (btw, stack = "+stack.toString(true));
  56. return Response.LOOP;
  57. }
  58. if(right.getType() == null || !left.getType().isResolved()) {
  59. if(fatal) throw new OocCompilationError(right, stack, "Right type of assignment unresolved: "+right);
  60. return Response.LOOP;
  61. }
  62. VariableAccess tAccess = new VariableAccess(left.getType().getRef().getName(), startToken);
  63. Expression size = new MemberAccess(tAccess, "size", startToken);
  64. if(isGeneric()) {
  65. FunctionCall call = new FunctionCall("memcmp", startToken);
  66. NodeList<Expression> args = call.getArguments();
  67. args.add(left.getGenericOperand());
  68. args.add(right.getGenericOperand());
  69. args.add(size);
  70. left = call;
  71. right = new IntLiteral(0, Format.DEC, startToken);
  72. return Response.RESTART;
  73. }
  74. return Response.OK;
  75. }
  76. private boolean isGeneric() {
  77. return (left. getType().isGeneric() && left. getType().getPointerLevel() == 0) ||
  78. (right.getType().isGeneric() && right.getType().getPointerLevel() == 0);
  79. }
  80. @Override
  81. public int getPriority() {
  82. switch(compareType) {
  83. case GREATER: case GREATER_OR_EQUAL: case LESSER: case LESSER_OR_EQUAL: return 40;
  84. case EQUAL: case NOT_EQUAL: return 50;
  85. }
  86. return 0; // never happens
  87. }
  88. }