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
|
||||
{
|
||||
internal abstract class LuaType
|
||||
public abstract class LuaType
|
||||
{
|
||||
public abstract Type Type { get; }
|
||||
public abstract object ToCSharpObject();
|
||||
|
|
|
@ -129,9 +129,13 @@ namespace Upsilon.Binder
|
|||
case bool b:
|
||||
outValue = new LuaBoolean(b);
|
||||
break;
|
||||
case string s:
|
||||
outValue = new LuaString(s);
|
||||
break;
|
||||
case null:
|
||||
outValue = new LuaNull();
|
||||
break;
|
||||
|
||||
default:
|
||||
_diagnostics.LogUnknownType(e.Span);
|
||||
break;
|
||||
|
|
|
@ -48,6 +48,15 @@ namespace Upsilon.Binder
|
|||
// Boolean equality
|
||||
new BoundBinaryOperator(OperatorKind.Equality, 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)
|
||||
|
|
|
@ -163,7 +163,13 @@ namespace Upsilon.Evaluator
|
|||
switch (e.Operator.Kind)
|
||||
{
|
||||
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:
|
||||
return ((Number)left) - ((Number)right);
|
||||
case BoundBinaryOperator.OperatorKind.Multiplication:
|
||||
|
|
|
@ -84,6 +84,8 @@ namespace Upsilon.Parser
|
|||
return new SyntaxToken(SyntaxKind.CloseParenthesis, _position, ")", null);
|
||||
case ',':
|
||||
return new SyntaxToken(SyntaxKind.Comma, _position, ",", null);
|
||||
case '"':
|
||||
return LexString();
|
||||
case '=':
|
||||
if (Next == '=')
|
||||
{
|
||||
|
@ -135,6 +137,24 @@ namespace Upsilon.Parser
|
|||
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()
|
||||
{
|
||||
var start = _position;
|
||||
|
|
|
@ -223,6 +223,8 @@ namespace Upsilon.Parser
|
|||
case SyntaxKind.TrueKeyword:
|
||||
case SyntaxKind.FalseKeyword:
|
||||
return ParseBoolean();
|
||||
case SyntaxKind.String:
|
||||
return ParseString();
|
||||
case SyntaxKind.Identifier:
|
||||
if (Next.Kind == SyntaxKind.OpenParenthesis)
|
||||
return ParseFunctionCallExpression();
|
||||
|
@ -277,5 +279,10 @@ namespace Upsilon.Parser
|
|||
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,
|
||||
TildeEquals,
|
||||
Comma,
|
||||
String,
|
||||
|
||||
// key words
|
||||
TrueKeyword,
|
||||
|
|
Loading…
Reference in New Issue