PageRenderTime 29ms CodeModel.GetById 18ms app.highlight 8ms RepoModel.GetById 2ms app.codeStats 0ms

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