From fa03f3d0a09c6102b552c434cc038205f721ef5f Mon Sep 17 00:00:00 2001 From: Piotr Fusik Date: Mon, 24 Jan 2022 10:22:32 +0100 Subject: [cleanup] Subclass CiLiteral. --- CiParser.cs | 12 ++++---- CiResolver.cs | 24 +++++++-------- CiTree.cs | 96 ++++++++++++++++++++++++++++++++++++++++++++++++----------- 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")); -- cgit v1.2.3