From ac83dba77f66b71f9233df5d054b6db15b858929 Mon Sep 17 00:00:00 2001 From: Deukhoofd Date: Sun, 11 Nov 2018 20:31:55 +0100 Subject: [PATCH] Binds Variable Assignment --- Upsilon/Binder/Binder.cs | 31 +++++++++++++++++++--- Upsilon/Binder/BoundAssignmenExpression.cs | 19 +++++++++++++ Upsilon/Binder/BoundKind.cs | 3 ++- Upsilon/Diagnostics.cs | 4 +++ Upsilon/Evaluator/Evaluator.cs | 12 ++++++--- 5 files changed, 61 insertions(+), 8 deletions(-) create mode 100644 Upsilon/Binder/BoundAssignmenExpression.cs diff --git a/Upsilon/Binder/Binder.cs b/Upsilon/Binder/Binder.cs index c23f7a9..42931ad 100644 --- a/Upsilon/Binder/Binder.cs +++ b/Upsilon/Binder/Binder.cs @@ -36,7 +36,7 @@ namespace Upsilon.Binder case SyntaxKind.ParenthesizedExpression: return BindParenthesizedExpression((ParenthesizedExpressionSyntax) e); case SyntaxKind.AssignmentExpression: - break; + return BindAssignmentExpression((AssignmentExpressionSyntax) e); case SyntaxKind.VariableExpression: break; case SyntaxKind.BadExpression: @@ -101,9 +101,34 @@ namespace Upsilon.Binder return new BoundLiteralExpression(outValue, type); } - private BoundExpression BindParenthesizedExpression(ParenthesizedExpressionSyntax syntax) + private BoundExpression BindParenthesizedExpression(ParenthesizedExpressionSyntax e) { - return BindExpression(syntax.Expression); + return BindExpression(e.Expression); + } + + private BoundExpression BindAssignmentExpression(AssignmentExpressionSyntax e) + { + var name = e.Identifier.Name; + var boundExpression = BindExpression(e.Expression); + + if (!_scope.TryGetVariable(name, out var variable)) + { + variable = new VariableSymbol(name, boundExpression.Type); + if (e.LocalToken != null) + _scope.SetVariable(variable); + else + _scope.SetGlobalVariable(variable); + } + else + { + if (boundExpression.Type != variable.Type) + { + _diagnostics.LogCannotConvert(boundExpression.Type, variable.Type, e.Span); + return boundExpression; + } + } + + return new BoundAssignmenExpression(variable, boundExpression); } } } \ No newline at end of file diff --git a/Upsilon/Binder/BoundAssignmenExpression.cs b/Upsilon/Binder/BoundAssignmenExpression.cs new file mode 100644 index 0000000..3f6cf90 --- /dev/null +++ b/Upsilon/Binder/BoundAssignmenExpression.cs @@ -0,0 +1,19 @@ +using Upsilon.BaseTypes; + +namespace Upsilon.Binder +{ + public class BoundAssignmenExpression : BoundExpression + { + public BoundAssignmenExpression(VariableSymbol variable, BoundExpression expression) + { + Variable = variable; + Expression = expression; + } + + public VariableSymbol Variable { get; } + public BoundExpression Expression { get; } + + public override BoundKind Kind => BoundKind.BoundAssignmentExpression; + public override Type Type { get; } + } +} \ No newline at end of file diff --git a/Upsilon/Binder/BoundKind.cs b/Upsilon/Binder/BoundKind.cs index caf80fd..8ed7b3a 100644 --- a/Upsilon/Binder/BoundKind.cs +++ b/Upsilon/Binder/BoundKind.cs @@ -6,6 +6,7 @@ namespace Upsilon.Binder BoundLiteralExpression, BoundBinaryExpression, - BoundUnaryExpression + BoundUnaryExpression, + BoundAssignmentExpression } } \ No newline at end of file diff --git a/Upsilon/Diagnostics.cs b/Upsilon/Diagnostics.cs index 6a00fc1..8c55782 100644 --- a/Upsilon/Diagnostics.cs +++ b/Upsilon/Diagnostics.cs @@ -55,6 +55,10 @@ namespace Upsilon LogError($"No unary operator {text} found for type '{inType}'", eSpan); } + public void LogCannotConvert(Type actualType, Type expectedType, TextSpan span) + { + LogError($"Cannot convert type '{actualType}' to '{expectedType}'", span); + } } public class DiagnosticsMessage diff --git a/Upsilon/Evaluator/Evaluator.cs b/Upsilon/Evaluator/Evaluator.cs index cd5e75c..ea9abcb 100644 --- a/Upsilon/Evaluator/Evaluator.cs +++ b/Upsilon/Evaluator/Evaluator.cs @@ -1,4 +1,5 @@ using System; +using System.Collections.Generic; using Upsilon.BaseTypes.Number; using Upsilon.Binder; using Upsilon.Parser; @@ -9,6 +10,7 @@ namespace Upsilon.Evaluator { private readonly Diagnostics _diagnostics; public Script Script { get; } + private Dictionary _variables = new Dictionary(); public Evaluator(Script script, Diagnostics diagnostics) { @@ -31,6 +33,8 @@ namespace Upsilon.Evaluator return EvaluateBinaryExpression((BoundBinaryExpression) e); case BoundKind.BoundUnaryExpression: return EvaluateUnaryExpression((BoundUnaryExpression) e); + case BoundKind.BoundAssignmentExpression: + return EvaluateAssignmentExpression((BoundAssignmenExpression) e); default: throw new NotImplementedException(); } @@ -75,13 +79,13 @@ namespace Upsilon.Evaluator } } - /* - private object EvaluateAssignmentExpression(AssignmentExpressionSyntax e) + private object EvaluateAssignmentExpression(BoundAssignmenExpression e) { - var variableName = e.Identifier.Name; + var variableName = e.Variable.Name; var val = EvaluateExpression(e.Expression); + _variables[variableName] = val; return val; - }*/ + } private object EvaluateVariableExpression(VariableExpressionSyntax e) {