Skip to content

Commit

Permalink
Version up + minor refactor.
Browse files Browse the repository at this point in the history
  • Loading branch information
jwaliszko committed Oct 15, 2014
1 parent c17f2c0 commit 959f833
Show file tree
Hide file tree
Showing 3 changed files with 34 additions and 36 deletions.
7 changes: 4 additions & 3 deletions src/ExpressiveAnnotations.Tests/ParserTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -108,19 +108,20 @@ public void verify_logic_without_context()
Assert.IsTrue(parser.Parse<object>("!!!true == false").Invoke(null));

Assert.IsTrue(parser.Parse<object>("true != !true").Invoke(null));
Assert.IsTrue(parser.Parse<object>("!!true != !!!true").Invoke(null));

Assert.IsTrue(parser.Parse<object>("true && true").Invoke(null));
Assert.IsFalse(parser.Parse<object>("false && false").Invoke(null));
Assert.IsFalse(parser.Parse<object>("true && false").Invoke(null));
Assert.IsFalse(parser.Parse<object>("false && true").Invoke(null));
Assert.IsFalse(parser.Parse<object>("false && true").Invoke(null));

Assert.IsTrue(parser.Parse<object>("true || true").Invoke(null));
Assert.IsFalse(parser.Parse<object>("false || false").Invoke(null));
Assert.IsTrue(parser.Parse<object>("true || false").Invoke(null));
Assert.IsTrue(parser.Parse<object>("false || true").Invoke(null));
Assert.IsTrue(parser.Parse<object>("false || true").Invoke(null));

Assert.IsTrue(parser.Parse<object>("(true || ((true || (false || true)))) || (true && true && false || (false || true && (true && true || ((false))))) && false").Invoke(null));
Assert.IsTrue(parser.Parse<object>("( !!((!(!!!true || !!false || !true))) && true && !(true && false) ) && (!((!(!true))) || !!!(((!true))))").Invoke(null));
Assert.IsTrue(parser.Parse<object>("( !!((!(!!!true || !!false || !true))) && true && !(true && false) ) && (!((!(!true))) || !!!(((!true))))").Invoke(null));

Assert.IsTrue(parser.Parse<object>("0 == 0 && 1 < 2").Invoke(null));

Expand Down
59 changes: 28 additions & 31 deletions src/ExpressiveAnnotations/Analysis/Parser.cs
Original file line number Diff line number Diff line change
Expand Up @@ -309,14 +309,14 @@ private Expression ParseOrExp()
var arg1 = ParseAndExp();
if (PeekType() != TokenType.OR)
return arg1;
var tkn = PeekToken();
var oper = PeekToken();
ReadToken();
var arg2 = ParseOrExp();

if (!arg1.Type.IsBool() || !arg2.Type.IsBool())
throw new ParseErrorException(
string.Format("Operator '{0}' cannot be applied to operands of type '{1}' and '{2}'.", tkn.Value, arg1.Type, arg2.Type),
tkn.Location);
string.Format("Operator '{0}' cannot be applied to operands of type '{1}' and '{2}'.", oper.Value, arg1.Type, arg2.Type),
oper.Location);

return Expression.OrElse(arg1, arg2); // short-circuit evaluation
}
Expand All @@ -326,14 +326,14 @@ private Expression ParseAndExp()
var arg1 = ParseRelExp();
if (PeekType() != TokenType.AND)
return arg1;
var tkn = PeekToken();
var oper = PeekToken();
ReadToken();
var arg2 = ParseAndExp();

if (!arg1.Type.IsBool() || !arg2.Type.IsBool())
throw new ParseErrorException(
string.Format("Operator '{0}' cannot be applied to operands of type '{1}' and '{2}'.", tkn.Value, arg1.Type, arg2.Type),
tkn.Location);
string.Format("Operator '{0}' cannot be applied to operands of type '{1}' and '{2}'.", oper.Value, arg1.Type, arg2.Type),
oper.Location);

return Expression.AndAlso(arg1, arg2); // short-circuit evaluation
}
Expand All @@ -343,19 +343,18 @@ private Expression ParseRelExp()
var arg1 = ParseNotExp();
if (!new[] {TokenType.LT, TokenType.LE, TokenType.GT, TokenType.GE, TokenType.EQ, TokenType.NEQ}.Contains(PeekType()))
return arg1;
var tkn = PeekToken();
var oper = PeekType();
var oper = PeekToken();
ReadToken();
var arg2 = ParseNotExp();

if (oper != TokenType.EQ && oper != TokenType.NEQ)
if (oper.Type != TokenType.EQ && oper.Type != TokenType.NEQ)
if ((!arg1.Type.IsNumeric() || !arg2.Type.IsNumeric()) && (!arg1.Type.IsDateTime() || !arg2.Type.IsDateTime()))
throw new ParseErrorException(
string.Format("Operator '{0}' cannot be applied to operands of type '{1}' and '{2}'.", tkn.Value, arg1.Type, arg2.Type),
tkn.Location);
string.Format("Operator '{0}' cannot be applied to operands of type '{1}' and '{2}'.", oper.Value, arg1.Type, arg2.Type),
oper.Location);

