diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..818aab3 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,20 @@ +name: CI +on: [push, pull_request] + +jobs: + build-linux: + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v1 + + - name: Setup .NET Core + uses: actions/setup-dotnet@v1 + with: + dotnet-version: 3.0.101 + - name: Get NuGet packages + run: dotnet restore + - name: Build with dotnet + run: dotnet build --configuration Release + - name: Run Unit Tests + run: dotnet test diff --git a/.travis.yml b/.travis.yml index 3988856..f3eafa9 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,6 +1,6 @@ language: csharp mono: none -dotnet: 2.2.401 +dotnet: 3.0.101 solution: Dust.sln @@ -8,5 +8,5 @@ install: - dotnet restore script: - - dotnet build - - dotnet test \ No newline at end of file + - dotnet build --configuration Release + - dotnet test diff --git a/Dust.CLI/Dust.CLI.csproj b/Dust.CLI/Dust.CLI.csproj index 049359e..f5c4f6b 100644 --- a/Dust.CLI/Dust.CLI.csproj +++ b/Dust.CLI/Dust.CLI.csproj @@ -1,8 +1,8 @@  Exe - netcoreapp2.0 - 7.2 + netcoreapp3.0 + default diff --git a/Dust.UnitTests/Dust.UnitTests.csproj b/Dust.UnitTests/Dust.UnitTests.csproj index 740e923..9914301 100644 --- a/Dust.UnitTests/Dust.UnitTests.csproj +++ b/Dust.UnitTests/Dust.UnitTests.csproj @@ -1,21 +1,21 @@ - netcoreapp2.1 + netcoreapp3.0 false - - - - - + + + + + - + diff --git a/Dust/Compiler/Binding/Binder.cs b/Dust/Compiler/Binding/Binder.cs index 203b683..d3eed1d 100644 --- a/Dust/Compiler/Binding/Binder.cs +++ b/Dust/Compiler/Binding/Binder.cs @@ -56,7 +56,7 @@ private BoundBinaryExpression BindBinaryExpression(BinaryExpression binaryExpres BoundExpression left = BindExpression(binaryExpression.Left); BoundExpression right = BindExpression(binaryExpression.Right); - BinaryOperatorKind kind = SyntaxFacts.GetBinaryOperatorKind(binaryExpression.OperatorToken); + BinaryOperatorKind kind = (BinaryOperatorKind) binaryExpression.OperatorToken.Kind; BoundBinaryOperator @operator = BoundBinaryOperator.Bind(left.Type, kind, right.Type); if (@operator == null) diff --git a/Dust/Compiler/Binding/BoundBinaryOperator.cs b/Dust/Compiler/Binding/BoundBinaryOperator.cs index 3c2241a..9f7b763 100644 --- a/Dust/Compiler/Binding/BoundBinaryOperator.cs +++ b/Dust/Compiler/Binding/BoundBinaryOperator.cs @@ -10,18 +10,20 @@ public class BoundBinaryOperator public DustType LeftType { get; } public DustType RightType { get; } public DustType ReturnType { get; } + public bool IsInterchangeable { get; } public BoundBinaryOperator(BinaryOperatorKind kind, DustType type) : this(kind, type, type, type) { } - public BoundBinaryOperator(BinaryOperatorKind kind, DustType leftType, DustType rightType, DustType returnType) + public BoundBinaryOperator(BinaryOperatorKind kind, DustType leftType, DustType rightType, DustType returnType, bool isInterchangeable = true) { Kind = kind; LeftType = leftType; RightType = rightType; ReturnType = returnType; + IsInterchangeable = isInterchangeable; } private static readonly List binaryOperators = new List @@ -52,7 +54,23 @@ public BoundBinaryOperator(BinaryOperatorKind kind, DustType leftType, DustType public static BoundBinaryOperator Bind(DustType leftType, BinaryOperatorKind kind, DustType rightType) { - return binaryOperators.Find((@operator) => @operator.Kind == kind && @operator.LeftType.IsAssignableFrom(leftType) && @operator.RightType.IsAssignableFrom(rightType)); + foreach (BoundBinaryOperator @operator in binaryOperators) + { + if (@operator.Kind == kind) + { + if (@operator.LeftType.IsAssignableFrom(leftType) && @operator.RightType.IsAssignableFrom(rightType)) + { + return @operator; + } + + if (@operator.IsInterchangeable && @operator.LeftType.IsAssignableFrom(rightType) && @operator.RightType.IsAssignableFrom(leftType)) + { + return @operator; + } + } + } + + return null; } } } \ No newline at end of file diff --git a/Dust/Compiler/Binding/Tree/Expressions/BoundBinaryExpression.cs b/Dust/Compiler/Binding/Tree/Expressions/BoundBinaryExpression.cs index 5e50453..0ba0749 100644 --- a/Dust/Compiler/Binding/Tree/Expressions/BoundBinaryExpression.cs +++ b/Dust/Compiler/Binding/Tree/Expressions/BoundBinaryExpression.cs @@ -7,7 +7,7 @@ public class BoundBinaryExpression : BoundExpression public BoundExpression Left { get; } public BoundBinaryOperator Operator { get; } public BoundExpression Right { get; } - public override DustType Type => DustTypes.BestTypeFor(Left.Type, Right.Type); + public override DustType Type => Operator.ReturnType; public BoundBinaryExpression(BoundExpression left, BoundBinaryOperator @operator, BoundExpression right) { diff --git a/Dust/Compiler/Interpreter/Interpreter.cs b/Dust/Compiler/Interpreter/Interpreter.cs index 62e9c25..a8afd03 100644 --- a/Dust/Compiler/Interpreter/Interpreter.cs +++ b/Dust/Compiler/Interpreter/Interpreter.cs @@ -54,25 +54,12 @@ private DustObject EvaluateBinaryExpression(BoundBinaryExpression binaryExpressi DustObject left = EvaluateExpression(binaryExpression.Left); DustObject right = EvaluateExpression(binaryExpression.Right); - /* - * int + double -> double - * DoubleType.Add(int, double) -> double - * double + int -> double - * DoubleType.Add(double, int) -> double - * int + string -> string - * StringType.Add(int, string) -> string - * Left Right -> ReturnType - * ReturnType.(Left, Right) -> ReturnType - */ - - -/* if (binaryExpression.Right.Type == binaryExpression.Type) - { - DustObject t = left; + BoundBinaryOperator @operator = binaryExpression.Operator; - left = right; - right = t; - }*/ + if (@operator.IsInterchangeable && !left.IsAssignableFrom(@operator.LeftType)) + { + (left, right) = (right, left); + } switch (binaryExpression.Operator.Kind) { diff --git a/Dust/Compiler/SyntaxFacts.cs b/Dust/Compiler/SyntaxFacts.cs index 7ee3d2d..8d89f3c 100644 --- a/Dust/Compiler/SyntaxFacts.cs +++ b/Dust/Compiler/SyntaxFacts.cs @@ -17,8 +17,8 @@ public static bool IsNumeric(char character) public static bool IsUnaryOperator(SyntaxToken token) { - return token.IsOr(SyntaxTokenKind.Plus, SyntaxTokenKind.Minus, SyntaxTokenKind.Bang, SyntaxTokenKind.PlusPlus, SyntaxTokenKind.MinusMinus, SyntaxTokenKind.AsteriskAsterisk, - SyntaxTokenKind.SlashSlash); + return token.IsOr(SyntaxTokenKind.Plus, SyntaxTokenKind.Minus, SyntaxTokenKind.Bang, SyntaxTokenKind.PlusPlus, SyntaxTokenKind.MinusMinus, + SyntaxTokenKind.AsteriskAsterisk, SyntaxTokenKind.SlashSlash); } public static bool IsBinaryOperator(SyntaxToken token) @@ -28,13 +28,14 @@ public static bool IsBinaryOperator(SyntaxToken token) public static bool IsBinaryArithmeticOperator(SyntaxToken token) { - return token.IsOr(SyntaxTokenKind.Plus, SyntaxTokenKind.Minus, SyntaxTokenKind.Asterisk, SyntaxTokenKind.Slash, SyntaxTokenKind.AsteriskAsterisk, SyntaxTokenKind.Percent); + return token.IsOr(SyntaxTokenKind.Plus, SyntaxTokenKind.Minus, SyntaxTokenKind.Asterisk, SyntaxTokenKind.Slash, SyntaxTokenKind.AsteriskAsterisk, + SyntaxTokenKind.Percent); } public static bool IsBinaryBooleanOperator(SyntaxToken token) { - return token.IsOr(SyntaxTokenKind.EqualsEquals, SyntaxTokenKind.NotEqual, SyntaxTokenKind.AmpersandAmpersand, SyntaxTokenKind.PipePipe, SyntaxTokenKind.GreaterThan, - SyntaxTokenKind.GreaterThanEqual, SyntaxTokenKind.LessThan, SyntaxTokenKind.LessThanEqual); + return token.IsOr(SyntaxTokenKind.EqualsEquals, SyntaxTokenKind.NotEqual, SyntaxTokenKind.AmpersandAmpersand, SyntaxTokenKind.PipePipe, + SyntaxTokenKind.GreaterThan, SyntaxTokenKind.GreaterThanEqual, SyntaxTokenKind.LessThan, SyntaxTokenKind.LessThanEqual); } public static bool IsAssignmentOperator(SyntaxToken token) diff --git a/Dust/Dust.csproj b/Dust/Dust.csproj index 13671a7..e446566 100644 --- a/Dust/Dust.csproj +++ b/Dust/Dust.csproj @@ -1,6 +1,6 @@  - netstandard2.0 - 7.3 + netcoreapp3.0 + default \ No newline at end of file