Adds Tables
This commit is contained in:
parent
4414534866
commit
6a396d6368
|
@ -0,0 +1,29 @@
|
|||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace Upsilon.BaseTypes
|
||||
{
|
||||
public class LuaTable : LuaType
|
||||
{
|
||||
private Dictionary<string, LuaType> _map;
|
||||
|
||||
public LuaTable()
|
||||
{
|
||||
_map = new Dictionary<string, LuaType>();
|
||||
}
|
||||
|
||||
public LuaTable(Dictionary<string, LuaType> map)
|
||||
{
|
||||
_map = map;
|
||||
}
|
||||
|
||||
|
||||
public override Type Type => Type.Table;
|
||||
public override object ToCSharpObject()
|
||||
{
|
||||
return _map.ToDictionary(x => x.Key, x => x.Value.ToCSharpObject());
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
|
@ -78,6 +78,8 @@ namespace Upsilon.Binder
|
|||
return BindVariableExpression((VariableExpressionSyntax) e);
|
||||
case SyntaxKind.FunctionCallExpression:
|
||||
return BindFunctionCallExpression((FunctionCallExpressionSyntax) e);
|
||||
case SyntaxKind.TableExpression:
|
||||
return BindTableExpression((TableExpressionSyntax) e);
|
||||
case SyntaxKind.BadExpression:
|
||||
break;
|
||||
case SyntaxKind.ScriptUnit:
|
||||
|
@ -352,5 +354,49 @@ namespace Upsilon.Binder
|
|||
return new BoundReturnStatement(expression);
|
||||
}
|
||||
|
||||
private BoundExpression BindTableExpression(TableExpressionSyntax e)
|
||||
{
|
||||
var keyType = Type.Unknown;
|
||||
var valueType = Type.Unknown;
|
||||
var currentKey = 0;
|
||||
var dictionary = new Dictionary<string, BoundExpression>();
|
||||
foreach (var expressionSyntax in e.Expressions)
|
||||
{
|
||||
if (expressionSyntax.Kind == SyntaxKind.AssignmentStatement)
|
||||
{
|
||||
var assignment = (AssignmentExpressionSyntax) expressionSyntax;
|
||||
var key = assignment.Identifier.Name;
|
||||
if (keyType == Type.Unknown)
|
||||
keyType = Type.String;
|
||||
if (dictionary.ContainsKey(key))
|
||||
{
|
||||
// TODO: Log
|
||||
continue;
|
||||
}
|
||||
var bound = BindExpression(assignment.Expression);
|
||||
if (valueType == Type.Unknown)
|
||||
valueType = bound.Type;
|
||||
dictionary.Add(key, bound);
|
||||
}
|
||||
else
|
||||
{
|
||||
var expression = (ExpressionSyntax) expressionSyntax;
|
||||
currentKey++;
|
||||
if (dictionary.ContainsKey(currentKey.ToString()))
|
||||
{
|
||||
// TODO: Log
|
||||
continue;
|
||||
}
|
||||
if (keyType == Type.Unknown)
|
||||
keyType = Type.Number;
|
||||
var bound = BindExpression(expression);
|
||||
if (valueType == Type.Unknown)
|
||||
valueType = bound.Type;
|
||||
dictionary.Add(currentKey.ToString(), bound);
|
||||
}
|
||||
}
|
||||
return new BoundTableExpression(keyType, valueType, dictionary);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,24 @@
|
|||
using System.Collections.Generic;
|
||||
using System.Collections.Immutable;
|
||||
using Upsilon.BaseTypes;
|
||||
|
||||
namespace Upsilon.Binder
|
||||
{
|
||||
public class BoundTableExpression : BoundExpression
|
||||
{
|
||||
public BoundTableExpression(Type keyType, Type valueType, Dictionary<string, BoundExpression> expressions)
|
||||
{
|
||||
KeyType = keyType;
|
||||
ValueType = valueType;
|
||||
Expressions = expressions;
|
||||
}
|
||||
|
||||
public override BoundKind Kind => BoundKind.BoundTableExpression;
|
||||
public override Type Type => Type.Table;
|
||||
|
||||
public Type KeyType { get; }
|
||||
public Type ValueType { get; }
|
||||
|
||||
public Dictionary<string, BoundExpression> Expressions { get; }
|
||||
}
|
||||
}
|
|
@ -9,6 +9,7 @@ namespace Upsilon.Binder
|
|||
BoundUnaryExpression,
|
||||
VariableExpression,
|
||||
BoundFunctionCallExpression,
|
||||
BoundTableExpression,
|
||||
|
||||
// Statements
|
||||
BoundAssignmentStatement,
|
||||
|
@ -18,6 +19,6 @@ namespace Upsilon.Binder
|
|||
BoundElseStatement,
|
||||
BoundFunctionStatement,
|
||||
BoundPromise,
|
||||
BoundReturnStatement
|
||||
BoundReturnStatement,
|
||||
}
|
||||
}
|
|
@ -68,6 +68,7 @@ namespace Upsilon.Evaluator
|
|||
case BoundKind.BoundUnaryExpression:
|
||||
case BoundKind.VariableExpression:
|
||||
case BoundKind.BoundFunctionCallExpression:
|
||||
case BoundKind.BoundTableExpression:
|
||||
_lastValue = EvaluateExpression((BoundExpression) b);
|
||||
break;
|
||||
case BoundKind.BoundAssignmentStatement:
|
||||
|
@ -135,6 +136,8 @@ namespace Upsilon.Evaluator
|
|||
return EvaluateVariableExpression((BoundVariableExpression) e);
|
||||
case BoundKind.BoundFunctionCallExpression:
|
||||
return EvaluateBoundFunctionCallExpression((BoundFunctionCallExpression) e);
|
||||
case BoundKind.BoundTableExpression:
|
||||
return EvaluateTableExpression((BoundTableExpression) e);
|
||||
default:
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
@ -287,5 +290,15 @@ namespace Upsilon.Evaluator
|
|||
HasReturned = true;
|
||||
}
|
||||
|
||||
private LuaType EvaluateTableExpression(BoundTableExpression e)
|
||||
{
|
||||
var dic = new Dictionary<string, LuaType>();
|
||||
foreach (var boundExpression in e.Expressions)
|
||||
{
|
||||
var evaluated = EvaluateExpression(boundExpression.Value);
|
||||
dic.Add(boundExpression.Key, evaluated);
|
||||
}
|
||||
return new LuaTable(dic);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,31 @@
|
|||
using System.Collections.Generic;
|
||||
using System.Collections.Immutable;
|
||||
using Upsilon.Text;
|
||||
|
||||
namespace Upsilon.Parser
|
||||
{
|
||||
public sealed class TableExpressionSyntax : ExpressionSyntax
|
||||
{
|
||||
public TableExpressionSyntax(SyntaxToken openBrace, ImmutableArray<SyntaxNode> expressions, SyntaxToken closeBrace)
|
||||
{
|
||||
Expressions = expressions;
|
||||
OpenBrace = openBrace;
|
||||
CloseBrace = closeBrace;
|
||||
Span = new TextSpan(OpenBrace.Span.Start, CloseBrace.Span.End - OpenBrace.Span.Start);
|
||||
}
|
||||
|
||||
public override SyntaxKind Kind => SyntaxKind.TableExpression;
|
||||
|
||||
public SyntaxToken OpenBrace { get; }
|
||||
public ImmutableArray<SyntaxNode> Expressions { get; }
|
||||
public SyntaxToken CloseBrace { get; }
|
||||
|
||||
public override IEnumerable<SyntaxNode> ChildNodes()
|
||||
{
|
||||
yield return OpenBrace;
|
||||
foreach (var e in Expressions)
|
||||
yield return e;
|
||||
yield return CloseBrace;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -22,25 +22,8 @@ namespace Upsilon.Parser
|
|||
return lexer.Lex();
|
||||
}
|
||||
|
||||
private char Current
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_position >= _text.Length)
|
||||
return '\0';
|
||||
return _text[_position];
|
||||
}
|
||||
}
|
||||
|
||||
private char Next
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_position + 1 >= _text.Length)
|
||||
return '\0';
|
||||
return _text[_position + 1];
|
||||
}
|
||||
}
|
||||
private char Current => _position >= _text.Length ? '\0' : _text[_position];
|
||||
private char Next => _position + 1 >= _text.Length ? '\0' : _text[_position + 1];
|
||||
|
||||
|
||||
private ImmutableArray<SyntaxToken> Lex()
|
||||
|
@ -82,6 +65,10 @@ namespace Upsilon.Parser
|
|||
return new SyntaxToken(SyntaxKind.OpenParenthesis, _position, "(", null);
|
||||
case ')':
|
||||
return new SyntaxToken(SyntaxKind.CloseParenthesis, _position, ")", null);
|
||||
case '{':
|
||||
return new SyntaxToken(SyntaxKind.OpenBrace, _position, "{", null);
|
||||
case '}':
|
||||
return new SyntaxToken(SyntaxKind.CloseBrace, _position, "}", null);
|
||||
case ',':
|
||||
return new SyntaxToken(SyntaxKind.Comma, _position, ",", null);
|
||||
case '"':
|
||||
|
|
|
@ -230,6 +230,8 @@ namespace Upsilon.Parser
|
|||
return ParseFunctionCallExpression();
|
||||
var token = MatchToken(SyntaxKind.Identifier);
|
||||
return new VariableExpressionSyntax((IdentifierToken) token);
|
||||
case SyntaxKind.OpenBrace:
|
||||
return ParseTable();
|
||||
case SyntaxKind.NilKeyword:
|
||||
var nilToken = MatchToken(SyntaxKind.NilKeyword);
|
||||
return new LiteralExpressionSyntax(nilToken, null);
|
||||
|
@ -284,5 +286,25 @@ namespace Upsilon.Parser
|
|||
var stringToken = MatchToken(SyntaxKind.String);
|
||||
return new LiteralExpressionSyntax(stringToken, stringToken.Value);
|
||||
}
|
||||
|
||||
private ExpressionSyntax ParseTable()
|
||||
{
|
||||
var openBrace = MatchToken(SyntaxKind.OpenBrace);
|
||||
var arrBuilder = ImmutableArray.CreateBuilder<SyntaxNode>();
|
||||
bool lastCommaFound = true;
|
||||
while (Current.Kind != SyntaxKind.CloseBrace)
|
||||
{
|
||||
if (!lastCommaFound)
|
||||
break;
|
||||
var parsed = ParseExpression();
|
||||
arrBuilder.Add(parsed);
|
||||
lastCommaFound = Current.Kind == SyntaxKind.Comma;
|
||||
if (lastCommaFound) NextToken();
|
||||
|
||||
}
|
||||
|
||||
var closeBrace = MatchToken(SyntaxKind.CloseBrace);
|
||||
return new TableExpressionSyntax(openBrace, arrBuilder.ToImmutable(), closeBrace);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -21,6 +21,8 @@ namespace Upsilon.Parser
|
|||
TildeEquals,
|
||||
Comma,
|
||||
String,
|
||||
OpenBrace,
|
||||
CloseBrace,
|
||||
|
||||
// key words
|
||||
TrueKeyword,
|
||||
|
@ -49,6 +51,7 @@ namespace Upsilon.Parser
|
|||
VariableExpression,
|
||||
FunctionCallExpression,
|
||||
BadExpression,
|
||||
TableExpression,
|
||||
|
||||
// script unit
|
||||
ScriptUnit,
|
||||
|
@ -60,6 +63,6 @@ namespace Upsilon.Parser
|
|||
ElseIfStatement,
|
||||
ElseStatement,
|
||||
FunctionStatement,
|
||||
ReturnStatement
|
||||
ReturnStatement,
|
||||
}
|
||||
}
|
|
@ -1,4 +1,6 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using Upsilon;
|
||||
using Upsilon.Evaluator;
|
||||
|
||||
|
@ -46,7 +48,8 @@ namespace Ycicle
|
|||
if (evaluate == null)
|
||||
continue;
|
||||
Console.ForegroundColor = ConsoleColor.Cyan;
|
||||
Console.WriteLine(evaluate);
|
||||
|
||||
Console.WriteLine(ParseEvaluated(evaluate));
|
||||
Console.ResetColor();
|
||||
}
|
||||
}
|
||||
|
@ -68,5 +71,34 @@ namespace Ycicle
|
|||
Console.Write(message.LineAfterError());
|
||||
Console.WriteLine();
|
||||
}
|
||||
|
||||
private static string ParseEvaluated(object o, int jumps = 0)
|
||||
{
|
||||
var sb = new StringBuilder();
|
||||
if (o is Dictionary<string, object> dic)
|
||||
{
|
||||
for (var i = 0; i < jumps; i++) sb.Append(" ");
|
||||
sb.Append("{\n");
|
||||
foreach (var (key, value) in dic)
|
||||
{
|
||||
for (var i = 0; i < jumps; i++) sb.Append(" ");
|
||||
sb.Append(" {");
|
||||
sb.Append("\"");
|
||||
sb.Append(key);
|
||||
sb.Append("\": ");
|
||||
sb.Append(ParseEvaluated(value, jumps + 1));
|
||||
sb.Append(" }");
|
||||
sb.Append(",\n");
|
||||
}
|
||||
for (var i = 0; i < jumps; i++) sb.Append(" ");
|
||||
sb.Append("}\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
sb.Append(o.ToString());
|
||||
}
|
||||
|
||||
return sb.ToString();
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue