Adds support for strings
This commit is contained in:
parent
ca49866c66
commit
2baf2b223e
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -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();
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -163,7 +163,13 @@ namespace Upsilon.Evaluator
|
||||||
switch (e.Operator.Kind)
|
switch (e.Operator.Kind)
|
||||||
{
|
{
|
||||||
case BoundBinaryOperator.OperatorKind.Addition:
|
case BoundBinaryOperator.OperatorKind.Addition:
|
||||||
return ((Number)left) + ((Number)right);
|
if (left.Type == Type.Number)
|
||||||
|
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:
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -20,6 +20,7 @@ namespace Upsilon.Parser
|
||||||
Tilde,
|
Tilde,
|
||||||
TildeEquals,
|
TildeEquals,
|
||||||
Comma,
|
Comma,
|
||||||
|
String,
|
||||||
|
|
||||||
// key words
|
// key words
|
||||||
TrueKeyword,
|
TrueKeyword,
|
||||||
|
|
Loading…
Reference in New Issue