diff --git a/NewSource/SocordiaC/Compilation/Listeners/Body/BinaryOperatorListener.cs b/NewSource/SocordiaC/Compilation/Listeners/Body/BinaryOperatorListener.cs index 17d8ebce..8e5f5272 100644 --- a/NewSource/SocordiaC/Compilation/Listeners/Body/BinaryOperatorListener.cs +++ b/NewSource/SocordiaC/Compilation/Listeners/Body/BinaryOperatorListener.cs @@ -14,10 +14,6 @@ protected override void ListenToNode(BodyCompilation context, BinaryOperatorExpr { EmitAssignment(context, node); } - else if (node.Operator is "<->") - { - EmitSwap(context, node); - } } private void EmitAssignment(BodyCompilation context, BinaryOperatorExpression node) @@ -37,38 +33,5 @@ private void EmitAssignment(BodyCompilation context, BinaryOperatorExpression no } } - private void EmitSwap(BodyCompilation context, BinaryOperatorExpression node) - { - //ToDo: test swap operator - var lvalue = context.Scope.GetFromNode(node.Left); - var rvalue = context.Scope.GetFromNode(node.Right); - - if (lvalue is ScopeItem { IsMutable: false } si) - { - node.Left.AddError("Variable '" + si.Name + "' is not mutable"); - return; - } - - if (rvalue is ScopeItem { IsMutable: false } si2) - { - node.Right.AddError("Variable '" + si2.Name + "' is not mutable"); - return; - } - - //ToDo: add check if types are compatible - - //todo: generalize to allow swapping of fields and parameters too - if (lvalue is VariableScopeItem vsi && rvalue is VariableScopeItem vsi2) - { - var temp = context.Builder.Method.CreateVar(vsi.Type); - context.Builder.CreateStore(temp, vsi.Slot); - context.Builder.CreateStore(vsi.Slot, vsi2.Slot); - context.Builder.CreateStore(vsi2.Slot, temp); - } - } - - protected override bool ShouldListenToChildren(BodyCompilation context, BinaryOperatorExpression node) - { - return false; - } + protected override bool ShouldListenToChildren(BodyCompilation context, BinaryOperatorExpression node) => false; } diff --git a/NewSource/SocordiaC/Compilation/Listeners/Body/Lowering/AssignmentsLowerer.cs b/NewSource/SocordiaC/Compilation/Listeners/Body/Lowering/AssignmentsLowerer.cs index e406edcb..72502a5d 100644 --- a/NewSource/SocordiaC/Compilation/Listeners/Body/Lowering/AssignmentsLowerer.cs +++ b/NewSource/SocordiaC/Compilation/Listeners/Body/Lowering/AssignmentsLowerer.cs @@ -23,4 +23,4 @@ public class AssignmentsLowerer : Replacer new BinaryOperatorExpression(newOperator, node.Left, node.Right) ); } -} \ No newline at end of file +} diff --git a/NewSource/SocordiaC/Compilation/Listeners/Body/Lowering/Lowerer.cs b/NewSource/SocordiaC/Compilation/Listeners/Body/Lowering/Lowerer.cs index 1e9fb21e..d318b6f3 100644 --- a/NewSource/SocordiaC/Compilation/Listeners/Body/Lowering/Lowerer.cs +++ b/NewSource/SocordiaC/Compilation/Listeners/Body/Lowering/Lowerer.cs @@ -8,5 +8,9 @@ public static class Lowerer public static readonly Pipeline Pipeline = Pipeline .Build( - builder => { builder.AddStage(); }); + builder => + { + builder.AddStage(); + builder.AddStage(); + }); } \ No newline at end of file diff --git a/NewSource/SocordiaC/Compilation/Listeners/Body/Lowering/SwapLowerer.cs b/NewSource/SocordiaC/Compilation/Listeners/Body/Lowering/SwapLowerer.cs new file mode 100644 index 00000000..7d557f66 --- /dev/null +++ b/NewSource/SocordiaC/Compilation/Listeners/Body/Lowering/SwapLowerer.cs @@ -0,0 +1,22 @@ +using MrKWatkins.Ast.Processing; +using Socordia.CodeAnalysis.AST; +using Socordia.CodeAnalysis.AST.Expressions; + +namespace SocordiaC.Compilation.Listeners.Body.Lowering; + +public class SwapLowerer : Replacer +{ + protected override AstNode? ReplaceNode(BinaryOperatorExpression node) + { + if (node.Operator != "<->") return node; + + //todo: implement a swap by introducting a new temp variable and test it + var tmpName = Utils.GenerateIdentifier(); + var tmp = new VariableStatement(tmpName, node.Left.Type, node.Left, false); + + var left = new BinaryOperatorExpression("=", node.Left, node.Right); + var right = new BinaryOperatorExpression("=", node.Right, new Identifier(tmpName)); + + return new Block([tmp, left, right]); + } +} \ No newline at end of file diff --git a/NewSource/SocordiaC/Compilation/Utils.cs b/NewSource/SocordiaC/Compilation/Utils.cs index f1b4f929..ef3d72d1 100644 --- a/NewSource/SocordiaC/Compilation/Utils.cs +++ b/NewSource/SocordiaC/Compilation/Utils.cs @@ -163,4 +163,20 @@ public static void EmitAnnotations(Declaration declaration, ModuleEntity entity) { foreach (var annotation in declaration.Annotations) EmitAnnotation(annotation, entity); } + + public static string GenerateIdentifier() + { + var sb = new StringBuilder(); + sb.Append("_"); + + const string ALPHABET = "abcdefhijklmnopqrstABCDEFGHIJKLMNOPQRSTUVWXYZ&%$"; + var random = new Random(); + + for (var i = 0; i < random.Next(5, 9); i++) + { + sb.Append(ALPHABET[random.Next(ALPHABET.Length)]); + } + + return sb.ToString(); + } } \ No newline at end of file diff --git a/Source/Backlang.Driver/Utils.cs b/Source/Backlang.Driver/Utils.cs index 98a5a595..aa880293 100644 --- a/Source/Backlang.Driver/Utils.cs +++ b/Source/Backlang.Driver/Utils.cs @@ -6,19 +6,7 @@ namespace Backlang.Driver; public static class Utils { - public static string GenerateIdentifier() - { - var sb = new StringBuilder(); - const string ALPHABET = "abcdefhijklmnopqrstABCDEFGHIJKLMNOPQRSTUVWXYZ&%$"; - var random = new Random(); - - for (var i = 0; i < random.Next(5, 9); i++) - { - sb.Append(ALPHABET[random.Next(ALPHABET.Length)]); - } - - return sb.ToString(); - } + public static void AddCompilerGeneratedAttribute(TypeResolver binder, DescribedType type) {