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