From 27a7465961845597d373dc91c6af81f5a81a94f7 Mon Sep 17 00:00:00 2001 From: Deukhoofd Date: Wed, 28 Nov 2018 16:18:56 +0100 Subject: [PATCH] Adds basics for predefined function parameter types --- Upsilon/Binder/Binder.cs | 12 +++++- Upsilon/BoundTypes/BoundTypeHandler.cs | 42 +++++++++++++++++++ .../FunctionExpressionSyntax.cs | 4 +- Upsilon/Parser/ParameterToken.cs | 23 ++++++++++ Upsilon/Parser/Parser.cs | 30 ++++++++----- Upsilon/Parser/SyntaxKind.cs | 1 + 6 files changed, 98 insertions(+), 14 deletions(-) create mode 100644 Upsilon/BoundTypes/BoundTypeHandler.cs create mode 100644 Upsilon/Parser/ParameterToken.cs diff --git a/Upsilon/Binder/Binder.cs b/Upsilon/Binder/Binder.cs index bc20d8b..4a31e11 100644 --- a/Upsilon/Binder/Binder.cs +++ b/Upsilon/Binder/Binder.cs @@ -4,6 +4,7 @@ using System.Collections.Immutable; using System.Linq; using Upsilon.BaseTypes; using Upsilon.BaseTypes.Number; +using Upsilon.BoundTypes; using Upsilon.Parser; using Type = Upsilon.BaseTypes.Type; @@ -421,12 +422,19 @@ namespace Upsilon.Binder var parameters = ImmutableArray.CreateBuilder(); foreach (var identifierToken in e.Parameters) { - var vari = new VariableSymbol(identifierToken.Name, Type.Unknown, true); + var variable = identifierToken; + var scriptType = Type.Unknown; + if (variable.TypeName != null) + { + var type = BoundTypeHandler.GetTypeDefinition(variable.TypeName.Name); + scriptType = type.ScriptType; + } + var vari = new VariableSymbol(variable.IdentifierName.Name, scriptType, true); parameters.Add(new BoundVariableSymbol(vari, identifierToken.Span)); innerScope.DefineLocalVariable(vari); } - if (parameters.Count == 0) + if (parameters.All(x => x.Type != Type.Unknown)) { Scope = innerScope; var block = BindBlockStatement(e.Block); diff --git a/Upsilon/BoundTypes/BoundTypeHandler.cs b/Upsilon/BoundTypes/BoundTypeHandler.cs new file mode 100644 index 0000000..b16e5fe --- /dev/null +++ b/Upsilon/BoundTypes/BoundTypeHandler.cs @@ -0,0 +1,42 @@ +using System.Collections.Generic; +using Upsilon.BaseTypes; + +namespace Upsilon.BoundTypes +{ + public static class BoundTypeHandler + { + private static Dictionary _typeDefinitions = new Dictionary + { + {"string", new BoundTypeDefinition(Type.String, typeof(string))}, + { + "number", + new BoundTypeDefinition(Type.Number, + new[] {typeof(int), typeof(long), typeof(float), typeof(double)}) + }, + {"bool", new BoundTypeDefinition(Type.Boolean, typeof(bool))} + }; + + public static BoundTypeDefinition GetTypeDefinition(string key) + { + return _typeDefinitions[key.ToLowerInvariant()]; + } + } + + public class BoundTypeDefinition + { + public BoundTypeDefinition(Type scriptType, System.Type[] validInternalTypes) + { + ScriptType = scriptType; + ValidInternalTypes = validInternalTypes; + } + + public BoundTypeDefinition(Type scriptType, System.Type validInternalType) + { + ScriptType = scriptType; + ValidInternalTypes = new []{validInternalType}; + } + + public Type ScriptType { get; } + public System.Type[] ValidInternalTypes { get; } + } +} \ No newline at end of file diff --git a/Upsilon/Parser/ExpressionSyntax/FunctionExpressionSyntax.cs b/Upsilon/Parser/ExpressionSyntax/FunctionExpressionSyntax.cs index 52ecf3a..fc729eb 100644 --- a/Upsilon/Parser/ExpressionSyntax/FunctionExpressionSyntax.cs +++ b/Upsilon/Parser/ExpressionSyntax/FunctionExpressionSyntax.cs @@ -8,13 +8,13 @@ namespace Upsilon.Parser { public SyntaxToken FunctionToken { get; } public SyntaxToken OpenParenthesis { get; } - public ImmutableArray Parameters { get; } + public ImmutableArray Parameters { get; } public SyntaxToken CloseParenthesis { get; } public BlockStatementSyntax Block { get; } public SyntaxToken EndToken { get; } public FunctionExpressionSyntax(SyntaxToken functionToken, - SyntaxToken openParenthesis, ImmutableArray parameters, SyntaxToken closeParenthesis, + SyntaxToken openParenthesis, ImmutableArray parameters, SyntaxToken closeParenthesis, BlockStatementSyntax block, SyntaxToken endToken) { FunctionToken = functionToken; diff --git a/Upsilon/Parser/ParameterToken.cs b/Upsilon/Parser/ParameterToken.cs new file mode 100644 index 0000000..515e5e8 --- /dev/null +++ b/Upsilon/Parser/ParameterToken.cs @@ -0,0 +1,23 @@ +using System.Collections.Generic; + +namespace Upsilon.Parser +{ + public class ParameterToken : SyntaxNode + { + public ParameterToken(IdentifierToken typeName, IdentifierToken identifierName) + { + IdentifierName = identifierName; + TypeName = typeName; + } + + public IdentifierToken IdentifierName { get; } + public IdentifierToken TypeName { get; } + + public override SyntaxKind Kind => SyntaxKind.Parameter; + public override IEnumerable ChildNodes() + { + yield return TypeName; + yield return IdentifierName; + } + } +} \ No newline at end of file diff --git a/Upsilon/Parser/Parser.cs b/Upsilon/Parser/Parser.cs index b3bfcda..87f3882 100644 --- a/Upsilon/Parser/Parser.cs +++ b/Upsilon/Parser/Parser.cs @@ -204,7 +204,7 @@ namespace Upsilon.Parser { var functionToken = MatchToken(SyntaxKind.FunctionKeyword); var openParenthesis = MatchToken(SyntaxKind.OpenParenthesis); - var variableBuilder = ImmutableArray.CreateBuilder(); + var variableBuilder = ImmutableArray.CreateBuilder(); SyntaxToken current = null; while (Current.Kind != SyntaxKind.CloseParenthesis) { @@ -213,8 +213,16 @@ namespace Upsilon.Parser break; } current = Current; - var variableIdentifier = (IdentifierToken)MatchToken(SyntaxKind.Identifier); - variableBuilder.Add(variableIdentifier); + var firstToken = MatchToken(SyntaxKind.Identifier); + if (Current.Kind == SyntaxKind.Identifier) + { + variableBuilder.Add(new ParameterToken((IdentifierToken) firstToken, + (IdentifierToken) NextToken())); + } + else + { + variableBuilder.Add(new ParameterToken(null, (IdentifierToken) firstToken)); + } if (Current.Kind == SyntaxKind.Comma) NextToken(); } @@ -241,17 +249,19 @@ namespace Upsilon.Parser } var identifier = MatchToken(SyntaxKind.Identifier); var openParenthesis = MatchToken(SyntaxKind.OpenParenthesis); - var variableBuilder = ImmutableArray.CreateBuilder(); - IdentifierToken lastIdentifier = null; + var variableBuilder = ImmutableArray.CreateBuilder(); while (Current.Kind != SyntaxKind.CloseParenthesis || Current.Kind == SyntaxKind.EndOfFile) { - var variableIdentifier =(IdentifierToken) MatchToken(SyntaxKind.Identifier); - if (lastIdentifier == variableIdentifier) + var firstToken = MatchToken(SyntaxKind.Identifier); + if (Current.Kind == SyntaxKind.Identifier) { - break; + variableBuilder.Add(new ParameterToken((IdentifierToken) firstToken, + (IdentifierToken) NextToken())); + } + else + { + variableBuilder.Add(new ParameterToken(null, (IdentifierToken) firstToken)); } - lastIdentifier = variableIdentifier; - variableBuilder.Add( variableIdentifier); if (Current.Kind == SyntaxKind.Comma) NextToken(); } diff --git a/Upsilon/Parser/SyntaxKind.cs b/Upsilon/Parser/SyntaxKind.cs index a4dac1b..784c875 100644 --- a/Upsilon/Parser/SyntaxKind.cs +++ b/Upsilon/Parser/SyntaxKind.cs @@ -51,6 +51,7 @@ namespace Upsilon.Parser BreakKeyword, Identifier, + Parameter, // Expressions UnaryExpression,