summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPiotr Fusik <fox@scene.pl>2022-01-24 10:22:32 +0100
committerPiotr Fusik <fox@scene.pl>2022-01-24 10:22:32 +0100
commitfa03f3d0a09c6102b552c434cc038205f721ef5f (patch)
tree5ea5d0ddcb1add133c3828c91ce6f8928f60c69f
parentb7cafa37060cd816bed8edfe67602680fd81d85e (diff)
[cleanup] Subclass CiLiteral.
-rw-r--r--CiParser.cs12
-rw-r--r--CiResolver.cs24
-rw-r--r--CiTree.cs96
3 files changed, 96 insertions, 36 deletions
diff --git a/CiParser.cs b/CiParser.cs
index 6837759..18fd24d 100644
--- a/CiParser.cs
+++ b/CiParser.cs
@@ -151,27 +151,27 @@ public class CiParser : CiLexer
case CiToken.New:
return new CiPrefixExpr { Line = this.Line, Op = NextToken(), Inner = ParseType() };
case CiToken.LiteralLong:
- result = new CiLiteral(this.LongValue) { Line = this.Line };
+ result = new CiLiteralLong(this.LongValue) { Line = this.Line };
NextToken();
break;
case CiToken.LiteralDouble:
- result = new CiLiteral(this.DoubleValue) { Line = this.Line };
+ result = new CiLiteralDouble(this.DoubleValue) { Line = this.Line };
NextToken();
break;
case CiToken.LiteralString:
- result = new CiLiteral(this.StringValue) { Line = this.Line };
+ result = new CiLiteralString(this.StringValue) { Line = this.Line };
NextToken();
break;
case CiToken.False:
- result = new CiLiteral(false) { Line = this.Line };
+ result = new CiLiteralFalse { Line = this.Line };
NextToken();
break;
case CiToken.True:
- result = new CiLiteral(true) { Line = this.Line };
+ result = new CiLiteralTrue { Line = this.Line };
NextToken();
break;
case CiToken.Null:
- result = new CiLiteral(null) { Line = this.Line };
+ result = new CiLiteralNull { Line = this.Line };
NextToken();
break;
case CiToken.InterpolatedString:
diff --git a/CiResolver.cs b/CiResolver.cs
index df9da3c..226078a 100644
--- a/CiResolver.cs
+++ b/CiResolver.cs
@@ -352,7 +352,7 @@ public class CiResolver : CiVisitor
}
sb.Append(expr.Suffix);
if (parts.Count == 0)
- return expr.ToLiteral(sb.ToString());
+ return expr.ToLiteralString(sb.ToString());
expr.Parts = parts.ToArray();
expr.Suffix = sb.ToString();
return expr;
@@ -396,13 +396,13 @@ public class CiResolver : CiVisitor
return result;
if (expr.Symbol == CiSystem.ArrayLength) {
if (scope is CiArrayStorageType array)
- return expr.ToLiteral((long) array.Length);
+ return expr.ToLiteralLong(array.Length);
throw new NotImplementedException(scope.GetType().Name);
}
if (expr.Symbol == CiSystem.StringLength && left is CiLiteral leftLiteral) {
string s = (string) leftLiteral.Value;
if (IsAscii(s))
- return expr.ToLiteral((long) s.Length);
+ return expr.ToLiteralLong(s.Length);
}
}
return new CiSymbolReference { Line = expr.Line, Left = left, Name = expr.Name, Symbol = expr.Symbol, Type = expr.Type };
@@ -473,7 +473,7 @@ public class CiResolver : CiVisitor
if (range != null)
type = range = new CiRangeType(SaturatedNeg(range.Max), SaturatedNeg(range.Min));
else if (inner is CiLiteral literal)
- return expr.ToLiteral(literal.Value is double d ? -d : -(long) literal.Value);
+ return literal.Value is double d ? expr.ToLiteralDouble(-d) : expr.ToLiteralLong(-(long) literal.Value);
else
type = inner.Type;
break;
@@ -526,7 +526,7 @@ public class CiResolver : CiVisitor
throw new NotImplementedException(expr.Op.ToString());
}
if (range != null && range.Min == range.Max)
- return expr.ToLiteral((long) range.Min);
+ return expr.ToLiteralLong(range.Min);
return new CiPrefixExpr { Line = expr.Line, Op = expr.Op, Inner = inner, Type = type };
}
@@ -575,15 +575,15 @@ public class CiResolver : CiVisitor
{
if (left.Type is CiRangeType leftRange && right.Type is CiRangeType rightRange) {
if (leftRange.Min == leftRange.Max && leftRange.Min == rightRange.Min && leftRange.Min == rightRange.Max)
- return expr.ToLiteral(expr.Op == CiToken.Equal);
+ return expr.ToLiteralBool(expr.Op == CiToken.Equal);
if (leftRange.Max < rightRange.Min || leftRange.Min > rightRange.Max)
- return expr.ToLiteral(expr.Op == CiToken.NotEqual);;
+ return expr.ToLiteralBool(expr.Op == CiToken.NotEqual);
}
else if (left.Type == right.Type) {
if (left is CiLiteral leftLiteral && right is CiLiteral rightLiteral)
- return expr.ToLiteral((expr.Op == CiToken.NotEqual) ^ object.Equals(leftLiteral.Value, rightLiteral.Value));
+ return expr.ToLiteralBool((expr.Op == CiToken.NotEqual) ^ object.Equals(leftLiteral.Value, rightLiteral.Value));
if (left.IsConstEnum && right.IsConstEnum)
- return expr.ToLiteral((expr.Op == CiToken.NotEqual) ^ (left.IntValue == right.IntValue));
+ return expr.ToLiteralBool((expr.Op == CiToken.NotEqual) ^ (left.IntValue == right.IntValue));
}
if (!left.Type.IsAssignableFrom(right.Type) && !right.Type.IsAssignableFrom(left.Type))
throw StatementException(expr, "Cannot compare {0} with {1}", left.Type, right.Type);
@@ -625,7 +625,7 @@ public class CiResolver : CiVisitor
if (IsAscii(s)) {
long i = (long) rightLiteral.Value;
if (i >= 0 && i < s.Length)
- return expr.ToLiteral((long) s[(int) i]);
+ return expr.ToLiteralLong(s[(int) i]);
}
}
break;
@@ -645,7 +645,7 @@ public class CiResolver : CiVisitor
Coerce(left, CiSystem.PrintableType);
Coerce(right, CiSystem.PrintableType);
if (left is CiLiteral leftLiteral && right is CiLiteral rightLiteral)
- return expr.ToLiteral(Convert.ToString(leftLiteral.Value, CultureInfo.InvariantCulture)
+ return expr.ToLiteralString(Convert.ToString(leftLiteral.Value, CultureInfo.InvariantCulture)
+ Convert.ToString(rightLiteral.Value, CultureInfo.InvariantCulture));
if (left is CiInterpolatedString || right is CiInterpolatedString)
return Concatenate(ToInterpolatedString(left), ToInterpolatedString(right));
@@ -896,7 +896,7 @@ public class CiResolver : CiVisitor
throw new NotImplementedException(expr.Op.ToString());
}
if (type is CiRangeType range && range.Min == range.Max)
- return expr.ToLiteral((long) range.Min);
+ return expr.ToLiteralLong(range.Min);
return new CiBinaryExpr { Line = expr.Line, Left = left, Op = expr.Op, Right = right, Type = type };
}
diff --git a/CiTree.cs b/CiTree.cs
index 6204bba..8201152 100644
--- a/CiTree.cs
+++ b/CiTree.cs
@@ -112,7 +112,10 @@ public abstract class CiExpr : CiStatement
public virtual int IntValue => throw new NotImplementedException(GetType().Name);
public virtual CiExpr Accept(CiVisitor visitor, CiPriority parent) => throw new NotImplementedException(GetType().Name);
public override void Accept(CiVisitor visitor) { visitor.Visit(this); }
- public CiLiteral ToLiteral(object value) => new CiLiteral(value) { Line = this.Line };
+ public CiLiteral ToLiteralBool(bool value) => value ? new CiLiteralTrue { Line = this.Line } : new CiLiteralFalse { Line = this.Line };
+ public CiLiteral ToLiteralLong(long value) => new CiLiteralLong(value) { Line = this.Line };
+ public CiLiteral ToLiteralDouble(double value) => new CiLiteralDouble(value) { Line = this.Line };
+ public CiLiteral ToLiteralString(string value) => new CiLiteralString(value) { Line = this.Line };
public virtual bool IsReferenceTo(CiSymbol symbol) => false;
}
@@ -255,7 +258,7 @@ public abstract class CiNamedValue : CiSymbol
{
public CiExpr TypeExpr;
public CiExpr Value;
- public bool IsAssignableStorage => this.Type is CiClass && this.Value is CiLiteral literal && literal.Value == null;
+ public bool IsAssignableStorage => this.Type is CiClass && this.Value is CiLiteralNull;
}
public class CiMember : CiNamedValue
@@ -285,22 +288,29 @@ public class CiConst : CiMember
public CiConst()
{
}
- public CiConst(string name, object value)
+ public CiConst(string name, int value)
{
this.Name = name;
- this.Value = new CiLiteral(value);
+ this.Value = new CiLiteralLong(value);
this.Type = this.Value.Type;
this.VisitStatus = CiVisitStatus.Done;
}
+ public CiConst(string name, double value)
+ {
+ this.Name = name;
+ this.Value = new CiLiteralDouble(value);
+ this.Type = CiSystem.DoubleType;
+ this.VisitStatus = CiVisitStatus.Done;
+ }
public override void Accept(CiVisitor visitor) { visitor.Visit(this); }
public override bool IsStatic => true;
}
-public class CiLiteral : CiExpr
+public abstract class CiLiteral : CiExpr
{
public readonly object Value;
- public CiLiteral(object value)
+ protected CiLiteral(object value)
{
switch (value) {
case null:
@@ -327,9 +337,6 @@ public class CiLiteral : CiExpr
this.Value = value;
}
- public override bool IsLiteralZero => (long) this.Value == 0;
- public override int IntValue => (int) (long) this.Value;
-
public bool IsDefaultValue
{
get
@@ -351,10 +358,63 @@ public class CiLiteral : CiExpr
}
}
- public static readonly CiLiteral False = new CiLiteral(false);
- public static readonly CiLiteral True = new CiLiteral(true);
+ public static readonly CiLiteralFalse False = new CiLiteralFalse();
+ public static readonly CiLiteralTrue True = new CiLiteralTrue();
public override CiExpr Accept(CiVisitor visitor, CiPriority parent) => visitor.Visit(this, parent);
- public override string ToString() => this.Value == null ? "null" : this.Value.ToString();
+ public override string ToString() => this.Value.ToString();
+}
+
+public class CiLiteralLong : CiLiteral
+{
+ public override bool IsLiteralZero => (long) this.Value == 0;
+ public override int IntValue => (int) (long) this.Value;
+
+ public CiLiteralLong(long value) : base(value)
+ {
+ }
+}
+
+public class CiLiteralDouble : CiLiteral
+{
+ public CiLiteralDouble(double value) : base(value)
+ {
+ }
+}
+
+public class CiLiteralString : CiLiteral
+{
+ public CiLiteralString(string value) : base(value)
+ {
+ }
+}
+
+public class CiLiteralNull : CiLiteral
+{
+ public CiLiteralNull() : base(null)
+ {
+ }
+ public override string ToString() => "null";
+}
+
+public abstract class CiLiteralBool : CiLiteral
+{
+ protected CiLiteralBool(bool value) : base(value)
+ {
+ }
+}
+
+public class CiLiteralFalse : CiLiteralBool
+{
+ public CiLiteralFalse() : base(false)
+ {
+ }
+}
+
+public class CiLiteralTrue : CiLiteralBool
+{
+ public CiLiteralTrue() : base(true)
+ {
+ }
}
public class CiImplicitEnumValue : CiExpr
@@ -1455,7 +1515,7 @@ public class CiSystem : CiScope
public static readonly CiMethod StringIndexOf = new CiMethod(CiCallType.Normal, Minus1Type, "IndexOf", new CiVar(StringPtrType, "value"));
public static readonly CiMethod StringLastIndexOf = new CiMethod(CiCallType.Normal, Minus1Type, "LastIndexOf", new CiVar(StringPtrType, "value"));
public static readonly CiMethod StringStartsWith = new CiMethod(CiCallType.Normal, BoolType, "StartsWith", new CiVar(StringPtrType, "value"));
- public static readonly CiMethod StringSubstring = new CiMethod(CiCallType.Normal, StringStorageType, "Substring", new CiVar(IntType, "offset"), new CiVar(IntType, "length") { Value = new CiLiteral(-1L) } ); // TODO: UIntType
+ public static readonly CiMethod StringSubstring = new CiMethod(CiCallType.Normal, StringStorageType, "Substring", new CiVar(IntType, "offset"), new CiVar(IntType, "length") { Value = new CiLiteralLong(-1L) } ); // TODO: UIntType
public static readonly CiMember ArrayLength = new CiMember { Name = "Length", Type = UIntType };
public static readonly CiMember CollectionCount = new CiMember { Name = "Count", Type = UIntType };
public static readonly CiMethod CollectionClear = new CiMethod(CiCallType.Normal, VoidType, "Clear") { IsMutator = true };
@@ -1466,7 +1526,7 @@ public class CiSystem : CiScope
public static readonly CiMethod ListRemoveRange = new CiMethod(CiCallType.Normal, VoidType, "RemoveRange", new CiVar(IntType, "index"), new CiVar(IntType, "count")) { IsMutator = true };
public static readonly CiType PrintableType = new CiPrintableType { Name = "printable" };
public static readonly CiMethod ConsoleWrite = new CiMethod(CiCallType.Static, VoidType, "Write", new CiVar(PrintableType, "value"));
- public static readonly CiMethod ConsoleWriteLine = new CiMethod(CiCallType.Static, VoidType, "WriteLine", new CiVar(PrintableType, "value") { Value = new CiLiteral("") });
+ public static readonly CiMethod ConsoleWriteLine = new CiMethod(CiCallType.Static, VoidType, "WriteLine", new CiVar(PrintableType, "value") { Value = new CiLiteralString("") });
public static readonly CiClass ConsoleBase = new CiClass(CiCallType.Static, "ConsoleBase",
ConsoleWrite,
ConsoleWriteLine);
@@ -1484,10 +1544,10 @@ public class CiSystem : CiScope
public static readonly CiClass EncodingClass = new CiClass(CiCallType.Static, "Encoding");
public static readonly CiMethod EnvironmentGetEnvironmentVariable = new CiMethod(CiCallType.Static, StringPtrType, "GetEnvironmentVariable", new CiVar(StringPtrType, "name"));
public static readonly CiClass EnvironmentClass = new CiClass(CiCallType.Static, "Environment", EnvironmentGetEnvironmentVariable);
- public static readonly CiConst RegexOptionsNone = new CiConst("None", 0L);
- public static readonly CiConst RegexOptionsIgnoreCase = new CiConst("IgnoreCase", 1L);
- public static readonly CiConst RegexOptionsMultiline = new CiConst("Multiline", 2L);
- public static readonly CiConst RegexOptionsSingleline = new CiConst("Singleline", 16L);
+ public static readonly CiConst RegexOptionsNone = new CiConst("None", 0);
+ public static readonly CiConst RegexOptionsIgnoreCase = new CiConst("IgnoreCase", 1);
+ public static readonly CiConst RegexOptionsMultiline = new CiConst("Multiline", 2);
+ public static readonly CiConst RegexOptionsSingleline = new CiConst("Singleline", 16);
public static readonly CiEnum RegexOptionsEnum = new CiEnumFlags { Name = "RegexOptions" };
public static readonly CiMethod RegexCompile = new CiMethod(CiCallType.Static, null /* filled later to avoid cyclic reference */, "Compile", new CiVar(StringPtrType, "pattern"), new CiVar(RegexOptionsEnum, "options") { Value = RegexOptionsNone });
public static readonly CiMethod RegexEscape = new CiMethod(CiCallType.Static, StringStorageType, "Escape", new CiVar(StringPtrType, "str"));