Implements remainder and exponent operators
This commit is contained in:
parent
f504a8706e
commit
9bd82174f2
|
@ -1,3 +1,5 @@
|
|||
using System;
|
||||
|
||||
namespace Upsilon.BaseTypes.Number
|
||||
{
|
||||
internal abstract class ScriptNumber : ScriptType
|
||||
|
@ -41,6 +43,17 @@ namespace Upsilon.BaseTypes.Number
|
|||
return new ScriptNumberDouble(((ScriptNumberLong) a).Value * ((ScriptNumberDouble) b).Value);
|
||||
}
|
||||
|
||||
public static ScriptNumber operator % (ScriptNumber a, ScriptNumber b)
|
||||
{
|
||||
if (!a.IsFloat && !b.IsFloat)
|
||||
return new ScriptNumberLong(((ScriptNumberLong) a).Value % ((ScriptNumberLong) b).Value);
|
||||
if (a.IsFloat && b.IsFloat)
|
||||
return new ScriptNumberDouble(((ScriptNumberDouble) a).Value % ((ScriptNumberDouble) b).Value);
|
||||
if (a.IsFloat)
|
||||
return new ScriptNumberDouble(((ScriptNumberDouble) a).Value % ((ScriptNumberLong) b).Value);
|
||||
return new ScriptNumberDouble(((ScriptNumberLong) a).Value % ((ScriptNumberDouble) b).Value);
|
||||
}
|
||||
|
||||
public static ScriptNumber operator / (ScriptNumber a, ScriptNumber b)
|
||||
{
|
||||
if (!a.IsFloat && !b.IsFloat)
|
||||
|
@ -60,6 +73,18 @@ namespace Upsilon.BaseTypes.Number
|
|||
return new ScriptNumberLong(-((ScriptNumberLong)n).Value);
|
||||
}
|
||||
|
||||
public static ScriptNumber Exponent(ScriptNumber a, ScriptNumber b)
|
||||
{
|
||||
if (!a.IsFloat && !b.IsFloat)
|
||||
return new ScriptNumberLong((long) Math.Pow(((ScriptNumberLong) a).Value, ((ScriptNumberLong) b).Value));
|
||||
if (a.IsFloat && b.IsFloat)
|
||||
return new ScriptNumberDouble(Math.Pow(((ScriptNumberDouble) a).Value, ((ScriptNumberDouble) b).Value));
|
||||
if (a.IsFloat)
|
||||
return new ScriptNumberDouble(Math.Pow(((ScriptNumberDouble) a).Value, ((ScriptNumberLong) b).Value));
|
||||
return new ScriptNumberDouble(Math.Pow(((ScriptNumberLong) a).Value, ((ScriptNumberDouble) b).Value));
|
||||
}
|
||||
|
||||
|
||||
|
||||
#region Equality
|
||||
private bool Equals(ScriptNumber other)
|
||||
|
@ -117,6 +142,7 @@ namespace Upsilon.BaseTypes.Number
|
|||
|
||||
|
||||
|
||||
|
||||
public static explicit operator double(ScriptNumber n)
|
||||
{
|
||||
if (n.IsFloat)
|
||||
|
|
|
@ -15,7 +15,9 @@ namespace Upsilon.Binder
|
|||
LessEquals,
|
||||
Less,
|
||||
And,
|
||||
Or
|
||||
Or,
|
||||
Exponent,
|
||||
Remainder
|
||||
}
|
||||
|
||||
private Type LeftType { get; }
|
||||
|
@ -46,6 +48,8 @@ namespace Upsilon.Binder
|
|||
new BoundBinaryOperator(OperatorKind.Subtraction, Type.Number),
|
||||
new BoundBinaryOperator(OperatorKind.Multiplication, Type.Number),
|
||||
new BoundBinaryOperator(OperatorKind.Division, Type.Number),
|
||||
new BoundBinaryOperator(OperatorKind.Exponent, Type.Number),
|
||||
new BoundBinaryOperator(OperatorKind.Remainder, Type.Number),
|
||||
|
||||
// Number equality
|
||||
new BoundBinaryOperator(OperatorKind.Equality, Type.Number, Type.Number, Type.Boolean),
|
||||
|
@ -102,6 +106,12 @@ namespace Upsilon.Binder
|
|||
case SyntaxKind.Slash:
|
||||
kind = OperatorKind.Division;
|
||||
break;
|
||||
case SyntaxKind.PercentSign:
|
||||
kind = OperatorKind.Remainder;
|
||||
break;
|
||||
case SyntaxKind.RoofSign:
|
||||
kind = OperatorKind.Exponent;
|
||||
break;
|
||||
case SyntaxKind.EqualsEquals:
|
||||
kind = OperatorKind.Equality;
|
||||
break;
|
||||
|
|
|
@ -288,7 +288,7 @@ namespace Upsilon.Evaluator
|
|||
}
|
||||
goto default;
|
||||
case BoundBinaryOperator.OperatorKind.Subtraction:
|
||||
if (left.Type == Type.Number)
|
||||
if (left.Type == Type.Number && right.Type == Type.Number)
|
||||
{
|
||||
return ((ScriptNumber)left) - ((ScriptNumber)right);
|
||||
}
|
||||
|
@ -301,7 +301,7 @@ namespace Upsilon.Evaluator
|
|||
}
|
||||
goto default;
|
||||
case BoundBinaryOperator.OperatorKind.Multiplication:
|
||||
if (left.Type == Type.Number)
|
||||
if (left.Type == Type.Number && right.Type == Type.Number)
|
||||
{
|
||||
return ((ScriptNumber)left) * ((ScriptNumber)right);
|
||||
}
|
||||
|
@ -314,7 +314,7 @@ namespace Upsilon.Evaluator
|
|||
}
|
||||
goto default;
|
||||
case BoundBinaryOperator.OperatorKind.Division:
|
||||
if (left.Type == Type.Number)
|
||||
if (left.Type == Type.Number && right.Type == Type.Number)
|
||||
{
|
||||
return ((ScriptNumber)left) / ((ScriptNumber)right);
|
||||
}
|
||||
|
@ -326,6 +326,18 @@ namespace Upsilon.Evaluator
|
|||
return type;
|
||||
}
|
||||
goto default;
|
||||
case BoundBinaryOperator.OperatorKind.Exponent:
|
||||
if (left.Type == Type.Number && right.Type == Type.Number)
|
||||
{
|
||||
return ScriptNumber.Exponent((ScriptNumber) left, (ScriptNumber) right);
|
||||
}
|
||||
goto default;
|
||||
case BoundBinaryOperator.OperatorKind.Remainder:
|
||||
if (left.Type == Type.Number && right.Type == Type.Number)
|
||||
{
|
||||
return ((ScriptNumber)left) % ((ScriptNumber)right);
|
||||
}
|
||||
goto default;
|
||||
case BoundBinaryOperator.OperatorKind.Equality:
|
||||
return new ScriptBoolean(Equals(left, right));
|
||||
case BoundBinaryOperator.OperatorKind.Inequality:
|
||||
|
|
|
@ -102,6 +102,10 @@ namespace Upsilon.Parser
|
|||
return new SyntaxToken(SyntaxKind.Comma, _position, ",", null);
|
||||
case '#':
|
||||
return new SyntaxToken(SyntaxKind.PoundSign, _position, "#", null);
|
||||
case '%':
|
||||
return new SyntaxToken(SyntaxKind.PercentSign, _position, "%", null);
|
||||
case '^':
|
||||
return new SyntaxToken(SyntaxKind.RoofSign, _position, "^", null);
|
||||
case '"':
|
||||
return LexString();
|
||||
case '=':
|
||||
|
|
|
@ -87,5 +87,7 @@ namespace Upsilon.Parser
|
|||
NumericForStatement,
|
||||
BreakStatement,
|
||||
GenericForStatement,
|
||||
PercentSign,
|
||||
RoofSign
|
||||
}
|
||||
}
|
|
@ -5,13 +5,12 @@ namespace Upsilon.Parser
|
|||
public enum Precedence
|
||||
{
|
||||
None = 0,
|
||||
Or,
|
||||
And,
|
||||
LogicalOr,
|
||||
LogicalAnd,
|
||||
Equality,
|
||||
PlusMinus,
|
||||
StarSlash,
|
||||
Additive,
|
||||
Multiplicative,
|
||||
Unary,
|
||||
Exponentiation
|
||||
}
|
||||
|
||||
public static Precedence UnaryOperatorPrecedence(this SyntaxKind kind)
|
||||
|
@ -44,18 +43,23 @@ namespace Upsilon.Parser
|
|||
|
||||
// logical operators
|
||||
case SyntaxKind.AndKeyword:
|
||||
return Precedence.And;
|
||||
return Precedence.LogicalAnd;
|
||||
case SyntaxKind.OrKeyword:
|
||||
return Precedence.Or;
|
||||
return Precedence.LogicalOr;
|
||||
|
||||
// math operators
|
||||
case SyntaxKind.Plus:
|
||||
case SyntaxKind.Minus:
|
||||
return Precedence.PlusMinus;
|
||||
return Precedence.Additive;
|
||||
|
||||
case SyntaxKind.Star:
|
||||
case SyntaxKind.Slash:
|
||||
return Precedence.StarSlash;
|
||||
case SyntaxKind.PercentSign:
|
||||
case SyntaxKind.RoofSign:
|
||||
return Precedence.Multiplicative;
|
||||
|
||||
|
||||
|
||||
default:
|
||||
return Precedence.None;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue