All Downloads are FREE. Search and download functionalities are using the official Maven repository.

js.prompto.expression.EqualsExpression.js Maven / Gradle / Ivy

var InstanceExpression = require("./InstanceExpression").InstanceExpression;
var UnresolvedIdentifier = require("./UnresolvedIdentifier").UnresolvedIdentifier;
var LinkedVariable = require("../runtime/LinkedVariable").LinkedVariable;
var LinkedValue = require("../runtime/LinkedValue").LinkedValue;
var BooleanType = require("../type/BooleanType").BooleanType;
var TypeValue = require("../value/TypeValue").TypeValue;
var NullValue = require("../value/NullValue").NullValue;
var CodeWriter = require("../utils/CodeWriter").CodeWriter;
var Instance = require("../value/Value").Instance;
var Value = require("../value/Value").Value;
var MatchOp = require("../store/MatchOp").MatchOp;
var Bool = require("../value/Bool").Bool;
var EqOp = require("../grammar/EqOp").EqOp;

function EqualsExpression(left, operator, right) {
	this.left = left;
	this.operator = operator;
	this.right = right;
	return this;
}

EqualsExpression.prototype.toString = function() {
	return this.left.toString() + " " + this.operator.toString() + " " + this.right.toString();
};

var VOWELS = "AEIO"; // sufficient here

EqualsExpression.prototype.toDialect = function(writer) {
    this.left.toDialect(writer);
    writer.append(" ");
    this.operator.toDialect(writer);
    // make this a AN
    if(this.operator==EqOp.IS_A || this.operator==EqOp.IS_NOT_A) {
        var name = this.right.toString();
        if(VOWELS.indexOf(name.charAt(0))>=0)
            writer.append("n");
    }
    writer.append(" ");
    this.right.toDialect(writer);
};

EqualsExpression.prototype.check = function(context) {
	this.left.check(context);
	this.right.check(context);
	return BooleanType.instance; // can compare all objects
};

EqualsExpression.prototype.interpret = function(context) {
    var lval = this.left.interpret(context) || NullValue.instance;
    var rval = this.right.interpret(context) || NullValue.instance;
    return this.interpretValues(context, lval, rval);
};

EqualsExpression.prototype.interpretValues = function(context, lval, rval) {
    var equal = false;
    switch(this.operator) {
        case EqOp.IS:
            equal = lval==rval;
            break;
        case EqOp.IS_NOT:
            equal = lval!=rval;
            break;
        case EqOp.IS_A:
            equal = this.isA(context,lval,rval);
            break;
        case EqOp.IS_NOT_A:
            equal = !this.isA(context,lval,rval);
            break;
        case EqOp.EQUALS:
            equal = this.areEqual(context,lval,rval);
            break;
        case EqOp.NOT_EQUALS:
            equal = !this.areEqual(context,lval,rval);
            break;
        case EqOp.ROUGHLY:
            equal = this.roughly(context,lval,rval);
            break;
    }
    return Bool.ValueOf(equal);
};

EqualsExpression.prototype.roughly = function(context, lval, rval) {
    if(lval!=null && rval!=null && lval.Roughly) {
        return lval.Roughly(context, rval);
    } else {
        return this.areEqual(context, lval, rval);
    }
};

EqualsExpression.prototype.areEqual = function(context, lval, rval) {
	if(lval==rval) {
		return true;
	} else if(lval==NullValue.instance || rval==NullValue.instance) {
        return false;
    } else {
		return lval.equals(rval);
	}
};

EqualsExpression.prototype.isA = function(context, lval, rval) {
    if(lval instanceof Value && rval instanceof TypeValue) {
        var actual = lval.type;
        var toCheck = rval.value;
        return toCheck.isAssignableFrom(context, actual);
    } else
        return false;
};


EqualsExpression.prototype.downCast = function(context, setValue) {
    if(this.operator==EqOp.IS_A) {
        var id = this.readLeftId();
        if(id!=null) {
            var value = context.getRegisteredValue(id.name);
            var type = this.right.value;
            var local = context.newChildContext();
            value = new LinkedVariable(type, value);
            local.registerValue(value, false);
            if(setValue)
                local.setValue(id, new LinkedValue(context));
            context = local;
        }
    }
    return context;
};

EqualsExpression.prototype.readLeftId = function() {
    if(this.left instanceof InstanceExpression)
        return this.left.id;
    else if(this.left instanceof UnresolvedIdentifier)
        return this.left.id;
    else
        return null;
};

EqualsExpression.prototype.interpretAssert = function(context, test) {
    var lval = this.left.interpret(context) || NullValue.instance;
    var rval = this.right.interpret(context) || NullValue.instance;
    var result = this.interpretValues(context, lval, rval);
    if(result==Bool.TRUE)
        return true;
    var writer = new CodeWriter(test.dialect, context);
    this.toDialect(writer);
    var expected = writer.toString();
    var actual = lval.toString() + " " + this.operator.toString(test.dialect) + " " + rval.toString();
    test.printFailedAssertion(context, expected, actual);
    return false;
};

EqualsExpression.prototype.interpretQuery = function(context, query) {
    var value = null;
    var name = this.readFieldName(this.left);
    if (name != null)
        value = this.right.interpret(context);
    else {
        name = this.readFieldName(this.right);
        if (name != null)
            value = this.left.interpret(context);
        else
            throw new SyntaxError("Unable to interpret predicate");
    }
    if (value instanceof Instance)
        value = value.getMemberValue(context, "dbId", false);
    var decl = context.findAttribute(name);
    var info = decl == null ? null : decl.getAttributeInfo();
    var data = value == null ? null : value.getStorableData();
    var match = this.getMatchOp();
    query.verify(info, match, data);
    if (this.operator == EqOp.NOT_EQUALS)
        query.not();
};


EqualsExpression.prototype.getMatchOp = function() {
    switch (this.operator) {
        case EqOp.EQUALS:
            return MatchOp.EQUALS;
        case EqOp.ROUGHLY:
            return MatchOp.ROUGHLY;
        case EqOp.NOT_EQUALS:
            return MatchOp.EQUALS
        default:
            throw new Exception("Not supported:" + this.operator.toString());
    }
};


EqualsExpression.prototype.readFieldName = function(exp) {
    if (exp instanceof UnresolvedIdentifier || exp instanceof InstanceExpression || exp instanceof MemberSelector)
        return exp.toString();
    else
        return null;
};

exports.EqualsExpression = EqualsExpression;






© 2015 - 2025 Weber Informatics LLC | Privacy Policy