using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Anonymus.Recognizers
{
public class SimpleArgRecognizer : ArgRecognizer
{
public SimpleArgRecognizer()
{
Operators = new string[] { "," };
NewLineLeft = NewLineRight = Operators;
Init();
}
public override bool SplitArgs(CompilerState State, PString Self, List<PString> Ret, bool EnableMessages = true)
{
var RetValue = true;
var Sep = (PString)null;
foreach (var e in Self.EnumSplit(",", StringSplitOptions.RemoveEmptyEntries, true, true))
{
if (e.IsSeparator)
{
if (Sep != null)
{
if (EnableMessages) State.Messages.Add(MessageId.MissingParam, Sep);
RetValue = false;
}
Sep = e.String;
}
else
{
Ret.Add(e.String);
Sep = null;
}
}
if (Sep != null)
{
if (EnableMessages) State.Messages.Add(MessageId.MissingParam, Sep);
RetValue = false;
}
return RetValue;
}
}
public abstract class MultiExprRecognizer : ExprRecognizer
{
public List<ExprRecognizer> Recognizers = new List<ExprRecognizer>();
public override void Init()
{
var AllOperators = new List<string>();
var AllNewLineLeft = new List<string>();
var AllNewLineRight = new List<string>();
var AllOnlyLeft = new List<string>();
var AllOnlyRight = new List<string>();
for (var i = 0; i < Recognizers.Count; i++)
{
var Rec = Recognizers[i];
if (Rec.Operators != null)
{
var Skip = new List<string>();
AllOperators.AddRange(Rec.Operators);
for (var j = i + 1; j < Recognizers.Count; j++)
{
var jOps = Recognizers[j].Operators;
if (jOps == null) continue;
foreach (var e in jOps)
{
foreach (var Op in Rec.Operators)
if (e.IndexOf(Op) != -1 && e != Op)
{
Skip.Add(e);
break;
}
}
}
if (Skip.Count == 0) this.Skip = null;
else Rec.Skip = Skip.ToArray();
}
if (Rec.NewLineLeft != null) AllNewLineLeft.AddRange(Rec.NewLineLeft);
if (Rec.NewLineRight != null) AllNewLineRight.AddRange(Rec.NewLineRight);
if (Rec.OnlyLeft != null) AllOnlyLeft.AddRange(Rec.OnlyLeft);
if (Rec.OnlyRight != null) AllOnlyRight.AddRange(Rec.OnlyRight);
}
Operators = ToArray(AllOperators);
NewLineLeft = ToArray(AllNewLineLeft);
NewLineRight = ToArray(AllNewLineRight);
OnlyLeft = ToArray(AllOnlyLeft);
OnlyRight = ToArray(AllOnlyRight);
}
private T[] ToArray<T>(List<T> List) where T : class
{
Helper.RemoveSameObject(List);
if (List.Count == 0) return null;
else return List.ToArray();
}
public override T GetRecognizer<T>()
{
foreach (var e in Recognizers)
if (e is T) return e as T;
return base.GetRecognizer<T>();
}
public override ExprRecognizerRes Recognize(PString Code, ExprPlugIn PlugIn, ref ExpressionNode Ret)
{
foreach (var e in Recognizers)
{
var Res = e.Recognize(Code, PlugIn, ref Ret);
if (Res != ExprRecognizerRes.UnknownOp) return Res;
}
return ExprRecognizerRes.UnknownOp;
}
}
public class LiteralRecognizer : ExprRecognizer
{
public override ExprRecognizerRes Recognize(PString Code, ExprPlugIn PlugIn, ref ExpressionNode Ret)
{
if (Expressions.IsLiteral(Code.String))
{
Ret = Expressions.GetLiteral(PlugIn, Code);
if (Ret == null) return ExprRecognizerRes.Failed;
return ExprRecognizerRes.Succeeded;
}
return ExprRecognizerRes.UnknownOp;
}
}
public class IdRecognizer : ExprRecognizer
{
public override ExprRecognizerRes Recognize(PString Code, ExprPlugIn PlugIn, ref ExpressionNode Ret)
{
if (Helper.IsValidIdentifierName(Code.String))
{
Ret = Expressions.GetId(PlugIn, Code);
if (Ret == null) return ExprRecognizerRes.Failed;
return ExprRecognizerRes.DontCallNewNode;
}
return ExprRecognizerRes.UnknownOp;
}
}
public class RefRecognizer : ExprRecognizer
{
public RefRecognizer()
{
NewLineRight = new string[] { "ref" };
Init();
}
public override ExprRecognizerRes Recognize(PString Code, ExprPlugIn PlugIn, ref ExpressionNode Ret)
{
if (Code.String.StartsWith("ref", true))
{
var SubCode = Code.TrimmedSubstring(3);
var Child = Expressions.Recognize(SubCode, PlugIn, true);
if (Child == null) return ExprRecognizerRes.Failed;
var IdChild = Child as IdExpressionNode;
if (Child.Type is TypeOfType && IdChild != null)
{
var Type = (IdChild.Id as Type).CreateRefType();
Ret = new IdExpressionNode(Type, Code);
}
else
{
var Ch = new List<ExpressionNode>() { Child };
Ret = new OpExpressionNode(Operator.Ref, Ch, Code);
}
return ExprRecognizerRes.Succeeded;
}
return ExprRecognizerRes.UnknownOp;
}
}
public class NewRecognizer : ExprRecognizer
{
public NewRecognizer()
{
NewLineRight = new string[] { "new" };
Init();
}
public override ExprRecognizerRes Recognize(PString Code, ExprPlugIn PlugIn, ref ExpressionNode Ret)
{
if (Code.String.StartsWith("new", true))
{
var State = PlugIn.State;
var Container = PlugIn.Container;
var SubCode = Code.TrimmedSubstring(3);
var Len = SubCode.StrLen;
var LChar = SubCode[Len - 1];
var Ch = new List<ExpressionNode>();
if (LChar == ']' || LChar == ')')
{
var ZPos = BracketHelper.ZPos(SubCode.String, RightToLeft: true);
if (ZPos == -1)
{
State.Messages.Add(MessageId.ZNumErr, SubCode.Substring(Len - 1));
return ExprRecognizerRes.Failed;
}
var StrParams = SubCode.TrimmedSubstring(ZPos + 1, Len - ZPos - 1);
SubCode = SubCode.TrimmedSubstring(0, ZPos);
var Params = Expressions.CreateParamNodes(PlugIn, Code, null, StrParams);
if (Params == null) return ExprRecognizerRes.Failed;
Ch.AddRange(Params);
}
var Type = Container.GetId<Type>(SubCode);
if (Type == null) return ExprRecognizerRes.Failed;
Type = Type.RealType;
if (!(Type is StructuredType))
{
State.Messages.Add(MessageId.CantOpApplied, Code, Type.Name.String);
return ExprRecognizerRes.Failed;
}
var Structured = Type as StructuredType;
var Id = Structured.Constructor;
if (Id != null)
{
var IdNode = PlugIn.NewNode(new IdExpressionNode(Id, Code));
if (IdNode == null) return ExprRecognizerRes.Failed;
Ch.Insert(0, IdNode);
}
Ret = new OpExpressionNode(Operator.New, Ch, Code);
Ret.Type = Type;
return ExprRecognizerRes.Succeeded;
}
return ExprRecognizerRes.UnknownOp;
}
}
public class IfThenRecognizer : ExprRecognizer
{
public IfThenRecognizer()
{
NewLineRight = new string[] { "if", "then", "else" };
Init();
}
public override ExprRecognizerRes Recognize(PString Code, ExprPlugIn PlugIn, ref ExpressionNode Ret)
{
if (Code.String.StartsWith("if", true))
{
var State = PlugIn.State;
var Container = PlugIn.Container;
FindRes Result;
var SubCode = Code.Substring(2);
if (SubCode == null || (Result = SubCode.String.Find(new string[] { "then" }, InZ: true, NotIdChar: true)).Position == -1)
{
State.Messages.Add(MessageId.NeedThenElse, Code);
return ExprRecognizerRes.Failed;
}
var ConditionStr = SubCode.TrimmedSubstring(0, Result.Position);
SubCode = SubCode.Substring(Result.Position + Result.String.Length);
if (SubCode == null || (Result = SubCode.String.Find(new string[] { "else" },
InZ: true, NotIdChar: true)).Position == -1)
{
State.Messages.Add(MessageId.NeedThenElse, Code);
return ExprRecognizerRes.Failed;
}
var ThenStr = SubCode.TrimmedSubstring(0, Result.Position);
var ElseStr = SubCode.TrimmedSubstring(Result.Position + Result.String.Length);
if (ThenStr == null || ElseStr == null || ConditionStr == null ||
ThenStr.String == "" || ElseStr.String == null || ConditionStr.String == "")
{
State.Messages.Add(MessageId.DeficientExpr, Code);
return ExprRecognizerRes.Failed;
}
var Condition = Expressions.Recognize(ConditionStr, PlugIn, true);
var Then = Expressions.Recognize(ThenStr, PlugIn, true);
var Else = Expressions.Recognize(ElseStr, PlugIn, true);
if (Condition == null || Then == null || Else == null)
return ExprRecognizerRes.Failed;
var Ch = new List<ExpressionNode>() { Condition, Then, Else };
Ret = new OpExpressionNode(Operator.Condition, Ch, Code);
return ExprRecognizerRes.Succeeded;
}
return ExprRecognizerRes.UnknownOp;
}
}
public class AssignmentRecognizer : ExprRecognizer
{
public AssignmentRecognizer()
{
Operators = new string[] { "+=", "-=", "*=", "/=", "%=", "<<=", ">>=", "|=", "&=", "^=", "=" };
NewLineLeft = NewLineRight = Operators;
Init();
}
public override ExprRecognizerRes Recognize(PString Code, ExprPlugIn PlugIn, ref ExpressionNode Ret)
{
var Result = Code.String.Find(Operators, InZ: true, Skip: Skip);
if (Result.Position != -1)
{
var Ch = Expressions.TwoParamOpNode(Code, Result, PlugIn);
if (Ch == null) return ExprRecognizerRes.Failed;
var Op = Operator.Nothing;
switch (Result.Index)
{
case 0: Op = Operator.Add; break;
case 1: Op = Operator.Subract; break;
case 2: Op = Operator.Multiply; break;
case 3: Op = Operator.Divide; break;
case 4: Op = Operator.Modolus; break;
case 5: Op = Operator.ShiftLeft; break;
case 6: Op = Operator.ShiftRight; break;
case 7: Op = Operator.Or; break;
case 8: Op = Operator.And; break;
case 9: Op = Operator.Xor; break;
case 10:
Ret = new OpExpressionNode(Operator.Assignment, Ch, Code);
break;
default:
throw new Exception("ERROR");
}
if (Op != Operator.Nothing)
{
var RId = Ch[0];
Ret = PlugIn.NewNode(new OpExpressionNode(Op, Ch, Code));
if (Ret == null) return ExprRecognizerRes.Failed;
Ch = new List<ExpressionNode>() { RId, Ret };
Ret = new OpExpressionNode(Operator.Assignment, Ch, Code);
}
return ExprRecognizerRes.Succeeded;
}
return ExprRecognizerRes.UnknownOp;
}
}
public class TupleCreatingRecognizer : ExprRecognizer
{
public TupleCreatingRecognizer()
{
Operators = new string[] { "{" };
NewLineRight = Operators;
}
public override ExprRecognizerRes Recognize(PString Code, ExprPlugIn PlugIn, ref ExpressionNode Ret)
{
if (Code.String.Find(',', InZ: true, Back: true) != -1)
{
var Members = Expressions.CreateParamNodes(PlugIn, Code, null, Code);
if (Members == null) return ExprRecognizerRes.Failed;
Ret = new OpExpressionNode(Operator.CreateTuple, Members, Code);
return ExprRecognizerRes.Succeeded;
}
return ExprRecognizerRes.UnknownOp;
}
}
public class LogicalRecognizer : ExprRecognizer
{
public LogicalRecognizer()
{
Operators = new string[] { "and", /* "xor", */ "or" };
NewLineLeft = NewLineRight = Operators;
Init();
}
public override ExprRecognizerRes Recognize(PString Code, ExprPlugIn PlugIn, ref ExpressionNode Ret)
{
var Result = Code.String.Find(Operators, InZ: true, NotIdChar: true, Back: true);
if (Result.Position != -1)
{
var Ch = Expressions.TwoParamOpNode(Code, Result, PlugIn);
if (Ch == null) return ExprRecognizerRes.Failed;
Operator Op;
if (Result.Index == 0) Op =Operator.And;
//else if (Result.Index == 1) Op = Operator.Xor;
else if (Result.Index == 1) Op = Operator.Or;
else throw new Exception("ERROR");
Ret = new OpExpressionNode(Op, Ch, Code);
return ExprRecognizerRes.Succeeded;
}
return ExprRecognizerRes.UnknownOp;
}
}
public class RelEquRecognizer : ExprRecognizer
{
public RelEquRecognizer()
{
Operators = new string[] { "==", "<>", "<", ">", "<=", "=<", ">=", "=>" };
NewLineLeft = NewLineRight = Operators;
Init();
}
public override ExprRecognizerRes Recognize(PString Code, ExprPlugIn PlugIn, ref ExpressionNode Ret)
{
var Results = Code.String.EnumFind(Operators, InZ: true, Skip: Skip, Back: true).ToArray();
if (Results.Length > 0)
{
var ChNodes = new List<ExpressionNode>();
for (var i = -1; i < Results.Length; i++)
{
int Start, Length;
if (i == -1)
{
var Res = Results[0];
Start = Res.Position + Res.String.Length;
Length = Code.StrLen - Start;
}
else
{
if (i + 1 == Results.Length)
{
Start = 0;
Length = Results[i].Position;
}
else
{
var Res = Results[i + 1];
Start = Res.Position + Res.String.Length;
Length = Results[i].Position - Start;
}
}
var PStr = Code.TrimmedSubstring(Start, Length);
if (PStr.StrLen == 0)
{
PlugIn.State.Messages.Add(MessageId.DeficientExpr, Code);
return ExprRecognizerRes.Failed;
}
var Node = Expressions.Recognize(PStr, PlugIn, true);
if (Node == null) return ExprRecognizerRes.Failed;
ChNodes.Add(Node);
}
var LinkedNodes = new List<LinkedExprNode>();
for (var i = 1; i < ChNodes.Count - 1; i++)
LinkedNodes.Add(new LinkedExprNode(ChNodes[i]));
var RetNodes = new List<ExpressionNode>();
for (var i = 0; i < Results.Length; i++)
{
var Result = Results[i];
Operator Op;
switch (Result.Index)
{
case 0: Op = Operator.Equal; break;
case 1: Op = Operator.Nonequal; break;
case 2: Op = Operator.Less; break;
case 3: Op = Operator.Greater; break;
case 4: Op = Operator.LessEqual; break;
case 5: Op = Operator.LessEqual; break;
case 6: Op = Operator.GreaterEqual; break;
case 7: Op = Operator.GreaterEqual; break;
default: throw new Exception("ERROR");
}
var Ch = new List<ExpressionNode>();
Ch.Add(i != Results.Length - 1 ? PlugIn.NewNode(new LinkingNode(LinkedNodes[i], Code)) : ChNodes[i + 1]);
Ch.Add(i != 0 ? PlugIn.NewNode(new LinkingNode(LinkedNodes[i - 1], Code)) : ChNodes[i]);
var NewNode = PlugIn.NewNode(new OpExpressionNode(Op, Ch, Code));
if (NewNode == null) return ExprRecognizerRes.Failed;
RetNodes.Add(NewNode);
}
while (RetNodes.Count > 1)
{
var Ch = new List<ExpressionNode>() { RetNodes[0], RetNodes[1] };
var Node = (ExpressionNode)new OpExpressionNode(Operator.And, Ch, Code);
if (LinkedNodes.Count > 0 && RetNodes.Count == 2)
Node.LinkedNodes = LinkedNodes;
if ((Node = PlugIn.NewNode(Node)) == null)
return ExprRecognizerRes.Failed;
RetNodes.RemoveAt(0);
RetNodes[0] = Node;
}
Ret = RetNodes[0];
return ExprRecognizerRes.DontCallNewNode;
}
return ExprRecognizerRes.UnknownOp;
}
}
public class AdditiveRecognizer : ExprRecognizer
{
public AdditiveRecognizer()
{
Operators = new string[] { "+", "-" };
NewLineLeft = NewLineRight = Operators;
Init();
}
public override ExprRecognizerRes Recognize(PString Code, ExprPlugIn PlugIn, ref ExpressionNode Ret)
{
var Result = Expressions.Find2(PlugIn.State, Code.String, Operators, Skip);
if (Result.Position != -1)
{
var Ch = Expressions.TwoParamOpNode(Code, Result, PlugIn);
if (Ch == null) return ExprRecognizerRes.Failed;
Operator Op;
if (Result.Index == 0) Op = Operator.Add;
else if (Result.Index == 1) Op = Operator.Subract;
else throw new Exception("ERROR");
Ret = new OpExpressionNode(Op, Ch, Code);
return ExprRecognizerRes.Succeeded;
}
return ExprRecognizerRes.UnknownOp;
}
}
public class MultiplicativeRecognizer : ExprRecognizer
{
public MultiplicativeRecognizer()
{
Operators = new string[] { "*", "/", "%" };
NewLineLeft = NewLineRight = Operators;
}
public override ExprRecognizerRes Recognize(PString Code, ExprPlugIn PlugIn, ref ExpressionNode Ret)
{
var Result = Code.String.Find(Operators, Skip: Skip, InZ: true, End: 1, Back: true);
if (Result.Position != -1)
{
var Ch = Expressions.TwoParamOpNode(Code, Result, PlugIn);
if (Ch == null) return ExprRecognizerRes.Failed;
Operator Op;
if (Result.Index == 0) Op = Operator.Multiply;
else if (Result.Index == 1) Op = Operator.Divide;
else if (Result.Index == 2) Op = Operator.Modolus;
else throw new Exception("ERROR");
Ret = new OpExpressionNode(Op, Ch, Code);
return ExprRecognizerRes.Succeeded;
}
return ExprRecognizerRes.UnknownOp;
}
}
public class ShiftRecognizer : ExprRecognizer
{
public ShiftRecognizer()
{
Operators = new string[] { "<<", ">>" };
NewLineLeft = NewLineRight = Operators;
Init();
}
public override ExprRecognizerRes Recognize(PString Code, ExprPlugIn PlugIn, ref ExpressionNode Ret)
{
var Result = Code.String.Find(Operators, InZ: true, Skip: Skip, Back: true);
if (Result.Position != -1)
{
var Ch = Expressions.TwoParamOpNode(Code, Result, PlugIn);
if (Ch == null) return ExprRecognizerRes.Failed;
Operator Op;
if (Result.Index == 0) Op = Operator.ShiftLeft;
else if (Result.Index == 1) Op = Operator.ShiftRight;
else throw new Exception("ERROR");
Ret = new OpExpressionNode(Op, Ch, Code);
return ExprRecognizerRes.Succeeded;
}
return ExprRecognizerRes.UnknownOp;
}
}
public class BitwiseRecognizer : ExprRecognizer
{
public BitwiseRecognizer()
{
Operators = new string[] { "&", "|", "^" };
NewLineLeft = NewLineRight = Operators;
Init();
}
public override ExprRecognizerRes Recognize(PString Code, ExprPlugIn PlugIn, ref ExpressionNode Ret)
{
var Result = Expressions.Find2(PlugIn.State, Code.String, Operators, Skip);
if (Result.Position != -1)
{
var Ch = Expressions.TwoParamOpNode(Code, Result, PlugIn);
if (Ch == null) return ExprRecognizerRes.Failed;
Operator Op;
if (Result.Index == 0) Op = Operator.BitwiseAnd;
else if (Result.Index == 1) Op = Operator.BitwiseOr;
else if (Result.Index == 2) Op = Operator.BitwiseXor;
else throw new Exception("ERROR");
Ret = new OpExpressionNode(Op, Ch, Code);
return ExprRecognizerRes.Succeeded;
}
return ExprRecognizerRes.UnknownOp;
}
}
public class CastRecognizer : ExprRecognizer
{
public override ExprRecognizerRes Recognize(PString Code, ExprPlugIn PlugIn, ref ExpressionNode Ret)
{
if (Expressions.IsCastString(PlugIn.State, Code.String))
{
var State = PlugIn.State;
var Container = PlugIn.Container;
var Pos = BracketHelper.ZPos(Code.String, 0);
if (Pos == -1)
{
State.Messages.Add(MessageId.ZNumErr, Code.TrimmedSubstring(0, 1));
return ExprRecognizerRes.Failed;
}
var TypeName = Code.TrimmedSubstring(1, Pos - 1);
var Type = Container.GetId<Type>(TypeName);
if (Type == null) return ExprRecognizerRes.Failed;
var ChildStr = Code.TrimmedSubstring(Pos + 1);
var Child = Expressions.Recognize(ChildStr, PlugIn, true);
if (Child == null) return ExprRecognizerRes.Failed;
Ret = new CastExpressionNode(Type, Child, Code);
return ExprRecognizerRes.Succeeded;
}
return ExprRecognizerRes.UnknownOp;
}
}
public class NegateRecognizer : ExprRecognizer
{
public NegateRecognizer()
{
NewLineRight = new string[] { "-", "+" };
Init();
}
public override ExprRecognizerRes Recognize(PString Code, ExprPlugIn PlugIn, ref ExpressionNode Ret)
{
if (Code.String.Length > 0 && Code.String[0] == '-')
{
Ret = Expressions.OneParamOpNode(Code, PlugIn, Operator.Neg);
if (Ret == null) return ExprRecognizerRes.Failed;
return ExprRecognizerRes.Succeeded;
}
else if (Code.String.Length > 0 && Code.String[0] == '+')
{
var SubStr = Code.TrimmedSubstring(1);
if (SubStr.StrLen == 0)
{
PlugIn.State.Messages.Add(MessageId.DeficientExpr, Code);
return ExprRecognizerRes.Failed;
}
Ret = Expressions.Recognize(SubStr, PlugIn, true);
if (Ret == null) return ExprRecognizerRes.Failed;
return ExprRecognizerRes.DontCallNewNode;
}
return ExprRecognizerRes.UnknownOp;
}
}
public class NotRecognizer : ExprRecognizer
{
public NotRecognizer()
{
NewLineRight = new string[] { "!" };
Init();
}
public static ExpressionNode Negate(ExpressionNode Node, ExprPlugIn PlugIn, PString Code)
{
if (Node is OpExpressionNode)
{
var OpNode = Node as OpExpressionNode;
var Op = OpNode.Operator;
var Ch = OpNode.Children;
if (Anonymus.Operators.IsBoolRetOp(Op))
{
OpNode.Operator = Anonymus.Operators.NegateOp(OpNode.Operator);
if (Anonymus.Operators.IsRelEqualityOp(Op)) return Node;
for (var i = 0; i < Ch.Count; i++)
{
Ch[i] = Negate(Ch[i], PlugIn, Code);
if (Ch[i] == null) return null;
}
return Node;
}
}
var NewCh = new List<ExpressionNode>() { Node };
return PlugIn.NewNode(new OpExpressionNode(Operator.Not, NewCh, Code));
}
public override ExprRecognizerRes Recognize(PString Code, ExprPlugIn PlugIn, ref ExpressionNode Ret)
{
if (Code.String.Length > 0 && Code.String[0] == '!')
{
var SubStr = Code.TrimmedSubstring(1);
if (SubStr.StrLen == 0)
{
PlugIn.State.Messages.Add(MessageId.DeficientExpr, Code);
return ExprRecognizerRes.Failed;
}
Ret = Expressions.Recognize(SubStr, PlugIn, true);
if (Ret == null) return ExprRecognizerRes.Failed;
if ((Ret = Negate(Ret, PlugIn, Code)) == null)
return ExprRecognizerRes.Failed;
return ExprRecognizerRes.DontCallNewNode;
}
return ExprRecognizerRes.UnknownOp;
}
}
public class AddressRecognizer : ExprRecognizer
{
public AddressRecognizer()
{
NewLineRight = new string[] { "&" };
Init();
}
public override ExprRecognizerRes Recognize(PString Code, ExprPlugIn PlugIn, ref ExpressionNode Ret)
{
if (Code.String.Length > 0 && Code.String[0] == '&')
{
Ret = Expressions.OneParamOpNode(Code, PlugIn, Operator.Address);
if (Ret == null) return ExprRecognizerRes.Failed;
return ExprRecognizerRes.Succeeded;
}
return ExprRecognizerRes.UnknownOp;
}
}
public class ComplementRecognizer : ExprRecognizer
{
public ComplementRecognizer()
{
NewLineRight = new string[] { "~" };
Init();
}
public override ExprRecognizerRes Recognize(PString Code, ExprPlugIn PlugIn, ref ExpressionNode Ret)
{
if (Code.String.Length > 0 && Code.String[0] == '~')
{
Ret = Expressions.OneParamOpNode(Code, PlugIn, Operator.Complement);
if (Ret == null) return ExprRecognizerRes.Failed;
return ExprRecognizerRes.Succeeded;
}
return ExprRecognizerRes.UnknownOp;
}
}
public class IncDecRecognizer : ExprRecognizer
{
public IncDecRecognizer()
{
Operators = new string[] { "++", "--" };
NewLineLeft = Operators;
Init();
}
public override ExprRecognizerRes Recognize(PString Code, ExprPlugIn PlugIn, ref ExpressionNode Ret)
{
if (Code.String.EndsWith("++"))
{
Ret = Expressions.IncDecNode(Code, PlugIn, Operator.Add, 2);
if (Ret == null) return ExprRecognizerRes.Failed;
return ExprRecognizerRes.DontCallNewNode;
}
else if (Code.String.EndsWith("--"))
{
Ret = Expressions.IncDecNode(Code, PlugIn, Operator.Subract, 2);
if (Ret == null) return ExprRecognizerRes.Failed;
return ExprRecognizerRes.DontCallNewNode;
}
return ExprRecognizerRes.UnknownOp;
}
}
public class IndirectionRecognizer : ExprRecognizer
{
public IndirectionRecognizer()
{
NewLineRight = new string[] { "*" };
Init();
}
public override ExprRecognizerRes Recognize(PString Code, ExprPlugIn PlugIn, ref ExpressionNode Ret)
{
if (Code.String.Length > 0 && Code.String[0] == '*')
{
var PtrCode = Code.TrimmedSubstring(1);
var PtrNode = Expressions.Recognize(PtrCode, PlugIn, true);
if (PtrNode == null) return ExprRecognizerRes.Failed;
var IdPtrNode = PtrNode as IdExpressionNode;
if (PtrNode.Type is TypeOfType && IdPtrNode != null)
{
var Type = (IdPtrNode.Id as Type).CreatePointerType();
Ret = new IdExpressionNode(Type, Code);
}
else
{
Ret = PtrNode.Indirection(PlugIn.State, PlugIn.Container, Code, PlugIn);
if (Ret == null) return ExprRecognizerRes.Failed;
return ExprRecognizerRes.DontCallNewNode;
}
}
return ExprRecognizerRes.UnknownOp;
}
}
public class CallIndexRecognizer : ExprRecognizer
{
public List<KeywordFuncRecognizer> Recognizers;
public CallIndexRecognizer(List<KeywordFuncRecognizer> Recognizers)
{
this.Recognizers = Recognizers;
Operators = new string[] { "(", "[" };
NewLineRight = Operators;
Init();
}
public override ExprRecognizerRes Recognize(PString Code, ExprPlugIn PlugIn, ref ExpressionNode Ret)
{
var Result = Code.String.Find(Operators, Skip: Skip);
if (Result.Position > 0)
{
var State = PlugIn.State;
var Pos = BracketHelper.ZPos(Code.String, Result.Position);
if (Pos == -1)
{
var Str = Code.TrimmedSubstring(Result.Position, 1);
State.Messages.Add(MessageId.ZNumErr, Str);
return ExprRecognizerRes.Failed;
}
Operator Op;
if (Result.Index == 0) Op = Operator.Call;
else if (Result.Index == 1) Op = Operator.Index;
else throw new Exception("ERROR");
var Func = Code.TrimmedSubstring(0, Result.Position);
var ParamStr = Code.Substring(Result.Position + 1, Pos - Result.Position - 1);
var AllParams = Expressions.ConstructCallIndexParams(State, Func, ParamStr);
if (Recognizers != null)
{
foreach (var e in Recognizers)
{
var Res = e.Recognize(Code, AllParams, PlugIn, ref Ret);
if (Res != ExprRecognizerRes.UnknownOp) return Res;
}
}
Ret = Expressions.CreateCallIndexExpr(Code, PlugIn, Op, AllParams);
if (Ret == null) return ExprRecognizerRes.Failed;
return ExprRecognizerRes.DontCallNewNode;
}
return ExprRecognizerRes.UnknownOp;
}
}
public class NullCoalescingRecognizer : ExprRecognizer
{
public NullCoalescingRecognizer()
{
Operators = new string[] { "??" };
NewLineLeft = NewLineRight = Operators;
Init();
}
public override ExprRecognizerRes Recognize(PString Code, ExprPlugIn PlugIn, ref ExpressionNode Ret)
{
var Result = Expressions.Find2(PlugIn.State, Code.String, Operators, Skip);
if (Result.Position != -1)
{
var State = PlugIn.State;
var Container = PlugIn.Container;
var GlobalScope = Container.GlobalScope;
var LeftRight = Expressions.TwoParamOpNode(Code, Result, PlugIn);
if (LeftRight == null) return ExprRecognizerRes.Failed;
var Linked = new LinkedExprNode(LeftRight[0]);
var Null = PlugIn.NewNode(new ConstExpressionNode(GlobalScope.AutoType, 0UL, Code));
if (Null == null) return ExprRecognizerRes.Failed;
var RelLnk = PlugIn.NewNode(new LinkingNode(Linked, Code));
if (RelLnk == null) return ExprRecognizerRes.Failed;
var RelCh = new List<ExpressionNode>() { RelLnk, Null };
var Rel = PlugIn.NewNode(new OpExpressionNode(Operator.Nonequal, RelCh, Code));
if (Rel == null) return ExprRecognizerRes.Failed;
var RetLnk = PlugIn.NewNode(new LinkingNode(Linked, Code));
if (RetLnk == null) return ExprRecognizerRes.Failed;
var RetCh = new List<ExpressionNode>() { Rel, RetLnk, LeftRight[1] };
Ret = new OpExpressionNode(Operator.Condition, RetCh, Code);
Ret.LinkedNodes = new List<LinkedExprNode>() { Linked };
return ExprRecognizerRes.Succeeded;
}
return ExprRecognizerRes.UnknownOp;
}
}
public class SafeNavigationRecognizer : ExprRecognizer
{
public SafeNavigationRecognizer()
{
Operators = new string[] { "?.", "?->" };
NewLineLeft = NewLineRight = Operators;
Init();
}
public override ExprRecognizerRes Recognize(PString Code, ExprPlugIn PlugIn, ref ExpressionNode Ret)
{
var Result = Expressions.Find2(PlugIn.State, Code.String, Operators, Skip);
if (Result.Position != -1)
{
var State = PlugIn.State;
var Container = PlugIn.Container;
var GlobalScope = Container.GlobalScope;
var Left_Str = Code.TrimmedSubstring(0, Result.Position);
var Right_Str = Code.TrimmedSubstring(Result.Position + Result.String.Length);
if (Left_Str.StrLen == 0 || Right_Str.StrLen == 0)
{
State.Messages.Add(MessageId.DeficientExpr, Code);
return ExprRecognizerRes.Failed;
}
var Left = Expressions.Recognize(Left_Str, PlugIn, true);
if (Left == null) return ExprRecognizerRes.Failed;
var Linked = new LinkedExprNode(Left);
//--------------------------------------------------------------------------------------
var Null = PlugIn.NewNode(new ConstExpressionNode(GlobalScope.AutoType, 0UL, Code));
if (Null == null) return ExprRecognizerRes.Failed;
var RelLnk = PlugIn.NewNode(new LinkingNode(Linked, Code));
if (RelLnk == null) return ExprRecognizerRes.Failed;
var RelCh = new List<ExpressionNode>() { RelLnk, Null };
var Rel = PlugIn.NewNode(new OpExpressionNode(Operator.Nonequal, RelCh, Code));
if (Rel == null) return ExprRecognizerRes.Failed;
//--------------------------------------------------------------------------------------
var ThenSrc = PlugIn.NewNode(new LinkingNode(Linked, Code));
if (ThenSrc == null) return ExprRecognizerRes.Failed;
if (Result.Index == 1)
{
ThenSrc = ThenSrc.Indirection(State, Container, Code, PlugIn);
if (ThenSrc == null) return ExprRecognizerRes.Failed;
}
var ThenSrcType = ThenSrc.Type as StructuredType;
if (ThenSrcType == null)
{
State.Messages.Add(MessageId.HasntGotMembers, Left_Str, ThenSrc.Type.Name.String);
return ExprRecognizerRes.Failed;
}
var Member = ThenSrcType.GetId<Identifier>(Right_Str.String);
if (Member == null)
{
State.Messages.Add(MessageId.UnknownId, Right_Str);
return ExprRecognizerRes.Failed;
}
else if (Member.IsStatic)
{
State.Messages.Add(MessageId.Static, Right_Str);
return ExprRecognizerRes.Failed;
}
var MemberNode = PlugIn.NewNode(new IdExpressionNode(Member, Code));
if (MemberNode == null) return ExprRecognizerRes.Failed;
var ThenCh = new List<ExpressionNode>() { ThenSrc, MemberNode };
var Then = PlugIn.NewNode(new OpExpressionNode(Operator.Member, ThenCh, Code));
if (Then == null) return ExprRecognizerRes.Failed;
//--------------------------------------------------------------------------------------
var Else = PlugIn.NewNode(new ConstExpressionNode(GlobalScope.AutoType, 0UL, Code));
if (Else == null) return ExprRecognizerRes.Failed;
var RetCh = new List<ExpressionNode>() { Rel, Then, Else };
Ret = new OpExpressionNode(Operator.Condition, RetCh, Code);
Ret.LinkedNodes = new List<LinkedExprNode>() { Linked };
return ExprRecognizerRes.Succeeded;
}
return ExprRecognizerRes.UnknownOp;
}
}
public class MemberRecognizer : ExprRecognizer
{
public MemberRecognizer()
{
Operators = new string[] { ".", "->" };
NewLineLeft = NewLineRight = Operators;
Init();
}
public override ExprRecognizerRes Recognize(PString Code, ExprPlugIn PlugIn, ref ExpressionNode Ret)
{
var Result = Code.String.Find(Operators, Skip: Skip, InZ: true);
if (Result.Position > 0)
{
var State = PlugIn.State;
var Container = PlugIn.Container;
var Left_Str = Code.TrimmedSubstring(0, Result.Position);
var Right_Str = Code.TrimmedSubstring(Result.Position + Result.String.Length);
if (Right_Str.StrLen == 0 || Left_Str.StrLen == 0)
{
State.Messages.Add(MessageId.DeficientExpr, Code);
return ExprRecognizerRes.Failed;
}
if (!Helper.IsValidIdentifierName(Right_Str.String) && !Right_Str.String.IsNum())
{
State.Messages.Add(MessageId.NotValidName, Right_Str);
return ExprRecognizerRes.Failed;
}
var Left = Expressions.Recognize(Left_Str, PlugIn, true);
if (Left == null) return ExprRecognizerRes.Failed;
if (Result.Index == 1)
{
Left = Left.Indirection(State, Container, Code, PlugIn);
if (Left == null) return ExprRecognizerRes.Failed;
}
var Ch = new List<ExpressionNode>() { Left };
var RealType = Left.Type.RealType;
if (RealType is StructuredType)
{
var SRealType = RealType as StructuredType;
var Id = (Identifier)null;
if (SRealType == null || (Id = SRealType.GetId<Identifier>(Right_Str.String)) == null)
{
State.Messages.Add(MessageId.UnknownId, Right_Str);
return ExprRecognizerRes.Failed;
}
if (Id.IsStatic)
{
State.Messages.Add(MessageId.Static, Right_Str);
return ExprRecognizerRes.Failed;
}
var V = PlugIn.NewNode(new IdExpressionNode(Id, Code));
if (V == null) return ExprRecognizerRes.Failed;
Ch.Add(V);
Ret = new OpExpressionNode(Operator.Member, Ch, Code);
return ExprRecognizerRes.Succeeded;
}
else if (RealType is TypeOfType)
{
var IdNode = Left as IdExpressionNode;
var Id = (Identifier)null;
if (IdNode.Id is EnumType)
{
var EType = IdNode.Id as EnumType;
var Val = EType.GetValue(Right_Str.String);
if (Val == null)
{
State.Messages.Add(MessageId.UnknownId, Right_Str);
return ExprRecognizerRes.Failed;
}
Ret = Val.GetNode(State, Code, PlugIn);
return ExprRecognizerRes.DontCallNewNode;
}
else if (IdNode.Id is StructuredType)
{
var Type = IdNode.Id as StructuredType;
if ((Id = Type.GetId<Identifier>(Right_Str.String)) == null)
{
State.Messages.Add(MessageId.UnknownId, Right_Str);
return ExprRecognizerRes.Failed;
}
if (!Id.IsStatic)
{
State.Messages.Add(MessageId.NonStatic, Right_Str);
return ExprRecognizerRes.Failed;
}
Ret = new IdExpressionNode(Id, Code);
return ExprRecognizerRes.Succeeded;
}
else
{
State.Messages.Add(MessageId.UnknownId, Right_Str);
return ExprRecognizerRes.Failed;
}
}
else
{
State.Messages.Add(MessageId.HasntGotMembers, Left_Str, RealType.Name.String);
return ExprRecognizerRes.Failed;
}
}
return ExprRecognizerRes.UnknownOp;
}
}
public class ExprVarDeclRecognizer : ExprRecognizer
{
public ExprVarDeclRecognizer()
{
Operators = new string[] { " ", "\t", "\r", "\n" };
Init();
}
public override ExprRecognizerRes Recognize(PString Code, ExprPlugIn PlugIn, ref ExpressionNode Ret)
{
var Result = Code.String.Find(Operators, InZ: true);
if (Result.Position != -1)
{
var VarName = Code.TrimmedSubstring(Result.Position);
if (!Helper.IsValidIdentifierName(VarName.String))
return ExprRecognizerRes.UnknownOp;
var Container = PlugIn.Container;
var State = PlugIn.State;
var TypeName = Code.TrimmedSubstring(0, Result.Position);
Ret = PlugIn.DeclareVariable(Code, TypeName, VarName);
if (Ret == null) return ExprRecognizerRes.Failed;
else return ExprRecognizerRes.DontCallNewNode;
}
return ExprRecognizerRes.UnknownOp;
}
}
}