Beispiel #1
0
 public CacheEntry(int hash, ESIR_Node node)
 {
     Hash = hash;
     Node = node;
 }
Beispiel #2
0
    private unsafe void AddIRNodeToTree(ESIR_Node node, TreeViewItem parentItem)
    {
        Debug.Assert(node is not null);
        if (node is null)
        {
            return;
        }

        switch (node.Kind)
        {
        case ESIR_NodeKind.ValueInt:
        case ESIR_NodeKind.ValueUInt:
        case ESIR_NodeKind.ValueFloat32:
        case ESIR_NodeKind.ValueFloat64:
        case ESIR_NodeKind.ValueIdentifier:
        case ESIR_NodeKind.ValueString:
        case ESIR_NodeKind.ValuePointer:
        case ESIR_NodeKind.List:
        case ESIR_NodeKind.TypeNode:
            Debug.Fail("These nodes shouldn't be added directly.");
            break;

        case ESIR_NodeKind.StaticVariable when node is ESIR_StaticVariable staticVar:
            AddNodeToTree($"{staticVar.Name} : {GetTypeName (staticVar.Type)}", parentItem);
            break;


        case ESIR_NodeKind.Struct when node is ESIR_Struct structDef: {
            var structItem = AddNodeToTree($"{GetTypeName (structDef.Type)}", parentItem);
            AddNodeToTree($"Size: {structDef.Type->RuntimeSize}", structItem);

            foreach (var member in structDef.Members.Elements)
            {
                AddIRNodeToTree(member, structItem);
            }

            break;
        }

        case ESIR_NodeKind.Function when node is ESIR_Function funcDef: {
            var structItem = AddNodeToTree($"{GetString (funcDef.Name)}", parentItem);
            AddNodeToTree($"Return type: {GetTypeName (funcDef.ReturnType)}", structItem);

            var argsItem   = AddNodeToTree("Arguments", structItem);
            var localsItem = AddNodeToTree("Locals", structItem);
            var bodyItem   = AddNodeToTree("Function body", structItem);

            var argsCount = 0;
            foreach (var arg in funcDef.Arguments.Elements)
            {
                AddNodeToTree(GetArgString(argsCount++, arg), argsItem);
            }

            var localsCount = 0;
            foreach (var localVal in funcDef.LocalValues.Elements)
            {
                AddNodeToTree(GetLocalValueString(localsCount++, localVal), localsItem);
            }

            foreach (var stmt in funcDef.Statements.Elements)
            {
                AddIRNodeToTree(stmt, bodyItem);
            }

            break;
        }

        case ESIR_NodeKind.ArgumentValue when node is ESIR_ArgumentValue argVal:
            if (argVal.ArgType == ES_ArgumentType.Normal)
            {
                AddNodeToTree($"{GetNiceExpr (argVal.Expression)}", parentItem);
            }
            else
            {
                AddNodeToTree($"{argVal.ArgType} {GetNiceExpr (argVal.Expression)}", parentItem);
            }
            break;

        case ESIR_NodeKind.Class:
            Debug.Fail("No IR node yet.");
            break;

        case ESIR_NodeKind.Field when node is ESIR_Field field: {
            var fieldItem = AddNodeToTree($"{GetString (field.Name)} : {GetTypeName (field.Type)}", parentItem);
            AddNodeToTree($"Offset: {field.Offset}", fieldItem);
            break;
        }

        case ESIR_NodeKind.StaticField when node is ESIR_StaticField staticField:
            AddNodeToTree($"{GetString (staticField.Name)} : {GetString (staticField.StaticVariable)}", parentItem);
            break;

            #region Expressions

        case ESIR_NodeKind.ErrorExpression:
            AddNodeToTree("[ERROR]", parentItem);
            break;

        case ESIR_NodeKind.AssignExpression when node is ESIR_AssignExpression assignExpr: {
            var assignItem = AddNodeToTree($"Assign: {GetNiceExpr (assignExpr.Assignee)} = {GetNiceExpr (assignExpr.Value)}", parentItem);
            AddIRNodeToTree(assignExpr.Assignee, assignItem);
            AddIRNodeToTree(assignExpr.Value, assignItem);
            break;
        }

            #region Binary

        case ESIR_NodeKind.BinaryExprConcat when node is ESIR_SimpleBinaryExpression binaryExpr: {
            AddBinaryExprToTree("Concatenate", "..", binaryExpr, parentItem);
            break;
        }

        case ESIR_NodeKind.BinaryExprPower when node is ESIR_SimpleBinaryExpression binaryExpr: {
            AddBinaryExprToTree("Exponentiate", "**", binaryExpr, parentItem);
            break;
        }

        case ESIR_NodeKind.BinaryExprMultiply when node is ESIR_SimpleBinaryExpression binaryExpr: {
            AddBinaryExprToTree("Multiply", "*", binaryExpr, parentItem);
            break;
        }

        case ESIR_NodeKind.BinaryExprDivide when node is ESIR_SimpleBinaryExpression binaryExpr: {
            AddBinaryExprToTree("Divide", "/", binaryExpr, parentItem);
            break;
        }

        case ESIR_NodeKind.BinaryExprModulo when node is ESIR_SimpleBinaryExpression binaryExpr: {
            AddBinaryExprToTree("Modulo", "%", binaryExpr, parentItem);
            break;
        }

        case ESIR_NodeKind.BinaryExprAdd when node is ESIR_SimpleBinaryExpression binaryExpr: {
            AddBinaryExprToTree("Add", "+", binaryExpr, parentItem);
            break;
        }

        case ESIR_NodeKind.BinaryExprSubtract when node is ESIR_SimpleBinaryExpression binaryExpr: {
            AddBinaryExprToTree("Subtract", "-", binaryExpr, parentItem);
            break;
        }

        case ESIR_NodeKind.BinaryExprShiftLeft when node is ESIR_SimpleBinaryExpression binaryExpr: {
            AddBinaryExprToTree("Left shift", "<<", binaryExpr, parentItem);
            break;
        }

        case ESIR_NodeKind.BinaryExprShiftRight when node is ESIR_SimpleBinaryExpression binaryExpr: {
            AddBinaryExprToTree("Right shift", ">>", binaryExpr, parentItem);
            break;
        }

        case ESIR_NodeKind.BinaryExprShiftRightUnsigned when node is ESIR_SimpleBinaryExpression binaryExpr: {
            AddBinaryExprToTree("Unsigned right shift", ">>>", binaryExpr, parentItem);
            break;
        }

        case ESIR_NodeKind.BinaryExprLesserThan when node is ESIR_SimpleBinaryExpression binaryExpr: {
            AddBinaryExprToTree("Lesser than", "<", binaryExpr, parentItem);
            break;
        }

        case ESIR_NodeKind.BinaryExprGreaterThan when node is ESIR_SimpleBinaryExpression binaryExpr: {
            AddBinaryExprToTree("Greater than", ">", binaryExpr, parentItem);
            break;
        }

        case ESIR_NodeKind.BinaryExprLesserThanEqual when node is ESIR_SimpleBinaryExpression binaryExpr: {
            AddBinaryExprToTree("Lesser than-equals", "<=", binaryExpr, parentItem);
            break;
        }

        case ESIR_NodeKind.BinaryExprGreaterThanEqual when node is ESIR_SimpleBinaryExpression binaryExpr: {
            AddBinaryExprToTree("Greater than-equals", ">=", binaryExpr, parentItem);
            break;
        }

        case ESIR_NodeKind.BinaryExprEquals when node is ESIR_SimpleBinaryExpression binaryExpr: {
            AddBinaryExprToTree("Equals", "==", binaryExpr, parentItem);
            break;
        }

        case ESIR_NodeKind.BinaryExprNotEquals when node is ESIR_SimpleBinaryExpression binaryExpr: {
            AddBinaryExprToTree("Not equal", "!=", binaryExpr, parentItem);
            break;
        }

        case ESIR_NodeKind.BinaryExprBitAnd when node is ESIR_SimpleBinaryExpression binaryExpr: {
            AddBinaryExprToTree("AND", "&", binaryExpr, parentItem);
            break;
        }

        case ESIR_NodeKind.BinaryExprBitOr when node is ESIR_SimpleBinaryExpression binaryExpr: {
            AddBinaryExprToTree("OR", "|", binaryExpr, parentItem);
            break;
        }

        case ESIR_NodeKind.BinaryExprBitXor when node is ESIR_SimpleBinaryExpression binaryExpr: {
            AddBinaryExprToTree("XOR", "^", binaryExpr, parentItem);
            break;
        }

        case ESIR_NodeKind.BinaryExprLogicalAnd when node is ESIR_SimpleBinaryExpression binaryExpr: {
            AddBinaryExprToTree("Logical and", "&&", binaryExpr, parentItem);
            break;
        }

        case ESIR_NodeKind.BinaryExprLogicalOr when node is ESIR_SimpleBinaryExpression binaryExpr: {
            AddBinaryExprToTree("Logical or", "||", binaryExpr, parentItem);
            break;
        }

            #endregion

            #region Unary

        case ESIR_NodeKind.UnaryNegative when node is ESIR_UnaryExpression unaryExpr: {
            AddUnaryExprToTree("Negative", "-", unaryExpr, parentItem);
            break;
        }

        case ESIR_NodeKind.UnaryLogicalNot when node is ESIR_UnaryExpression unaryExpr: {
            AddUnaryExprToTree("Logical negation", "!", unaryExpr, parentItem);
            break;
        }

        case ESIR_NodeKind.UnaryBitNot when node is ESIR_UnaryExpression unaryExpr: {
            AddUnaryExprToTree("NOT", "~", unaryExpr, parentItem);
            break;
        }

        case ESIR_NodeKind.UnaryDereference when node is ESIR_UnaryExpression unaryExpr: {
            AddUnaryExprToTree("Dereference", "*", unaryExpr, parentItem);
            break;
        }

        case ESIR_NodeKind.UnaryPreIncrement when node is ESIR_UnaryExpression unaryExpr: {
            AddUnaryExprToTree("Pre-increment", "++", unaryExpr, parentItem, false);
            break;
        }

        case ESIR_NodeKind.UnaryPreDecrement when node is ESIR_UnaryExpression unaryExpr: {
            AddUnaryExprToTree("Pre-decrement", "--", unaryExpr, parentItem, false);
            break;
        }

        case ESIR_NodeKind.UnaryPostIncrement when node is ESIR_UnaryExpression unaryExpr: {
            AddUnaryExprToTree("Post-increment", "++", unaryExpr, parentItem, true);
            break;
        }

        case ESIR_NodeKind.UnaryPostDecrement when node is ESIR_UnaryExpression unaryExpr: {
            AddUnaryExprToTree("Post-decrement", "--", unaryExpr, parentItem, true);
            break;
        }

            #endregion

            #region Literals

        case ESIR_NodeKind.LiteralTrue:
            AddNodeToTree("True", parentItem);
            break;

        case ESIR_NodeKind.LiteralFalse:
            AddNodeToTree("False", parentItem);
            break;

        case ESIR_NodeKind.LiteralInt when node is ESIR_LiteralExpression litExpr:
            AddNodeToTree($"Int {litExpr.Value.GetInt ()}", parentItem);
            break;

        case ESIR_NodeKind.LiteralFloat when node is ESIR_LiteralExpression litExpr: {
            if (litExpr.Value.Kind == ESIR_NodeKind.ValueFloat32)
            {
                AddNodeToTree($"Float {litExpr.Value.GetFloat32 ()}", parentItem);
            }
            else
            {
                AddNodeToTree($"Float {litExpr.Value.GetFloat64 ()}", parentItem);
            }
            break;
        }

        case ESIR_NodeKind.LiteralChar when node is ESIR_LiteralExpression litExpr:
            AddNodeToTree($"Char {(char) litExpr.Value.GetInt ()}", parentItem);
            break;

        case ESIR_NodeKind.LiteralNull when node is ESIR_NullLiteralExpression nullExpr:
            AddNodeToTree($"Null {GetTypeName (nullExpr.Type)}", parentItem);
            break;

            #endregion

            #region Values

        case ESIR_NodeKind.StringConstant when node is ESIR_StringConstantExpression stringConstExpr: {
            AddNodeToTree($"String constant #{stringConstExpr.Index}", parentItem);
            break;
        }

        case ESIR_NodeKind.StaticVariableExpression when node is ESIR_StaticVariableExpression staticVarExpr: {
            AddNodeToTree($"Static var {GetString (staticVarExpr.Name)}", parentItem);
            break;
        }

        case ESIR_NodeKind.ArgumentExpression when node is ESIR_ArgumentExpression argExpr: {
            AddNodeToTree($"Arg #{argExpr.Index}", parentItem);
            break;
        }

        case ESIR_NodeKind.LocalValueExpression when node is ESIR_LocalValueExpression localExpr: {
            AddNodeToTree($"Local #{localExpr.Index}", parentItem);
            break;
        }

        case ESIR_NodeKind.DefaultValueExpression when node is ESIR_DefaultValueExpression defValExpr: {
            AddNodeToTree($"Defaults {GetTypeName (defValExpr.Type)}", parentItem);
            break;
        }

            #endregion

        case ESIR_NodeKind.MemberAccessExpression when node is ESIR_MemberAccessExpression accessExpr: {
            var nameStr    = GetString(accessExpr.Name);
            var accessItem = AddNodeToTree($"Member access: {GetNiceExpr (accessExpr.ExprParent)}.{nameStr}", parentItem);
            AddIRNodeToTree(accessExpr.ExprParent, accessItem);
            AddNodeToTree(nameStr, accessItem);

            break;
        }

        case ESIR_NodeKind.FunctionCallExpression when node is ESIR_FunctionCallExpression callExpr: {
            var funcName = GetString(callExpr.Name);
            var callItem = AddNodeToTree($"Function call {funcName}", parentItem);
            foreach (var arg in callExpr.Arguments.Elements)
            {
                AddIRNodeToTree(arg, callItem);
            }

            break;
        }

        case ESIR_NodeKind.IndexingExpression when node is ESIR_IndexingExpression indexExpr: {
            var sb = new StringBuilder();
            sb.Append("Index ");
            sb.Append(GetNiceExpr(indexExpr.IndexedExpr));

            sb.Append(" [");
            var firstDim = false;
            foreach (var index in indexExpr.Indices.Elements)
            {
                if (firstDim)
                {
                    firstDim = false;
                }
                else
                {
                    sb.Append(", ");
                }
                sb.Append(GetNiceExpr(index));
            }
            sb.Append(']');

            var indexItem = AddNodeToTree(sb.ToString(), parentItem);
            AddIRNodeToTree(indexExpr.IndexedExpr, indexItem);
            var dimsItem = AddNodeToTree("Dimensions", indexItem);

            foreach (var index in indexExpr.Indices.Elements)
            {
                AddIRNodeToTree(index, dimsItem);
            }

            break;
        }

        case ESIR_NodeKind.NewObjectExpression when node is ESIR_NewObjectExpression newObjExpr: {
            AddNodeToTree($"New {GetTypeName (newObjExpr.Type)}", parentItem);
            break;
        }

        case ESIR_NodeKind.NewArrayExpression when node is ESIR_NewArrayExpression newArrExpr: {
            var dimsCount = newArrExpr.Ranks.Elements.Length;
            var newItem   = AddNodeToTree($"New {GetTypeName (newArrExpr.ElementType)} [{new string (',', dimsCount - 1)}]", parentItem);

            foreach (var dim in newArrExpr.Ranks.Elements)
            {
                AddIRNodeToTree(dim, newItem);
            }

            break;
        }

        case ESIR_NodeKind.CastExpression when node is ESIR_CastExpression castExpr: {
            var castItem = AddNodeToTree($"Cast ({GetTypeName (castExpr.DestType)})", parentItem);
            AddIRNodeToTree(castExpr.Expression, castItem);

            break;
        }

        case ESIR_NodeKind.ConditionalExpression when node is ESIR_ConditionalExpression condExpr: {
            var niceCond      = GetNiceExpr(condExpr.Condition);
            var niceTrueExpr  = GetNiceExpr(condExpr.ThenExpression);
            var niceFalseExpr = GetNiceExpr(condExpr.ElseExpression);

            var condItem = AddNodeToTree($"Conditional: {niceCond} ? {niceTrueExpr} : {niceFalseExpr}", parentItem);
            AddIRNodeToTree(condExpr.Condition, condItem);
            AddIRNodeToTree(condExpr.ThenExpression, condItem);
            AddIRNodeToTree(condExpr.ElseExpression, condItem);

            break;
        }

        case ESIR_NodeKind.ExpressionList when node is ESIR_ExpressionList exprList: {
            var listItem = AddNodeToTree("Expression list", parentItem);
            foreach (var expr in exprList.Expressions.Elements)
            {
                AddIRNodeToTree(expr, listItem);
            }

            break;
        }

            #endregion

            #region Statements

        case ESIR_NodeKind.BlockStatement when node is ESIR_BlockStatement blockStmt: {
            var blockItem = AddNodeToTree("Block", parentItem);
            foreach (var stmt in blockStmt.Statements.Elements)
            {
                AddIRNodeToTree(stmt, blockItem);
            }

            break;
        }

        case ESIR_NodeKind.LabeledStatement when node is ESIR_LabeledStatement labelStmt: {
            AddNodeToTree($"Label {GetString (labelStmt.Label)}:", parentItem);
            AddIRNodeToTree(labelStmt.Statement, parentItem);
            break;
        }

        case ESIR_NodeKind.ConditionalStatement when node is ESIR_ConditionalStatement condStmt: {
            var ifItem   = AddNodeToTree($"If ({GetNiceExpr (condStmt.Condition)})", parentItem);
            var condItem = AddNodeToTree("Condition", ifItem);
            AddIRNodeToTree(condStmt.Condition, condItem);

            AddIRNodeToTree(condStmt.Then, ifItem);
            if (condStmt.Else is not null)
            {
                AddIRNodeToTree(condStmt.Else, ifItem);
            }

            break;
        }

        case ESIR_NodeKind.SwitchStatement:
            AddNodeToTree("Switch [NO NODE IMPLEMENTED]", parentItem);
            break;

        case ESIR_NodeKind.BreakStatement when node is ESIR_BreakStatement breakStmt: {
            if (breakStmt.Label is null)
            {
                AddNodeToTree("Break", parentItem);
                break;
            }

            AddNodeToTree($"Break {GetString (breakStmt.Label.Value)}", parentItem);
            break;
        }

        case ESIR_NodeKind.ContinueStatement when node is ESIR_ContinueStatement continueStmt: {
            if (continueStmt.Label is null)
            {
                AddNodeToTree("Continue", parentItem);
                break;
            }

            AddNodeToTree($"Continue {GetString (continueStmt.Label.Value)}", parentItem);
            break;
        }

        case ESIR_NodeKind.GotoLabelStatement when node is ESIR_GotoLabelStatement gotoStmt: {
            AddNodeToTree($"Goto {GetString (gotoStmt.Label)}", parentItem);
            break;
        }

        case ESIR_NodeKind.GotoCaseStatement when node is ESIR_GotoCaseStatement gotoCaseStmt: {
            var caseStr = gotoCaseStmt.CaseExpr is null ? "default" : $"case {GetNiceExpr (gotoCaseStmt.CaseExpr)}";
            AddNodeToTree($"Goto {caseStr}", parentItem);
            break;
        }

        case ESIR_NodeKind.ReturnStatement when node is ESIR_ReturnStatement retStmt: {
            if (retStmt.ReturnExpr is null)
            {
                AddNodeToTree("Return void", parentItem);
                break;
            }

            var retItem = AddNodeToTree($"Return {GetNiceExpr (retStmt.ReturnExpr)}", parentItem);
            AddIRNodeToTree(retStmt.ReturnExpr, retItem);
            break;
        }

        case ESIR_NodeKind.LoopStatement when node is ESIR_LoopStatement loopStmt: {
            var loopItem = AddNodeToTree("Loop", parentItem);

            var condExprs = loopStmt.ConditionExpr.Elements;
            if (condExprs.Length > 0)
            {
                foreach (var expr in condExprs[..^ 1])