Newer
Older
RDLProofSystem / src / main / java / constants / Symbols.java
package constants;

import java.util.List;

import models.algebra.Constant;
import models.algebra.Expression;
import models.algebra.Symbol;
import models.algebra.Type;
import parser.Parser;

public class Symbols {
	
	public static final Symbol null_ = new Symbol("null", 0, Symbol.Type.PREFIX, "null", Symbol.Type.PREFIX);
	public static final Symbol true_ = new Symbol("true", 0, Symbol.Type.PREFIX, "true", Symbol.Type.PREFIX);
	public static final Symbol false_ = new Symbol("false", 0, Symbol.Type.PREFIX, "false", Symbol.Type.PREFIX);
	
	public static final Symbol add = new Symbol(Parser.ADD, 2, Symbol.Type.INFIX, new Symbol.ICalculator() {
		@Override
		public Expression calculate(List<Expression> args) {
			if (!(args.get(0).getClass() == Constant.class)) {
				return null;
			}
			if (!(args.get(1).getClass() == Constant.class)) {
				return null;
			}
			Constant arg0 = (Constant) args.get(0);
			Constant arg1 = (Constant) args.get(1);
			String sArg0 = arg0.getSymbol().toString();
			String sArg1 = arg1.getSymbol().toString();
			if (arg0.getType() != null && arg1.getType() != null) {
				if (arg0.getType().equals(Types.typeDouble) || arg1.getType().equals(Types.typeDouble)) {
					return new Constant(Double.toString(Double.parseDouble(sArg0) + Double.parseDouble(sArg1)), Types.typeDouble);
				} else if (arg0.getType().equals(Types.typeFloat) || arg1.getType().equals(Types.typeFloat)) {
					return new Constant(Float.toString(Float.parseFloat(sArg0) + Float.parseFloat(sArg1)), Types.typeFloat);
				} else if (arg0.getType().equals(Types.typeLong) || arg1.getType().equals(Types.typeLong)) {
					return new Constant(Long.toString(Long.parseLong(sArg0) + Long.parseLong(sArg1)), Types.typeLong);
				} else if (arg0.getType().equals(Types.typeInt) || arg1.getType().equals(Types.typeInt)) {
					return new Constant(Integer.toString(Integer.parseInt(sArg0) + Integer.parseInt(sArg1)), Types.typeInt);
				} else if (arg0.getType().equals(Types.typeString) || arg1.getType().equals(Types.typeString)) {
					return new Constant((String) arg0.getValue() + (String) arg1.getValue(), Types.typeString);
				}
			}
			if (sArg0.contains(Parser.DOT) || sArg1.contains(Parser.DOT)) {
				return new Constant(Double.toString(Double.parseDouble(sArg0) + Double.parseDouble(sArg1)), Types.typeDouble);
			} else {
				return new Constant(Integer.toString(Integer.parseInt(sArg0) + Integer.parseInt(sArg1)), Types.typeInt);
			}
		}
	});
	public static final Symbol mul = new Symbol(Parser.MUL, 2, Symbol.Type.INFIX, new Symbol.ICalculator() {
		@Override
		public Expression calculate(List<Expression> args) {
			if (!(args.get(0).getClass() == Constant.class)) {
				return null;
			}
			if (!(args.get(1).getClass() == Constant.class)) {
				return null;
			}
			Constant arg0 = (Constant) args.get(0);
			Constant arg1 = (Constant) args.get(1);
			String sArg0 = arg0.getSymbol().toString();
			String sArg1 = arg1.getSymbol().toString();
			if (arg0.getType() != null && arg1.getType() != null) {
				if (arg0.getType().equals(Types.typeDouble) || arg1.getType().equals(Types.typeDouble)) {
					return new Constant(Double.toString(Double.parseDouble(sArg0) * Double.parseDouble(sArg1)), Types.typeDouble);
				} else if (arg0.getType().equals(Types.typeFloat) || arg1.getType().equals(Types.typeFloat)) {
					return new Constant(Float.toString(Float.parseFloat(sArg0) * Float.parseFloat(sArg1)), Types.typeFloat);
				} else if (arg0.getType().equals(Types.typeLong) || arg1.getType().equals(Types.typeLong)) {
					return new Constant(Long.toString(Long.parseLong(sArg0) * Long.parseLong(sArg1)), Types.typeLong);
				} else if (arg0.getType().equals(Types.typeInt) || arg1.getType().equals(Types.typeInt)) {
					return new Constant(Integer.toString(Integer.parseInt(sArg0) * Integer.parseInt(sArg1)), Types.typeInt);
				}
			}
			if (sArg0.contains(Parser.DOT) || sArg1.contains(Parser.DOT)) {
				return new Constant(Double.toString(Double.parseDouble(sArg0) * Double.parseDouble(sArg1)), Types.typeDouble);
			} else {
				return new Constant(Integer.toString(Integer.parseInt(sArg0) * Integer.parseInt(sArg1)), Types.typeInt);
			}
		}
	});
	public static final Symbol sub = new Symbol(Parser.SUB, 2, Symbol.Type.INFIX, new Symbol.ICalculator() {
		@Override
		public Expression calculate(List<Expression> args) {
			if (!(args.get(0).getClass() == Constant.class)) {
				return null;
			}
			if (!(args.get(1).getClass() == Constant.class)) {
				return null;
			}
			Constant arg0 = (Constant) args.get(0);
			Constant arg1 = (Constant) args.get(1);
			String sArg0 = arg0.getSymbol().toString();
			String sArg1 = arg1.getSymbol().toString();
			if (arg0.getType() != null && arg1.getType() != null) {
				if (arg0.getType().equals(Types.typeDouble) || arg1.getType().equals(Types.typeDouble)) {
					return new Constant(Double.toString(Double.parseDouble(sArg0) - Double.parseDouble(sArg1)), Types.typeDouble);
				} else if (arg0.getType().equals(Types.typeFloat) || arg1.getType().equals(Types.typeFloat)) {
					return new Constant(Float.toString(Float.parseFloat(sArg0) - Float.parseFloat(sArg1)), Types.typeFloat);
				} else if (arg0.getType().equals(Types.typeLong) || arg1.getType().equals(Types.typeLong)) {
					return new Constant(Long.toString(Long.parseLong(sArg0) - Long.parseLong(sArg1)), Types.typeLong);
				} else if (arg0.getType().equals(Types.typeInt) || arg1.getType().equals(Types.typeInt)) {
					return new Constant(Integer.toString(Integer.parseInt(sArg0) - Integer.parseInt(sArg1)), Types.typeInt);
				}
			}
			if (sArg0.contains(Parser.DOT) || sArg1.contains(Parser.DOT)) {
				return new Constant(Double.toString(Double.parseDouble(sArg0) - Double.parseDouble(sArg1)), Types.typeDouble);
			} else {
				return new Constant(Integer.toString(Integer.parseInt(sArg0) - Integer.parseInt(sArg1)), Types.typeInt);
			}
		}
	});
	public static final Symbol div = new Symbol(Parser.DIV, 2, Symbol.Type.INFIX, new Symbol.ICalculator() {
		@Override
		public Expression calculate(List<Expression> args) {
			if (!(args.get(0).getClass() == Constant.class)) {
				return null;
			}
			if (!(args.get(1).getClass() == Constant.class)) {
				return null;
			}
			Constant arg0 = (Constant) args.get(0);
			Constant arg1 = (Constant) args.get(1);
			String sArg0 = arg0.getSymbol().toString();
			String sArg1 = arg1.getSymbol().toString();
			if (arg0.getType() != null && arg1.getType() != null) {
				if (arg0.getType().equals(Types.typeDouble) || arg1.getType().equals(Types.typeDouble)) {
					return new Constant(Double.toString(Double.parseDouble(sArg0) / Double.parseDouble(sArg1)), Types.typeDouble);
				} else if (arg0.getType().equals(Types.typeFloat) || arg1.getType().equals(Types.typeFloat)) {
					return new Constant(Float.toString(Float.parseFloat(sArg0) / Float.parseFloat(sArg1)), Types.typeFloat);
				} else if (arg0.getType().equals(Types.typeLong) || arg1.getType().equals(Types.typeLong)) {
					return new Constant(Long.toString(Long.parseLong(sArg0) / Long.parseLong(sArg1)), Types.typeLong);
				} else if (arg0.getType().equals(Types.typeInt) || arg1.getType().equals(Types.typeInt)) {
					return new Constant(Integer.toString(Integer.parseInt(sArg0) / Integer.parseInt(sArg1)), Types.typeInt);
				}
			}
			if (sArg0.contains(Parser.DOT) || sArg1.contains(Parser.DOT)) {
				return new Constant(Double.toString(Double.parseDouble(sArg0) / Double.parseDouble(sArg1)), Types.typeDouble);
			} else {
				return new Constant(Integer.toString(Integer.parseInt(sArg0) / Integer.parseInt(sArg1)), Types.typeInt);
			}
		}
	});
	public static final Symbol mod = new Symbol(Parser.MOD, 2, Symbol.Type.INFIX, "%", Symbol.Type.INFIX, new Symbol.ICalculator() {
		@Override
		public Expression calculate(List<Expression> args) {
			if (!(args.get(0).getClass() == Constant.class)) {
				return null;
			}
			if (!(args.get(1).getClass() == Constant.class)) {
				return null;
			}
			Constant arg0 = (Constant) args.get(0);
			Constant arg1 = (Constant) args.get(1);
			String sArg0 = arg0.getSymbol().toString();
			String sArg1 = arg1.getSymbol().toString();
			if (arg0.getType() != null && arg1.getType() != null) {
				if (arg0.getType().equals(Types.typeLong) || arg1.getType().equals(Types.typeLong)) {
					return new Constant(Long.toString(Long.parseLong(sArg0) % Long.parseLong(sArg1)), Types.typeLong);
				} else if (arg0.getType().equals(Types.typeInt) || arg1.getType().equals(Types.typeInt)) {
					return new Constant(Integer.toString(Integer.parseInt(sArg0) % Integer.parseInt(sArg1)), Types.typeInt);
				}
			}
			return new Constant(Integer.toString(Integer.parseInt(sArg0) % Integer.parseInt(sArg1)));
		}
	});
	public static final Symbol minus = new Symbol(Parser.MINUS, 1, new Symbol.ICalculator() {
		@Override
		public Expression calculate(List<Expression> args) {
			if (!(args.get(0).getClass() == Constant.class)) {
				return null;
			}
			Constant arg = (Constant) args.get(0);
			String sArg = arg.getSymbol().toString();
			if (arg.getType() != null) {
				if (arg.getType().equals(Types.typeDouble)) {
					return new Constant(Double.toString(-Double.parseDouble(sArg)), Types.typeDouble);
				} else if (arg.getType().equals(Types.typeFloat)) {
					return new Constant(Float.toString(-Float.parseFloat(sArg)), Types.typeFloat);
				} else if (arg.getType().equals(Types.typeLong)) {
					return new Constant(Long.toString(-Long.parseLong(sArg)), Types.typeLong);
				} else if (arg.getType().equals(Types.typeInt)) {
					return new Constant(Integer.toString(-Integer.parseInt(sArg)), Types.typeInt);
				}
			}
			if (sArg.contains(Parser.DOT)) {
				return new Constant(Double.toString(-Double.parseDouble(sArg)), Types.typeDouble);
			} else {
				return new Constant(Integer.toString(-Integer.parseInt(sArg)), Types.typeInt);
			}
		}
	});
	public static final Symbol eq = new Symbol(Parser.EQ, 2, Symbol.Type.INFIX, new Symbol.IImplGenerator() {
		@Override
		public String generate(Type type, Type[] childrenTypes, String[] children, String[] childrenSideEffects, String[] sideEffect) {
			for (String s: childrenSideEffects) {
				sideEffect[0] += s;
			}
			if (childrenTypes[0] != null && childrenTypes[0].equals(Types.typeString) 
					&& childrenTypes[1] != null && childrenTypes[1].equals(Types.typeString)) {
				return children[0] + ".equals(" + children[1] + ")";
			}
			return "(" + children[0] + "==" + children[1] + ")";
		}
	}, new Symbol.ICalculator() {
		@Override
		public Expression calculate(List<Expression> args) {
			if (!(args.get(0).getClass() == Constant.class)) {
				return null;
			}
			if (!(args.get(1).getClass() == Constant.class)) {
				return null;
			}
			Constant arg0 = (Constant) args.get(0);
			Constant arg1 = (Constant) args.get(1);
			String sArg0 = arg0.getSymbol().toString();
			String sArg1 = arg1.getSymbol().toString();
			boolean result = false;
			if (arg0.getType() == null || arg1.getType() == null) {
				if (sArg0.contains(Parser.DOT) || sArg1.contains(Parser.DOT)) {
					result = Double.parseDouble(sArg0) == Double.parseDouble(sArg1);
				} else {
					result = Integer.parseInt(sArg0) == Integer.parseInt(sArg1);
				}
			}
			if (arg0.getType().equals(Types.typeDouble) || arg1.getType().equals(Types.typeDouble)) {
				result = (Double.parseDouble(sArg0) == Double.parseDouble(sArg1));
			} else if (arg0.getType().equals(Types.typeFloat) || arg1.getType().equals(Types.typeFloat)) {
				result = (Float.parseFloat(sArg0) == Float.parseFloat(sArg1));
			} else if (arg0.getType().equals(Types.typeLong) || arg1.getType().equals(Types.typeLong)) {
				result = (Long.parseLong(sArg0) == Long.parseLong(sArg1));
			} else if (arg0.getType().equals(Types.typeInt) || arg1.getType().equals(Types.typeInt)) {
				result = (Integer.parseInt(sArg0) == Integer.parseInt(sArg1));
			} else if (arg0.getType().equals(Types.typeString) || arg1.getType().equals(Types.typeString)) {
				result = sArg0.toString().equals(sArg1.toString());
			}
			if (result) {
				return new Constant(true_);
			} else {
				return new Constant(false_);
			}
		}
	});
	public static final Symbol neq = new Symbol(Parser.NEQ, 2, Symbol.Type.INFIX, new Symbol.IImplGenerator() {
		@Override
		public String generate(Type type, Type[] childrenTypes, String[] children, String[] childrenSideEffects, String[] sideEffect) {
			for (String s: childrenSideEffects) {
				sideEffect[0] += s;
			}
			if (childrenTypes[0] != null && childrenTypes[0].equals(Types.typeString) 
					&& childrenTypes[1] != null && childrenTypes[1].equals(Types.typeString)) {
				return "!" + children[0] + ".equals(" + children[1] + ")";
			}
			return "(" + children[0] + "!=" + children[1] + ")";
		}
	}, new Symbol.ICalculator() {
		@Override
		public Expression calculate(List<Expression> args) {
			if (!(args.get(0).getClass() == Constant.class)) {
				return null;
			}
			if (!(args.get(1).getClass() == Constant.class)) {
				return null;
			}
			Constant arg0 = (Constant) args.get(0);
			Constant arg1 = (Constant) args.get(1);
			String sArg0 = arg0.getSymbol().toString();
			String sArg1 = arg1.getSymbol().toString();
			boolean result = false;
			if (arg0.getType() == null || arg1.getType() == null) {
				if (sArg0.contains(Parser.DOT) || sArg1.contains(Parser.DOT)) {
					result = Double.parseDouble(sArg0) != Double.parseDouble(sArg1);
				} else {
					result = Integer.parseInt(sArg0) != Integer.parseInt(sArg1);
				}
			}
			if (arg0.getType().equals(Types.typeDouble) || arg1.getType().equals(Types.typeDouble)) {
				result = (Double.parseDouble(sArg0) != Double.parseDouble(sArg1));
			} else if (arg0.getType().equals(Types.typeFloat) || arg1.getType().equals(Types.typeFloat)) {
				result = (Float.parseFloat(sArg0) != Float.parseFloat(sArg1));
			} else if (arg0.getType().equals(Types.typeLong) || arg1.getType().equals(Types.typeLong)) {
				result = (Long.parseLong(sArg0) != Long.parseLong(sArg1));
			} else if (arg0.getType().equals(Types.typeInt) || arg1.getType().equals(Types.typeInt)) {
				result = (Integer.parseInt(sArg0) != Integer.parseInt(sArg1));
			} else if (arg0.getType().equals(Types.typeString) || arg1.getType().equals(Types.typeString)) {
				result = !(sArg0.toString().equals(sArg1.toString()));
			}
			if (result) {
				return new Constant(true_);
			} else {
				return new Constant(false_);
			}
		}
	});
	public static final Symbol gt = new Symbol(Parser.GT, 2, Symbol.Type.INFIX, ">", Symbol.Type.INFIX, new Symbol.ICalculator() {
		@Override
		public Expression calculate(List<Expression> args) {
			if (!(args.get(0).getClass() == Constant.class)) {
				return null;
			}
			if (!(args.get(1).getClass() == Constant.class)) {
				return null;
			}
			Constant arg0 = (Constant) args.get(0);
			Constant arg1 = (Constant) args.get(1);
			String sArg0 = arg0.getSymbol().toString();
			String sArg1 = arg1.getSymbol().toString();
			boolean result = false;
			if (arg0.getType() == null || arg1.getType() == null) {
				if (sArg0.contains(Parser.DOT) || sArg1.contains(Parser.DOT)) {
					result = Double.parseDouble(sArg0) > Double.parseDouble(sArg1);
				} else {
					result = Integer.parseInt(sArg0) > Integer.parseInt(sArg1);
				}
			}
			if (arg0.getType().equals(Types.typeDouble) || arg1.getType().equals(Types.typeDouble)) {
				result = (Double.parseDouble(sArg0) > Double.parseDouble(sArg1));
			} else if (arg0.getType().equals(Types.typeFloat) || arg1.getType().equals(Types.typeFloat)) {
				result = (Float.parseFloat(sArg0) > Float.parseFloat(sArg1));
			} else if (arg0.getType().equals(Types.typeLong) || arg1.getType().equals(Types.typeLong)) {
				result = (Long.parseLong(sArg0) > Long.parseLong(sArg1));
			} else if (arg0.getType().equals(Types.typeInt) || arg1.getType().equals(Types.typeInt)) {
				result = (Integer.parseInt(sArg0) > Integer.parseInt(sArg1));
			}
			if (result) {
				return new Constant(true_);
			} else {
				return new Constant(false_);
			}
		}
	});
	public static final Symbol lt = new Symbol(Parser.LT, 2, Symbol.Type.INFIX, "<", Symbol.Type.INFIX, new Symbol.ICalculator() {
		@Override
		public Expression calculate(List<Expression> args) {
			if (!(args.get(0).getClass() == Constant.class)) {
				return null;
			}
			if (!(args.get(1).getClass() == Constant.class)) {
				return null;
			}
			Constant arg0 = (Constant) args.get(0);
			Constant arg1 = (Constant) args.get(1);
			String sArg0 = arg0.getSymbol().toString();
			String sArg1 = arg1.getSymbol().toString();
			boolean result = false;
			if (arg0.getType() == null || arg1.getType() == null) {
				if (sArg0.contains(Parser.DOT) || sArg1.contains(Parser.DOT)) {
					result = Double.parseDouble(sArg0) < Double.parseDouble(sArg1);
				} else {
					result = Integer.parseInt(sArg0) < Integer.parseInt(sArg1);
				}
			}
			if (arg0.getType().equals(Types.typeDouble) || arg1.getType().equals(Types.typeDouble)) {
				result = (Double.parseDouble(sArg0) < Double.parseDouble(sArg1));
			} else if (arg0.getType().equals(Types.typeFloat) || arg1.getType().equals(Types.typeFloat)) {
				result = (Float.parseFloat(sArg0) < Float.parseFloat(sArg1));
			} else if (arg0.getType().equals(Types.typeLong) || arg1.getType().equals(Types.typeLong)) {
				result = (Long.parseLong(sArg0) < Long.parseLong(sArg1));
			} else if (arg0.getType().equals(Types.typeInt) || arg1.getType().equals(Types.typeInt)) {
				result = (Integer.parseInt(sArg0) < Integer.parseInt(sArg1));
			}
			if (result) {
				return new Constant(true_);
			} else {
				return new Constant(false_);
			}
		}
	});
	public static final Symbol ge = new Symbol(Parser.GE, 2, Symbol.Type.INFIX, ">=", Symbol.Type.INFIX, new Symbol.ICalculator() {
		@Override
		public Expression calculate(List<Expression> args) {
			if (!(args.get(0).getClass() == Constant.class)) {
				return null;
			}
			if (!(args.get(1).getClass() == Constant.class)) {
				return null;
			}
			Constant arg0 = (Constant) args.get(0);
			Constant arg1 = (Constant) args.get(1);
			String sArg0 = arg0.getSymbol().toString();
			String sArg1 = arg1.getSymbol().toString();
			boolean result = false;
			if (arg0.getType() == null || arg1.getType() == null) {
				if (sArg0.contains(Parser.DOT) || sArg1.contains(Parser.DOT)) {
					result = Double.parseDouble(sArg0) >= Double.parseDouble(sArg1);
				} else {
					result = Integer.parseInt(sArg0) >= Integer.parseInt(sArg1);
				}
			}
			if (arg0.getType().equals(Types.typeDouble) || arg1.getType().equals(Types.typeDouble)) {
				result = (Double.parseDouble(sArg0) >= Double.parseDouble(sArg1));
			} else if (arg0.getType().equals(Types.typeFloat) || arg1.getType().equals(Types.typeFloat)) {
				result = (Float.parseFloat(sArg0) >= Float.parseFloat(sArg1));
			} else if (arg0.getType().equals(Types.typeLong) || arg1.getType().equals(Types.typeLong)) {
				result = (Long.parseLong(sArg0) >= Long.parseLong(sArg1));
			} else if (arg0.getType().equals(Types.typeInt) || arg1.getType().equals(Types.typeInt)) {
				result = (Integer.parseInt(sArg0) >= Integer.parseInt(sArg1));
			}
			if (result) {
				return new Constant(true_);
			} else {
				return new Constant(false_);
			}
		}
	});
	public static final Symbol le = new Symbol(Parser.LE, 2, Symbol.Type.INFIX, "<=", Symbol.Type.INFIX, new Symbol.ICalculator() {
		@Override
		public Expression calculate(List<Expression> args) {
			if (!(args.get(0).getClass() == Constant.class)) {
				return null;
			}
			if (!(args.get(1).getClass() == Constant.class)) {
				return null;
			}
			Constant arg0 = (Constant) args.get(0);
			Constant arg1 = (Constant) args.get(1);
			String sArg0 = arg0.getSymbol().toString();
			String sArg1 = arg1.getSymbol().toString();
			boolean result = false;
			if (arg0.getType() == null || arg1.getType() == null) {
				if (sArg0.contains(Parser.DOT) || sArg1.contains(Parser.DOT)) {
					result = Double.parseDouble(sArg0) <= Double.parseDouble(sArg1);
				} else {
					result = Integer.parseInt(sArg0) <= Integer.parseInt(sArg1);
				}
			}
			if (arg0.getType().equals(Types.typeDouble) || arg1.getType().equals(Types.typeDouble)) {
				result = (Double.parseDouble(sArg0) <= Double.parseDouble(sArg1));
			} else if (arg0.getType().equals(Types.typeFloat) || arg1.getType().equals(Types.typeFloat)) {
				result = (Float.parseFloat(sArg0) <= Float.parseFloat(sArg1));
			} else if (arg0.getType().equals(Types.typeLong) || arg1.getType().equals(Types.typeLong)) {
				result = (Long.parseLong(sArg0) <= Long.parseLong(sArg1));
			} else if (arg0.getType().equals(Types.typeInt) || arg1.getType().equals(Types.typeInt)) {
				result = (Integer.parseInt(sArg0) <= Integer.parseInt(sArg1));
			}
			if (result) {
				return new Constant(true_);
			} else {
				return new Constant(false_);
			}
		}
	});
	public static final Symbol and = new Symbol(Parser.AND, 2, Symbol.Type.INFIX, "&&", Symbol.Type.INFIX, new Symbol.ICalculator() {
		@Override
		public Expression calculate(List<Expression> args) {
			if (!(args.get(0).getClass() == Constant.class)) {
				return null;
			}
			if (!(args.get(1).getClass() == Constant.class)) {
				return null;
			}
			Constant arg0 = (Constant) args.get(0);
			Constant arg1 = (Constant) args.get(1);
			String sArg0 = arg0.getSymbol().toString();
			String sArg1 = arg1.getSymbol().toString();
			boolean result = false;
			if (arg0.getType() == null || arg1.getType() == null) return null;
			if (arg0.getType().equals(Types.typeBoolean) || arg1.getType().equals(Types.typeBoolean)) {
				result = (Boolean.parseBoolean(sArg0) && Boolean.parseBoolean(sArg1));
			}
			if (result) {
				return new Constant(true_);
			} else {
				return new Constant(false_);
			}
		}
	});
	public static final Symbol or = new Symbol(Parser.OR, 2, Symbol.Type.INFIX, "||", Symbol.Type.INFIX, new Symbol.ICalculator() {
		@Override
		public Expression calculate(List<Expression> args) {
			if (!(args.get(0).getClass() == Constant.class)) {
				return null;
			}
			if (!(args.get(1).getClass() == Constant.class)) {
				return null;
			}
			Constant arg0 = (Constant) args.get(0);
			Constant arg1 = (Constant) args.get(1);
			String sArg0 = arg0.getSymbol().toString();
			String sArg1 = arg1.getSymbol().toString();
			boolean result = false;
			if (arg0.getType() == null || arg1.getType() == null) return null;
			if (arg0.getType().equals(Types.typeBoolean) || arg1.getType().equals(Types.typeBoolean)) {
				result = (Boolean.parseBoolean(sArg0) || Boolean.parseBoolean(sArg1));
			}
			if (result) {
				return new Constant(true_);
			} else {
				return new Constant(false_);
			}
		}
	});
	public static final Symbol neg = new Symbol(Parser.NEG, 1, Symbol.Type.PREFIX, "!", Symbol.Type.PREFIX, new Symbol.ICalculator() {
		@Override
		public Expression calculate(List<Expression> args) {
			if (!(args.get(0).getClass() == Constant.class)) {
				return null;
			}
			Constant arg0 = (Constant) args.get(0);
			String sArg0 = arg0.getSymbol().toString();
			boolean result = false;
			if (arg0.getType() == null) return null;
			if (arg0.getType().equals(Types.typeBoolean)) {
				result = !Boolean.parseBoolean(sArg0);
			}
			if (result) {
				return new Constant(true_);
			} else {
				return new Constant(false_);
			}
		}
	});
	
}