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);
|
return BindVariableExpression((VariableExpressionSyntax) e);
|
||||||
case SyntaxKind.FunctionCallExpression:
|
case SyntaxKind.FunctionCallExpression:
|
||||||
return BindFunctionCallExpression((FunctionCallExpressionSyntax) e);
|
return BindFunctionCallExpression((FunctionCallExpressionSyntax) e);
|
||||||
|
case SyntaxKind.TableExpression:
|
||||||
|
return BindTableExpression((TableExpressionSyntax) e);
|
||||||
case SyntaxKind.BadExpression:
|
case SyntaxKind.BadExpression:
|
||||||
break;
|
break;
|
||||||
case SyntaxKind.ScriptUnit:
|
case SyntaxKind.ScriptUnit:
|
||||||
|
@ -352,5 +354,49 @@ namespace Upsilon.Binder
|
||||||
return new BoundReturnStatement(expression);
|
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,
|
BoundUnaryExpression,
|
||||||
VariableExpression,
|
VariableExpression,
|
||||||
BoundFunctionCallExpression,
|
BoundFunctionCallExpression,
|
||||||
|
BoundTableExpression,
|
||||||
|
|
||||||
// Statements
|
// Statements
|
||||||
BoundAssignmentStatement,
|
BoundAssignmentStatement,
|
||||||
|
@ -18,6 +19,6 @@ namespace Upsilon.Binder
|
||||||
BoundElseStatement,
|
BoundElseStatement,
|
||||||
BoundFunctionStatement,
|
BoundFunctionStatement,
|
||||||
BoundPromise,
|
BoundPromise,
|
||||||
BoundReturnStatement
|
BoundReturnStatement,
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -68,6 +68,7 @@ namespace Upsilon.Evaluator
|
||||||
case BoundKind.BoundUnaryExpression:
|
case BoundKind.BoundUnaryExpression:
|
||||||
case BoundKind.VariableExpression:
|
case BoundKind.VariableExpression:
|
||||||
case BoundKind.BoundFunctionCallExpression:
|
case BoundKind.BoundFunctionCallExpression:
|
||||||
|
case BoundKind.BoundTableExpression:
|
||||||
_lastValue = EvaluateExpression((BoundExpression) b);
|
_lastValue = EvaluateExpression((BoundExpression) b);
|
||||||
break;
|
break;
|
||||||
case BoundKind.BoundAssignmentStatement:
|
case BoundKind.BoundAssignmentStatement:
|
||||||
|
@ -135,6 +136,8 @@ namespace Upsilon.Evaluator
|
||||||
return EvaluateVariableExpression((BoundVariableExpression) e);
|
return EvaluateVariableExpression((BoundVariableExpression) e);
|
||||||
case BoundKind.BoundFunctionCallExpression:
|
case BoundKind.BoundFunctionCallExpression:
|
||||||
return EvaluateBoundFunctionCallExpression((BoundFunctionCallExpression) e);
|
return EvaluateBoundFunctionCallExpression((BoundFunctionCallExpression) e);
|
||||||
|
case BoundKind.BoundTableExpression:
|
||||||
|
return EvaluateTableExpression((BoundTableExpression) e);
|
||||||
default:
|
default:
|
||||||
throw new NotImplementedException();
|
throw new NotImplementedException();
|
||||||
}
|
}
|
||||||
|
@ -287,5 +290,15 @@ namespace Upsilon.Evaluator
|
||||||
HasReturned = true;
|
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();
|
return lexer.Lex();
|
||||||
}
|
}
|
||||||
|
|
||||||
private char Current
|
private char Current => _position >= _text.Length ? '\0' : _text[_position];
|
||||||
{
|
private char Next => _position + 1 >= _text.Length ? '\0' : _text[_position + 1];
|
||||||
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 ImmutableArray<SyntaxToken> Lex()
|
private ImmutableArray<SyntaxToken> Lex()
|
||||||
|
@ -82,6 +65,10 @@ namespace Upsilon.Parser
|
||||||
return new SyntaxToken(SyntaxKind.OpenParenthesis, _position, "(", null);
|
return new SyntaxToken(SyntaxKind.OpenParenthesis, _position, "(", null);
|
||||||
case ')':
|
case ')':
|
||||||
return new SyntaxToken(SyntaxKind.CloseParenthesis, _position, ")", null);
|
return new SyntaxToken(SyntaxKind.CloseParenthesis, _position, ")", null);
|
||||||
|
case '{':
|
||||||
|
return new SyntaxToken(SyntaxKind.OpenBrace, _position, "{", null);
|
||||||
|
case '}':
|
||||||
|
return new SyntaxToken(SyntaxKind.CloseBrace, _position, "}", null);
|
||||||
case ',':
|
case ',':
|
||||||
return new SyntaxToken(SyntaxKind.Comma, _position, ",", null);
|
return new SyntaxToken(SyntaxKind.Comma, _position, ",", null);
|
||||||
case '"':
|
case '"':
|
||||||
|
|
|
@ -230,6 +230,8 @@ namespace Upsilon.Parser
|
||||||
return ParseFunctionCallExpression();
|
return ParseFunctionCallExpression();
|
||||||
var token = MatchToken(SyntaxKind.Identifier);
|
var token = MatchToken(SyntaxKind.Identifier);
|
||||||
return new VariableExpressionSyntax((IdentifierToken) token);
|
return new VariableExpressionSyntax((IdentifierToken) token);
|
||||||
|
case SyntaxKind.OpenBrace:
|
||||||
|
return ParseTable();
|
||||||
case SyntaxKind.NilKeyword:
|
case SyntaxKind.NilKeyword:
|
||||||
var nilToken = MatchToken(SyntaxKind.NilKeyword);
|
var nilToken = MatchToken(SyntaxKind.NilKeyword);
|
||||||
return new LiteralExpressionSyntax(nilToken, null);
|
return new LiteralExpressionSyntax(nilToken, null);
|
||||||
|
@ -284,5 +286,25 @@ namespace Upsilon.Parser
|
||||||
var stringToken = MatchToken(SyntaxKind.String);
|
var stringToken = MatchToken(SyntaxKind.String);
|
||||||
return new LiteralExpressionSyntax(stringToken, stringToken.Value);
|
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,
|
TildeEquals,
|
||||||
Comma,
|
Comma,
|
||||||
String,
|
String,
|
||||||
|
OpenBrace,
|
||||||
|
CloseBrace,
|
||||||
|
|
||||||
// key words
|
// key words
|
||||||
TrueKeyword,
|
TrueKeyword,
|
||||||
|
@ -49,6 +51,7 @@ namespace Upsilon.Parser
|
||||||
VariableExpression,
|
VariableExpression,
|
||||||
FunctionCallExpression,
|
FunctionCallExpression,
|
||||||
BadExpression,
|
BadExpression,
|
||||||
|
TableExpression,
|
||||||
|
|
||||||
// script unit
|
// script unit
|
||||||
ScriptUnit,
|
ScriptUnit,
|
||||||
|
@ -60,6 +63,6 @@ namespace Upsilon.Parser
|
||||||
ElseIfStatement,
|
ElseIfStatement,
|
||||||
ElseStatement,
|
ElseStatement,
|
||||||
FunctionStatement,
|
FunctionStatement,
|
||||||
ReturnStatement
|
ReturnStatement,
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,4 +1,6 @@
|
||||||
using System;
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Text;
|
||||||
using Upsilon;
|
using Upsilon;
|
||||||
using Upsilon.Evaluator;
|
using Upsilon.Evaluator;
|
||||||
|
|
||||||
|
@ -46,7 +48,8 @@ namespace Ycicle
|
||||||
if (evaluate == null)
|
if (evaluate == null)
|
||||||
continue;
|
continue;
|
||||||
Console.ForegroundColor = ConsoleColor.Cyan;
|
Console.ForegroundColor = ConsoleColor.Cyan;
|
||||||
Console.WriteLine(evaluate);
|
|
||||||
|
Console.WriteLine(ParseEvaluated(evaluate));
|
||||||
Console.ResetColor();
|
Console.ResetColor();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -68,5 +71,34 @@ namespace Ycicle
|
||||||
Console.Write(message.LineAfterError());
|
Console.Write(message.LineAfterError());
|
||||||
Console.WriteLine();
|
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