using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
namespace Anonymus
{
public enum Operator
{
Nothing,
Assignment,
Condition,
CreateTuple,
New,
Ref,
Indirection,
Call,
Index,
Member,
Neg,
Not,
Address,
Complement,
And,
Or,
Xor,
Less,
Greater,
Equal,
Nonequal,
LessEqual,
GreaterEqual,
Add,
Subract,
Multiply,
Divide,
Modolus,
ShiftLeft,
ShiftRight,
BitwiseAnd,
BitwiseOr,
BitwiseXor,
Abs,
Sqrt,
Sin,
Cos,
Tan,
ATan,
ATan2,
ASin,
ACos,
}
public static class Operators
{
public static bool IsStdOp(Operator Op)
{
return Operators.IsBoolRetBitArithmOp(Op) || Operators.IsMathsOp(Op) ||
Op == Operator.Neg || Op == Operator.Not || Op == Operator.Complement || Op == Operator.Condition;
}
public static bool IsMathsOp(Operator Op)
{
return Op == Operator.Abs || Op == Operator.Sqrt || Op == Operator.Sin || Op == Operator.ASin ||
Op == Operator.ACos || Op == Operator.Cos || Op == Operator.Tan || Op == Operator.ATan || Op == Operator.ATan2;
}
public static bool IsInstructionOp(Operator Op)
{
return IsRelEqualityOp(Op) || IsBitArithmOp(Op) || Op == Operator.Assignment;
}
public static bool IsArithmeticalOp(Operator Op)
{
return Op == Operator.Add || Op == Operator.Subract || Op == Operator.Multiply ||
Op == Operator.Divide || Op == Operator.Modolus;
}
public static bool IsRelEqualityOp(Operator Op)
{
return Op == Operator.Equal || Op == Operator.Nonequal || Op == Operator.Less ||
Op == Operator.LessEqual || Op == Operator.Greater || Op == Operator.GreaterEqual;
}
public static bool IsShiftOp(Operator Op)
{
return Op == Operator.ShiftLeft || Op == Operator.ShiftRight;
}
public static bool IsBitwiseOp(Operator Op)
{
return Op == Operator.BitwiseAnd || Op == Operator.BitwiseOr || Op == Operator.BitwiseXor;
}
public static bool IsLogicalOp(Operator Op)
{
return Op == Operator.And || Op == Operator.Or || Op == Operator.And;
}
public static bool IsBitArithmOp(Operator Op)
{
return IsArithmeticalOp(Op) || IsShiftOp(Op) || IsBitwiseOp(Op);
}
public static bool IsBoolRetBitArithmOp(Operator Op)
{
return IsBitArithmOp(Op) || IsBoolRetOp(Op);
}
public static bool IsBoolRetOp(Operator Op)
{
return IsLogicalOp(Op) || IsRelEqualityOp(Op);
}
public static Operator NegateOp(Operator Op)
{
switch (Op)
{
case Operator.And: Op = Operator.Or; break;
case Operator.Or: Op = Operator.And; break;
case Operator.Equal: Op = Operator.Nonequal; break;
case Operator.Nonequal: Op = Operator.Equal; break;
case Operator.Less: Op = Operator.GreaterEqual; break;
case Operator.LessEqual: Op = Operator.Greater; break;
case Operator.Greater: Op = Operator.LessEqual; break;
case Operator.GreaterEqual: Op = Operator.Less; break;
default: throw new Exception("ERROR");
}
return Op;
}
}
public delegate ExpressionNode ReplaceVarsFunc(string Name);
public delegate ExpressionNode ReplaceNodeFunc(ExpressionNode Node);
public class MacroExpressionNode : ExpressionNode
{
public Macro Macro;
public MacroExpressionNode(Macro Macro, PString Code)
: base(Code)
{
this.Macro = Macro;
}
public override ExpressionNode Copy(CompilerState State, PString Code, ReplaceNodeFunc Func)
{
if (Code == null) Code = this.Code;
return Func(new MacroExpressionNode(Macro, Code));
}
}
public class MacroArgNode : ExpressionNode
{
public int Index;
public MacroArgNode(int Index, PString Code)
: base(Code)
{
this.Index = Index;
}
public override ExpressionNode Copy(CompilerState State, PString Code, ReplaceNodeFunc Func)
{
if (Code == null) Code = this.Code;
return Func(new MacroArgNode(Index, Code));
}
}
public class StrExpressionNode : ExpressionNode
{
public StrExpressionNode(PString Code)
: base(Code)
{
}
public override ExpressionNode Copy(CompilerState State, PString Code, ReplaceNodeFunc Func)
{
if (Code == null) Code = this.Code;
return Func(new StrExpressionNode(Code));
}
}
public class IdExpressionNode : ExpressionNode
{
public Identifier Id;
public bool MustBeAssigned = false;
public IdExpressionNode(Identifier Id, PString Code)
: base(Code)
{
this.Id = Id;
}
public override ExpressionNode Copy(CompilerState State, PString Code, ReplaceNodeFunc Func)
{
if (Code == null) Code = this.Code;
return Func(new IdExpressionNode(Id, Code));
}
}
public class OpExpressionNode : ExpressionNode
{
public List<ExpressionNode> Children;
public Operator Operator = Operator.Nothing;
public bool Reverse = false;
public OpExpressionNode(Operator Operator, List<ExpressionNode> Children, PString Code)
: base(Code)
{
this.Operator = Operator;
this.Children = Children;
}
public OpExpressionNode(PString Code)
: base(Code)
{
this.Operator = Operator.Nothing;
this.Children = null;
}
protected override void CallChNewNode(ExprPlugIn Settings, bool CallToLinkedNodes)
{
for (var i = 0; i < Children.Count; i++)
Children[i] = Children[i].CallNewNode(Settings, false, false, CallToLinkedNodes);
base.CallChNewNode(Settings, CallToLinkedNodes);
}
public override IEnumerable<ExpressionNode> EnumChildrenF(NodeEnumMode Mode)
{
foreach (var e in base.EnumChildrenF(Mode))
yield return e;
foreach (var e in Children)
{
if (!(e is LinkingNode))
{
if (Mode.HasFlag(NodeEnumMode.Nodes))
yield return e;
}
else
{
if (Mode.HasFlag(NodeEnumMode.Linking))
yield return e;
}
}
}
public override ExpressionNode Copy(CompilerState State, PString Code, ReplaceNodeFunc Func)
{
var Ch = new List<ExpressionNode>();
foreach (var e in Children)
{
var p = e.Copy(State, Code, Func);
if (p == null) return null;
Ch.Add(p);
}
if (Code == null) Code = this.Code;
return Func(new OpExpressionNode(Operator, Ch, Code));
}
public override void ReplaceNodes(ExpressionNode From, ExpressionNode To)
{
base.ReplaceNodes(From, To);
for (int i = 0; i < Children.Count; i++)
if (Children[i] == From) Children[i] = To;
}
public override bool GetAssignVar(ref Variable AssignVar)
{
if (Operator == Operator.Assignment)
{
var N = Children[0] as IdExpressionNode;
if (N != null) AssignVar = N.Id as Variable;
else AssignVar = null;
return true;
}
return false;
}
public void Swap()
{
var tmp = Children[0];
Children[0] = Children[1];
Children[1] = tmp;
if (Operator == Operator.Subract || Operator == Operator.Divide)
{
Reverse = !Reverse;
}
else if (Operators.IsRelEqualityOp(Operator))
{
if (Operator == Operator.Less) Operator = Operator.Greater;
else if (Operator == Operator.LessEqual) Operator = Operator.GreaterEqual;
else if (Operator == Operator.Greater) Operator = Operator.Less;
else if (Operator == Operator.GreaterEqual) Operator = Operator.LessEqual;
}
}
}
public class CastExpressionNode : ExpressionNode
{
public ExpressionNode Child;
protected override void CallChNewNode(ExprPlugIn Settings, bool CallToLinkedNodes)
{
Child = Child.CallNewNode(Settings, false, false, CallToLinkedNodes);
base.CallChNewNode(Settings, CallToLinkedNodes);
}
public override void ReplaceNodes(ExpressionNode From, ExpressionNode To)
{
if (Child == From) Child = To;
base.ReplaceNodes(From, To);
}
public CastExpressionNode(Type Type, ExpressionNode Child, PString Code)
: base(Code)
{
this.Type = Type;
this.Child = Child;
}
public override IEnumerable<ExpressionNode> EnumChildrenF(NodeEnumMode Mode)
{
foreach (var e in base.EnumChildrenF(Mode))
yield return e;
if (!(Child is LinkingNode))
{
if (Mode.HasFlag(NodeEnumMode.Nodes))
yield return Child;
}
else
{
if (Mode.HasFlag(NodeEnumMode.Linking))
yield return Child;
}
}
public override ExpressionNode Copy(CompilerState State, PString Code, ReplaceNodeFunc Func)
{
var Ch = Child.Copy(State, Code, Func);
if (Code == null) Code = this.Code;
return Func(new CastExpressionNode(Type, Ch, Code));
}
}
public class LinkedExprNode
{
public ExpressionNode Node;
public object ArchData;
public int LinkingCount = 0;
public LinkedExprNode(ExpressionNode Node)
{
this.Node = Node;
}
}
[Flags]
public enum NodeEnumMode
{
Nodes = 1,
Linking = 2,
Linked = 4,
NodesnLinked = Nodes | Linked,
}
public class LinkingNode : ExpressionNode
{
public LinkedExprNode LinkedNode;
public LinkingNode(LinkedExprNode Node, PString Code)
: base(Code)
{
this.LinkedNode = Node;
}
public override IEnumerable<ExpressionNode> EnumChildrenF(NodeEnumMode Mode)
{
foreach (var e in base.EnumChildrenF(Mode))
yield return e;
if (Mode.HasFlag(NodeEnumMode.Linked))
yield return LinkedNode.Node;
}
public override ExpressionNode Copy(CompilerState State, PString Code, ReplaceNodeFunc Func)
{
if (Code == null) Code = this.Code;
return Func(new LinkingNode(LinkedNode, Code));
}
public override ExpressionNode RealNode
{
get { return LinkedNode.Node; }
}
}
public abstract class ExpressionNode
{
public List<LinkedExprNode> LinkedNodes;
public Type Type;
public object ArchData;
public PString Code;
// RootNode Data
public NodeVariables Vars;
public virtual ExpressionNode RealNode
{
get { return this; }
}
public virtual IEnumerable<ExpressionNode> EnumChildrenF(NodeEnumMode Mode)
{
if (LinkedNodes != null && Mode.HasFlag(NodeEnumMode.Linked))
{
foreach (var e in LinkedNodes)
yield return e.Node;
}
}
public IEnumerable<ExpressionNode> EnumChildren
{
get { return EnumChildrenF(NodeEnumMode.NodesnLinked); }
}
public IEnumerable<ExpressionNode> EnumChWithoutLinkedNodes
{
get { return EnumChildrenF(NodeEnumMode.Nodes); }
}
public virtual void ReplaceNodes(ExpressionNode From, ExpressionNode To)
{
if (LinkedNodes != null)
{
foreach (var e in LinkedNodes)
if (e.Node == From) e.Node = To;
}
}
public virtual ConditionRes ConditionResult
{ get { return ConditionRes.Unknown; } }
protected virtual void CallChNewNode(ExprPlugIn Settings, bool CallToLinkedNodes)
{
}
public ExpressionNode CallNewNode(ExprPlugIn Settings, bool Begin = true, bool End = true,
bool CallToLinkedNodes = true)
{
if (Begin) Settings.Begin();
if (LinkedNodes != null && CallToLinkedNodes)
{
for (var i = 0; i < LinkedNodes.Count; i++)
{
var N = LinkedNodes[i].Node;
N = N.CallNewNode(Settings, false, false);
LinkedNodes[i].Node = N;
}
}
CallChNewNode(Settings, CallToLinkedNodes);
var Node = Settings.NewNode(this);
if (End) Node = Settings.End(Node);
return Node;
}
public ExpressionNode Copy(CompilerState State, PString Code = null, ExprPlugIn PlugIn = null,
ReplaceNodeFunc Func = null, bool Begin = true, bool End = true)
{
if (Begin && PlugIn != null) PlugIn.Begin();
var Ret = Copy(State, Code, (Node) =>
{
if (Func != null) Node = Func(Node);
if (PlugIn != null && Node != null) return PlugIn.NewNode(Node);
else return Node;
});
if (End && Ret != null && PlugIn != null) Ret = PlugIn.End(Ret);
return Ret;
}
public abstract ExpressionNode Copy(CompilerState State, PString Code, ReplaceNodeFunc Func);
public ExpressionNode(PString Code)
{
this.Code = Code;
}
public ExpressionNode Indirection(CompilerState State, IdContainer Container,
PString Code, ExprPlugIn PlugIn = null)
{
var Ch = new List<ExpressionNode>() { this };
var Ret = new OpExpressionNode(Operator.Indirection, Ch, Code);
if (PlugIn == null) return Ret;
else return PlugIn.NewNode(Ret);
}
public ExpressionNode CreateAssignExpr(ExpressionNode Child, PString Code,
ExprPlugIn PlugIn = null, bool End = false)
{
var Children = new List<ExpressionNode>() { Child, this };
var Ret = (ExpressionNode)new OpExpressionNode(Operator.Assignment, Children, Code);
if (PlugIn == null) return Ret;
Ret = PlugIn.NewNode(Ret);
if (Ret == null) return null;
if (End) Ret = PlugIn.End(Ret);
return Ret;
}
public ExpressionNode CreateAssignExpr(Identifier Id, PString Code,
ExprPlugIn PlugIn = null, bool End = false)
{
var Child = (ExpressionNode)new IdExpressionNode(Id, Code);
if (PlugIn != null)
{
Child = PlugIn.NewNode(Child);
if (Child == null) return null;
}
return CreateAssignExpr(Child, Code, PlugIn, End);
}
public ExpressionNode CreateCastExpr(Type Type, PString Code = null, ExprPlugIn PlugIn = null)
{
if (Code == null) Code = this.Code;
var Ret = new CastExpressionNode(Type, this, Code);
if (PlugIn == null) return Ret;
else return PlugIn.NewNode(Ret);
}
public bool IdUsed(Identifier Id)
{
if (this is IdExpressionNode)
{
var RId = this as IdExpressionNode;
return RId.Id == Id;
}
foreach (var Ch in EnumChWithoutLinkedNodes)
if (Ch.IdUsed(Id)) return true;
return false;
}
public bool IdUsed()
{
if (this is IdExpressionNode || this is StrExpressionNode)
return true;
foreach (var e in EnumChildren)
if (e.IdUsed()) return true;
return false;
}
public virtual bool GetAssignVar(ref Variable AssignVar)
{
return false;
}
}
public class NodeVariables
{
public List<IdExpressionNode> AssignedIds = new List<IdExpressionNode>();
public List<IdExpressionNode> UsedBeforeAssignIds = new List<IdExpressionNode>();
public NodeVariables()
{
}
public bool UsedBeforeAssign(Identifier Id)
{
foreach (var e in UsedBeforeAssignIds)
if (e.Id == Id) return true;
return false;
}
public bool Assigned(Identifier Id)
{
foreach (var e in AssignedIds)
if (e.Id == Id) return true;
return false;
}
public bool Assigned(IEnumerable<Identifier> Ids)
{
foreach (var e in Ids)
if (!Assigned(e)) return false;
return true;
}
}
}