Adds support for strings

This commit is contained in:
Deukhoofd 2018-11-17 15:57:26 +01:00
parent ca49866c66
commit 2baf2b223e
No known key found for this signature in database
GPG Key ID: B4C087AC81641654
8 changed files with 125 additions and 2 deletions

View File

@ -0,0 +1,76 @@
using System;
using Upsilon.BaseTypes.Number;
namespace Upsilon.BaseTypes
{
internal class LuaString : LuaType
{
public LuaString(string value)
{
Value = value;
}
public string Value { get; }
public override Type Type => Type.String;
public override object ToCSharpObject()
{
return Value;
}
public override bool Equals(object obj)
{
if (obj == null)
return false;
if (!(obj is LuaString s))
return false;
return Equals(s);
}
public override int GetHashCode()
{
return (Value != null ? Value.GetHashCode() : 0);
}
public bool Equals(LuaString s)
{
if (s == null) return false;
return string.Equals(s.Value, Value);
}
public static LuaString operator +(LuaString a, LuaType b)
{
switch (b)
{
case LuaString s:
return a + s;
case LuaBoolean bl:
return a + bl;
case NumberLong l:
return a + l;
case NumberDouble d:
return a + d;
}
throw new ArgumentException($"Adding Type '{b.Type}' to a LuaString is not supported.");
}
public static LuaString operator +(LuaString a, LuaString b)
{
return new LuaString(a.Value + b.Value);
}
public static LuaString operator +(LuaString a, LuaBoolean b)
{
return new LuaString(a.Value + b.Value);
}
public static LuaString operator +(LuaString a, NumberLong b)
{
return new LuaString(a.Value + b.Value);
}
public static LuaString operator +(LuaString a, NumberDouble b)
{
return new LuaString(a.Value + b.Value);
}
}
}

View File

@ -1,6 +1,6 @@
namespace Upsilon.BaseTypes namespace Upsilon.BaseTypes
{ {
internal abstract class LuaType public abstract class LuaType
{ {
public abstract Type Type { get; } public abstract Type Type { get; }
public abstract object ToCSharpObject(); public abstract object ToCSharpObject();

View File

@ -129,9 +129,13 @@ namespace Upsilon.Binder
case bool b: case bool b:
outValue = new LuaBoolean(b); outValue = new LuaBoolean(b);
break; break;
case string s:
outValue = new LuaString(s);
break;
case null: case null:
outValue = new LuaNull(); outValue = new LuaNull();
break; break;
default: default:
_diagnostics.LogUnknownType(e.Span); _diagnostics.LogUnknownType(e.Span);
break; break;

View File

@ -48,6 +48,15 @@ namespace Upsilon.Binder
// Boolean equality // Boolean equality
new BoundBinaryOperator(OperatorKind.Equality, Type.Boolean), new BoundBinaryOperator(OperatorKind.Equality, Type.Boolean),
new BoundBinaryOperator(OperatorKind.Inequality, Type.Boolean), new BoundBinaryOperator(OperatorKind.Inequality, Type.Boolean),
// String operators
new BoundBinaryOperator(OperatorKind.Addition, Type.String, Type.String, Type.String),
new BoundBinaryOperator(OperatorKind.Addition, Type.String, Type.Number, Type.String),
new BoundBinaryOperator(OperatorKind.Addition, Type.String, Type.Boolean, Type.String),
// String equality
new BoundBinaryOperator(OperatorKind.Equality, Type.String, Type.String, Type.Boolean),
new BoundBinaryOperator(OperatorKind.Inequality, Type.String, Type.String, Type.Boolean),
}; };
public static BoundBinaryOperator Bind(SyntaxKind operatorToken, Type left, Type right) public static BoundBinaryOperator Bind(SyntaxKind operatorToken, Type left, Type right)

View File

@ -163,7 +163,13 @@ namespace Upsilon.Evaluator
switch (e.Operator.Kind) switch (e.Operator.Kind)
{ {
case BoundBinaryOperator.OperatorKind.Addition: case BoundBinaryOperator.OperatorKind.Addition:
if (left.Type == Type.Number)
return ((Number)left) + ((Number)right); return ((Number)left) + ((Number)right);
else if (left.Type == Type.String)
{
return ((LuaString) left) + right;
}
goto default;
case BoundBinaryOperator.OperatorKind.Subtraction: case BoundBinaryOperator.OperatorKind.Subtraction:
return ((Number)left) - ((Number)right); return ((Number)left) - ((Number)right);
case BoundBinaryOperator.OperatorKind.Multiplication: case BoundBinaryOperator.OperatorKind.Multiplication:

View File

@ -84,6 +84,8 @@ namespace Upsilon.Parser
return new SyntaxToken(SyntaxKind.CloseParenthesis, _position, ")", null); return new SyntaxToken(SyntaxKind.CloseParenthesis, _position, ")", null);
case ',': case ',':
return new SyntaxToken(SyntaxKind.Comma, _position, ",", null); return new SyntaxToken(SyntaxKind.Comma, _position, ",", null);
case '"':
return LexString();
case '=': case '=':
if (Next == '=') if (Next == '=')
{ {
@ -135,6 +137,24 @@ namespace Upsilon.Parser
return new SyntaxToken(SyntaxKind.Number, start, numStr.ToString(), o); return new SyntaxToken(SyntaxKind.Number, start, numStr.ToString(), o);
} }
private SyntaxToken LexString()
{
var start = _position;
var sb = new StringBuilder();
while (true)
{
_position++;
if (Current == '"')
break;
sb.Append(Current);
}
_position++;
var res = sb.ToString();
return new SyntaxToken(SyntaxKind.String, start, $"\"{res}\"", res);
}
private SyntaxToken LexIdentifierOrKeyword() private SyntaxToken LexIdentifierOrKeyword()
{ {
var start = _position; var start = _position;

View File

@ -223,6 +223,8 @@ namespace Upsilon.Parser
case SyntaxKind.TrueKeyword: case SyntaxKind.TrueKeyword:
case SyntaxKind.FalseKeyword: case SyntaxKind.FalseKeyword:
return ParseBoolean(); return ParseBoolean();
case SyntaxKind.String:
return ParseString();
case SyntaxKind.Identifier: case SyntaxKind.Identifier:
if (Next.Kind == SyntaxKind.OpenParenthesis) if (Next.Kind == SyntaxKind.OpenParenthesis)
return ParseFunctionCallExpression(); return ParseFunctionCallExpression();
@ -277,5 +279,10 @@ namespace Upsilon.Parser
return new LiteralExpressionSyntax(token, isTrue); return new LiteralExpressionSyntax(token, isTrue);
} }
private ExpressionSyntax ParseString()
{
var stringToken = MatchToken(SyntaxKind.String);
return new LiteralExpressionSyntax(stringToken, stringToken.Value);
}
} }
} }

View File

@ -20,6 +20,7 @@ namespace Upsilon.Parser
Tilde, Tilde,
TildeEquals, TildeEquals,
Comma, Comma,
String,
// key words // key words
TrueKeyword, TrueKeyword,