Skip to content

Commit

Permalink
move to expression ast for easier maintenance
Browse files Browse the repository at this point in the history
Each IExpression represents a cc-expression. An expression produces an IValue. Each IValue knows how to let coerce itself to the target type.
  • Loading branch information
Andrin Meier committed Mar 4, 2016
1 parent e8f6b04 commit 3641b0b
Show file tree
Hide file tree
Showing 77 changed files with 3,160 additions and 1,875 deletions.
40 changes: 40 additions & 0 deletions Rubberduck.Parsing/Preprocessing/AbsLibraryFunctionExpression.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
using System;

namespace Rubberduck.Parsing.Preprocessing
{
public sealed class AbsLibraryFunctionExpression : Expression
{
private readonly IExpression _expression;

public AbsLibraryFunctionExpression(IExpression expression)
{
_expression = expression;
}

public override IValue Evaluate()
{
var expr = _expression.Evaluate();
if (expr == null)
{
return null;
}
if (expr.ValueType == ValueType.Date)
{
decimal exprValue = expr.AsDecimal;
exprValue = Math.Abs(exprValue);
try
{
return new DateValue(new DecimalValue(exprValue).AsDate);
}
catch
{
return new DecimalValue(exprValue);
}
}
else
{
return new DecimalValue(Math.Abs(expr.AsDecimal));
}
}
}
}
27 changes: 27 additions & 0 deletions Rubberduck.Parsing/Preprocessing/BinaryDivisionExpression.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
namespace Rubberduck.Parsing.Preprocessing
{
public sealed class BinaryDivisionExpression : Expression
{
private readonly IExpression _left;
private readonly IExpression _right;

public BinaryDivisionExpression(IExpression left, IExpression right)
{
_left = left;
_right = right;
}

public override IValue Evaluate()
{
var left = _left.Evaluate();
var right = _right.Evaluate();
if (left == null || right == null)
{
return null;
}
var leftValue = left.AsDecimal;
var rightValue = right.AsDecimal;
return new DecimalValue(leftValue / rightValue);
}
}
}
29 changes: 29 additions & 0 deletions Rubberduck.Parsing/Preprocessing/BinaryIntDivExpression.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
using System;

namespace Rubberduck.Parsing.Preprocessing
{
public sealed class BinaryIntDivExpression : Expression
{
private readonly IExpression _left;
private readonly IExpression _right;

public BinaryIntDivExpression(IExpression left, IExpression right)
{
_left = left;
_right = right;
}

public override IValue Evaluate()
{
var left = _left.Evaluate();
var right = _right.Evaluate();
if (left == null || right == null)
{
return null;
}
var leftValue = Convert.ToInt64(left.AsDecimal);
var rightValue = Convert.ToInt64(right.AsDecimal);
return new DecimalValue(Math.Truncate((decimal)leftValue / rightValue));
}
}
}
53 changes: 53 additions & 0 deletions Rubberduck.Parsing/Preprocessing/BinaryMinusExpression.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
namespace Rubberduck.Parsing.Preprocessing
{
public sealed class BinaryMinusExpression : Expression
{
private readonly IExpression _left;
private readonly IExpression _right;

public BinaryMinusExpression(IExpression left, IExpression right)
{
_left = left;
_right = right;
}

public override IValue Evaluate()
{
var left = _left.Evaluate();
var right = _right.Evaluate();
if (left == null || right == null)
{
return null;
}
else if (left.ValueType == ValueType.Date && right.ValueType == ValueType.Date)
{
// 5.6.9.3.3 - Effective value type exception.
// If left + right are both Date then effective value type is double.
decimal leftValue = left.AsDecimal;
decimal rightValue = right.AsDecimal;
decimal difference = leftValue - rightValue;
return new DecimalValue(difference);
}
else if (left.ValueType == ValueType.Date || right.ValueType == ValueType.Date)
{
decimal leftValue = left.AsDecimal;
decimal rightValue = right.AsDecimal;
decimal difference = leftValue - rightValue;
try
{
return new DateValue(new DecimalValue(difference).AsDate);
}
catch
{
return new DecimalValue(difference);
}
}
else
{
decimal leftValue = left.AsDecimal;
decimal rightValue = right.AsDecimal;
return new DecimalValue(leftValue - rightValue);
}
}
}
}
29 changes: 29 additions & 0 deletions Rubberduck.Parsing/Preprocessing/BinaryMultiplicationExpression.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
using System;

namespace Rubberduck.Parsing.Preprocessing
{
public sealed class BinaryMultiplicationExpression : Expression
{
private readonly IExpression _left;
private readonly IExpression _right;

public BinaryMultiplicationExpression(IExpression left, IExpression right)
{
_left = left;
_right = right;
}

public override IValue Evaluate()
{
var left = _left.Evaluate();
var right = _right.Evaluate();
if (left == null || right == null)
{
return null;
}
var leftValue = left.AsDecimal;
var rightValue = right.AsDecimal;
return new DecimalValue(leftValue * rightValue);
}
}
}
48 changes: 48 additions & 0 deletions Rubberduck.Parsing/Preprocessing/BinaryPlusExpression.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
namespace Rubberduck.Parsing.Preprocessing
{
public sealed class BinaryPlusExpression : Expression
{
private readonly IExpression _left;
private readonly IExpression _right;

public BinaryPlusExpression(IExpression left, IExpression right)
{
_left = left;
_right = right;
}

public override IValue Evaluate()
{
var left = _left.Evaluate();
var right = _right.Evaluate();
if (left == null || right == null)
{
return null;
}
if (left.ValueType == ValueType.String)
{
return new StringValue(left.AsString+ right.AsString);
}
else if (left.ValueType == ValueType.Date || right.ValueType == ValueType.Date)
{
decimal leftValue = left.AsDecimal;
decimal rightValue = right.AsDecimal;
decimal sum = leftValue + rightValue;
try
{
return new DateValue(new DecimalValue(sum).AsDate);
}
catch
{
return new DecimalValue(sum);
}
}
else
{
var leftNumber = left.AsDecimal;
var rightNumber = right.AsDecimal;
return new DecimalValue(leftNumber + rightNumber);
}
}
}
}
50 changes: 0 additions & 50 deletions Rubberduck.Parsing/Preprocessing/BoolLetCoercion.cs

This file was deleted.

85 changes: 85 additions & 0 deletions Rubberduck.Parsing/Preprocessing/BoolValue.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
using System;

namespace Rubberduck.Parsing.Preprocessing
{
public sealed class BoolValue : IValue
{
private readonly bool _value;

public BoolValue(bool value)
{
_value = value;
}

public ValueType ValueType
{
get
{
return ValueType.Bool;
}
}

public bool AsBool
{
get
{
return _value;
}
}

public byte AsByte
{
get
{
if (_value)
{
return 255;
}
return 0;
}
}

public DateTime AsDate
{
get
{
return new DecimalValue(AsDecimal).AsDate;
}
}

public decimal AsDecimal
{
get
{
if (_value)
{
return -1;
}
else
{
return 0;
}
}
}

public string AsString
{
get
{
if (_value)
{
return "True";
}
else
{
return "False";
}
}
}

public override string ToString()
{
return _value.ToString();
}
}
}

0 comments on commit 3641b0b

Please sign in to comment.