Helper.MakeTypesCompatible(arg1, arg2, out arg1, out arg2);
switch (oper)
switch (oper.Type)
{
case TokenType.LT:
return Expression.LessThan(arg1, arg2);
Expand All @@ -378,14 +377,14 @@ private Expression ParseNotExp()
{
if (PeekType() != TokenType.NOT)
return ParseAddExp();
var tkn = PeekToken();
var oper = PeekToken();
ReadToken();
var arg = ParseNotExp(); // allow multiple negations

if (!arg.Type.IsBool())
throw new ParseErrorException(
string.Format("Operator '{0}' cannot be applied to operand of type '{1}'.", tkn.Value, arg.Type),
tkn.Location);
string.Format("Operator '{0}' cannot be applied to operand of type '{1}'.", oper.Value, arg.Type),
oper.Location);

return Expression.Not(arg);
}
Expand All @@ -405,23 +404,22 @@ private Expression ParseAddExpInternal(Expression arg1)
{
if (!new[] {TokenType.ADD, TokenType.SUB}.Contains(PeekType()))
return arg1;
var tkn = PeekToken();
var oper = PeekType();
var oper = PeekToken();
ReadToken();
var sign = UnifySign();
var arg2 = ParseMulExp();

if (sign == TokenType.SUB)
arg2 = InverseNumber(arg2);

if (oper == TokenType.SUB)
if (oper.Type == TokenType.SUB)
if (arg1.Type.IsString() || arg2.Type.IsString())
throw new ParseErrorException(
string.Format("Operator '{0}' cannot be applied to operands of type '{1}' and '{2}'.", tkn.Value, arg1.Type, arg2.Type),
tkn.Location);
string.Format("Operator '{0}' cannot be applied to operands of type '{1}' and '{2}'.", oper.Value, arg1.Type, arg2.Type),
oper.Location);

Helper.MakeTypesCompatible(arg1, arg2, out arg1, out arg2);
switch (oper)
switch (oper.Type)
{
case TokenType.ADD:
return ParseAddExpInternal(
Expand Down Expand Up @@ -453,8 +451,7 @@ private Expression ParseMulExpInternal(Expression arg1)
{
if (!new[] {TokenType.MUL, TokenType.DIV}.Contains(PeekType()))
return arg1;
var tkn = PeekToken();
var oper = PeekType();
var oper = PeekToken();
ReadToken();
var sign = UnifySign();
var arg2 = ParseVal();
Expand All @@ -464,11 +461,11 @@ private Expression ParseMulExpInternal(Expression arg1)

if (!arg1.Type.IsNumeric() || !arg2.Type.IsNumeric())
throw new ParseErrorException(
string.Format("Operator '{0}' cannot be applied to operands of type '{1}' and '{2}'.", tkn.Value, arg1.Type, arg2.Type),
tkn.Location);
string.Format("Operator '{0}' cannot be applied to operands of type '{1}' and '{2}'.", oper.Value, arg1.Type, arg2.Type),
oper.Location);

Helper.MakeTypesCompatible(arg1, arg2, out arg1, out arg2);
switch (oper)
switch (oper.Type)
{
case TokenType.MUL:
return ParseMulExpInternal(Expression.Multiply(arg1, arg2));
Expand Down Expand Up @@ -554,8 +551,8 @@ private Expression ParseString()

private Expression ParseFunc()
{
var funcTkn = PeekToken();
var name = PeekValue().ToString();
var func = PeekToken();
var name = func.Value.ToString();
ReadToken(); // read name

if (PeekType() != TokenType.LEFT_BRACKET)
Expand All @@ -566,15 +563,15 @@ private Expression ParseFunc()
var args = new List<Tuple<Expression, Location>>();
while (PeekType() != TokenType.RIGHT_BRACKET) // read comma-separated arguments until we hit ")"
{
var argTkn = PeekToken();
var tkn = PeekToken();
var arg = ParseOrExp();
if (PeekType() == TokenType.COMMA)
ReadToken();
args.Add(new Tuple<Expression, Location>(arg, argTkn.Location));
args.Add(new Tuple<Expression, Location>(arg, tkn.Location));
}
ReadToken(); // read ")"

return ExtractMethodExpression(name, args, funcTkn.Location); // get method call
return ExtractMethodExpression(name, args, func.Location); // get method call
}

private Expression ExtractFieldExpression(string name)
Expand Down
4 changes: 2 additions & 2 deletions src/ExpressiveAnnotations/Properties/AssemblyInfo.cs
Original file line number Diff line number Diff line change
Expand Up @@ -48,5 +48,5 @@
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("2.2.4.0")]
[assembly: AssemblyFileVersion("2.2.4.0")]
[assembly: AssemblyVersion("2.2.5.0")]
[assembly: AssemblyFileVersion("2.2.5.0")]

0 comments on commit 959f833

Please sign in to comment.