public static string FormatValue(Literal literal) { switch (literal.ValueType.Type) { case DataType.Unit: if (literal.Value != null) throw new InvalidProgramException(); return literal.ValueType.Unit.ToString(); case DataType.Boolean: if (literal.Value is bool == false) throw new InvalidProgramException(); return literal.Value.ToString(); case DataType.Int: if (literal.Value is int == false) throw new InvalidProgramException(); return literal.Value.ToString(); case DataType.Double: if (literal.Value is double == false) throw new InvalidProgramException(); return ((double)literal.Value).ToString(CultureInfo.InvariantCulture); case DataType.String: if (literal.Value is string == false) throw new InvalidProgramException(); return "\"" + literal.Value + "\""; default: throw new NotImplementedException(); } }
public static Literal Calculate(BinaryOp op, Literal left, Literal right) { var range = new CodeRange(left, right); object val = CalculateValue(op, left, right); var type = TypeEvaluator.GetType(left.ValueType, op, right.ValueType); return new Literal(range, type, val); }
public static Literal ToLiteral(this Token token) { var lt = (LiteralToken)token; var exp = new Literal(lt.CodeRange, GetLaxType(lt.Type), token.Value); return exp; }
private static object CalculateValue(BinaryOp op, Literal left, Literal right) { if (op.Operator == "*") { if (left.ValueType.Type == DataType.Unit) return right.Value; if (right.ValueType.Type == DataType.Unit) return left.Value; } if (op.Operator == "/") { if (right.ValueType.Type == DataType.Unit) return left.Value; } string key = (left.ValueType.Type + " " + op.Operator + " " + right.ValueType.Type).ToLowerInvariant(); switch (key) { case "double + double": return (double)left.Value + (double)right.Value; case "double - double": return (double)left.Value - (double)right.Value; case "double * double": return (double)left.Value * (double)right.Value; case "double / double": return (double)left.Value / (double)right.Value; case "int + int": return (int)left.Value + (int)right.Value; case "int - int": return (int)left.Value - (int)right.Value; case "int * int": return (int)left.Value * (int)right.Value; case "int / int": return (int)left.Value / (int)right.Value; case "double + int": return (double)left.Value + (int)right.Value; case "int + double": return (int)left.Value + (double)right.Value; case "double - int": return (double)left.Value - (int)right.Value; case "int - double": return (int)left.Value - (double)right.Value; case "double * int": return (double)left.Value * (int)right.Value; case "int * double": return (int)left.Value * (double)right.Value; case "double / int": return (double)left.Value / (int)right.Value; case "int / double": return (int)left.Value / (double)right.Value; case "boolean and boolean": return (bool)left.Value && (bool)right.Value; case "boolean or boolean": return (bool)left.Value || (bool)right.Value; default: throw new SyntaxError(op.CodeRange, "Operator-type not implemented: " + key); } }
void PushLiteral(Literal exp) { //Check that we have an operator if (opStack.Count != operandStack.Count) throw new SyntaxError(exp.CodeRange, "Expected operand"); //Operand operandStack.Push(exp); }