private static ExpressionData CompileExpression( ref PassData passData, ref FunctionData funcData, ESIR_Expression expr ) { if (expr is ESIR_SimpleBinaryExpression simpleBinaryExpr) { return(CompileExpression_SimpleBinary(ref passData, ref funcData, simpleBinaryExpr)); } else if (expr is ESIR_UnaryExpression unaryExpr) { return(CompileExpression_Unary(ref passData, ref funcData, unaryExpr)); } switch (expr.Kind) { case ESIR_NodeKind.ErrorExpression: throw new CompilationException(ES_BackendErrors.FrontendError); case ESIR_NodeKind.AssignExpression when expr is ESIR_AssignExpression assignExpr: { var assigneeExpr = CompileExpression(ref passData, ref funcData, assignExpr.Assignee); var valueExpr = CompileExpression(ref passData, ref funcData, assignExpr.Value); Debug.Assert(assigneeExpr.Type == valueExpr.Type); var value = AssignmentExpression( SyntaxKind.SimpleAssignmentExpression, assigneeExpr.Value !, valueExpr.Value ! ); return(new ExpressionData { Type = assigneeExpr.Type, Value = value, }); } #region Literals case ESIR_NodeKind.LiteralTrue: case ESIR_NodeKind.LiteralFalse: return(new ExpressionData { Type = passData.Env.TypeBool, Value = BoolLiteral(expr.Kind == ESIR_NodeKind.LiteralTrue), }); case ESIR_NodeKind.LiteralInt when expr is ESIR_LiteralExpression litIntExpr: { bool unsigned; ExpressionSyntax value; if (litIntExpr.Value !.TryGetInt(out var longVal)) { value = NumericLiteral(longVal); unsigned = false; }
public static ESIR_ConditionalStatement ConditionalStatement(ESIR_Expression condition, ESIR_Statement thenStmt, ESIR_Statement?elseStmt) { var node = ESIR_NodeCache.Shared.TryGetNode(ESIR_NodeKind.ConditionalStatement, condition, thenStmt, elseStmt, out var hash); if (node is not null) { return((ESIR_ConditionalStatement)node); } var ret = new ESIR_ConditionalStatement(condition, thenStmt, elseStmt); if (hash >= 0) { ESIR_NodeCache.Shared.AddNode(ret, hash); } return(ret); }
private static ESIR_MemberAccessExpression MemberAccessExpression(ESIR_Expression parent, ESIR_ValueNode name) { var node = ESIR_NodeCache.Shared.TryGetNode(ESIR_NodeKind.MemberAccessExpression, parent, name, out var hash); if (node is not null) { return((ESIR_MemberAccessExpression)node); } var ret = new ESIR_MemberAccessExpression(parent, name); if (hash >= 0) { ESIR_NodeCache.Shared.AddNode(ret, hash); } return(ret); }
public static ESIR_IndexingExpression IndexingExpression(ESIR_Expression indexedExpr, ESIR_List <ESIR_Expression> ranks) { var node = ESIR_NodeCache.Shared.TryGetNode(ESIR_NodeKind.IndexingExpression, indexedExpr, ranks, out var hash); if (node is not null) { return((ESIR_IndexingExpression)node); } var ret = new ESIR_IndexingExpression(indexedExpr, ranks); if (hash >= 0) { ESIR_NodeCache.Shared.AddNode(ret, hash); } return(ret); }
public static ESIR_CastExpression CastExpression(ESIR_Expression expression, ESIR_TypeNode destType) { var node = ESIR_NodeCache.Shared.TryGetNode(ESIR_NodeKind.CastExpression, expression, destType, out var hash); if (node is not null) { return((ESIR_CastExpression)node); } var ret = new ESIR_CastExpression(expression, destType); if (hash >= 0) { ESIR_NodeCache.Shared.AddNode(ret, hash); } return(ret); }
public static ESIR_ConditionalExpression ConditionalExpression(ESIR_Expression condition, ESIR_Expression left, ESIR_Expression right) { var node = ESIR_NodeCache.Shared.TryGetNode(ESIR_NodeKind.ConditionalExpression, condition, left, right, out var hash); if (node is not null) { return((ESIR_ConditionalExpression)node); } var ret = new ESIR_ConditionalExpression(condition, left, right); if (hash >= 0) { ESIR_NodeCache.Shared.AddNode(ret, hash); } return(ret); }
public static ESIR_ExpressionStatement ExpressionStatement(ESIR_Expression expr) { var node = ESIR_NodeCache.Shared.TryGetNode(ESIR_NodeKind.ExpressionStatement, expr, out var hash); if (node is not null) { return((ESIR_ExpressionStatement)node); } var ret = new ESIR_ExpressionStatement(expr); if (hash >= 0) { ESIR_NodeCache.Shared.AddNode(ret, hash); } return(ret); }
private static ESIR_ArgumentValue ArgumentValue(ESIR_ValueNode argType, ESIR_Expression expression) { var node = ESIR_NodeCache.Shared.TryGetNode(ESIR_NodeKind.ArgumentValue, argType, expression, out var hash); if (node is not null) { return((ESIR_ArgumentValue)node); } var ret = new ESIR_ArgumentValue(argType, expression); if (hash >= 0) { ESIR_NodeCache.Shared.AddNode(ret, hash); } return(ret); }
public static ESIR_AssignExpression AssignmentExpression(ESIR_Expression assignee, ESIR_Expression value) { var node = ESIR_NodeCache.Shared.TryGetNode(ESIR_NodeKind.AssignExpression, assignee, value, out var hash); if (node is not null) { return((ESIR_AssignExpression)node); } var ret = new ESIR_AssignExpression(assignee, value); if (hash >= 0) { ESIR_NodeCache.Shared.AddNode(ret, hash); } return(ret); }
public static ESIR_UnaryExpression UnaryExpression(ESIR_NodeKind kind, ESIR_Expression inner) { if (kind < ESIR_NodeKind.UnaryNegative || kind > ESIR_NodeKind.UnaryPostDecrement) { throw new ArgumentOutOfRangeException(nameof(kind), "Kind is not an unary expression."); } var node = ESIR_NodeCache.Shared.TryGetNode(kind, inner, out var hash); if (node is not null) { return((ESIR_UnaryExpression)node); } var ret = new ESIR_UnaryExpression(kind, inner); if (hash >= 0) { ESIR_NodeCache.Shared.AddNode(ret, hash); } return(ret); }
public static ESIR_GotoCaseStatement GotoCaseStatement(ESIR_Expression caseExpr) => GotoCaseStatementInternal(caseExpr);
private string GetExprLabel(ESIR_Expression node) { Debug.Assert(node is not null); if (node is null) { return("[EXPR NODE NULL]"); } switch (node.Kind) { case ESIR_NodeKind.ErrorExpression: return("[ERROR]"); case ESIR_NodeKind.AssignExpression: return("[Assign]"); #region Binary case ESIR_NodeKind.BinaryExprConcat: return("[Concat]"); case ESIR_NodeKind.BinaryExprPower: return("[Exponentiate]"); case ESIR_NodeKind.BinaryExprMultiply: return("[Multiply]"); case ESIR_NodeKind.BinaryExprDivide: return("[Divide]"); case ESIR_NodeKind.BinaryExprModulo: return("[Modulo]"); case ESIR_NodeKind.BinaryExprAdd: return("[Add]"); case ESIR_NodeKind.BinaryExprSubtract: return("[Subtract]"); case ESIR_NodeKind.BinaryExprShiftLeft: return("[Shift left]"); case ESIR_NodeKind.BinaryExprShiftRight: return("[Shift right]"); case ESIR_NodeKind.BinaryExprShiftRightUnsigned: return("[Unsigned shift right]"); case ESIR_NodeKind.BinaryExprLesserThan: return("[Lesser than]"); case ESIR_NodeKind.BinaryExprGreaterThan: return("[Greater than]"); case ESIR_NodeKind.BinaryExprLesserThanEqual: return("[Lesser than-equals]"); case ESIR_NodeKind.BinaryExprGreaterThanEqual: return("[Greater than-equals]"); case ESIR_NodeKind.BinaryExprEquals: return("[Equals]"); case ESIR_NodeKind.BinaryExprNotEquals: return("[Not equal]"); case ESIR_NodeKind.BinaryExprBitAnd: return("[AND]"); case ESIR_NodeKind.BinaryExprBitOr: return("[OR]"); case ESIR_NodeKind.BinaryExprBitXor: return("[XOR]"); case ESIR_NodeKind.BinaryExprLogicalAnd: return("[Logical AND]"); case ESIR_NodeKind.BinaryExprLogicalOr: return("[Logical OR]"); #endregion #region Unary case ESIR_NodeKind.UnaryNegative: return("[Negative]"); case ESIR_NodeKind.UnaryLogicalNot: return("[Logical negation]"); case ESIR_NodeKind.UnaryBitNot: return("[NOT]"); case ESIR_NodeKind.UnaryDereference: return("[Dereference]"); case ESIR_NodeKind.UnaryPreIncrement: return($"[Pre-increment]"); case ESIR_NodeKind.UnaryPreDecrement: return($"[Pre-decrement]"); case ESIR_NodeKind.UnaryPostIncrement: return($"[Post-increment]"); case ESIR_NodeKind.UnaryPostDecrement: return($"[Post-decrement]"); #endregion #region Literals case ESIR_NodeKind.LiteralTrue: case ESIR_NodeKind.LiteralFalse: case ESIR_NodeKind.LiteralInt: case ESIR_NodeKind.LiteralFloat: case ESIR_NodeKind.LiteralChar: case ESIR_NodeKind.LiteralNull: return(GetNiceExpr(node)); #endregion #region Values case ESIR_NodeKind.StringConstant: case ESIR_NodeKind.StaticVariableExpression: case ESIR_NodeKind.ArgumentExpression: case ESIR_NodeKind.LocalValueExpression: return(GetNiceExpr(node)); case ESIR_NodeKind.DefaultValueExpression: return("[default]"); #endregion case ESIR_NodeKind.MemberAccessExpression: return("[Member access]"); case ESIR_NodeKind.FunctionCallExpression: return("[Function call]"); case ESIR_NodeKind.VirtualCallExpression: return("[Virtual call]"); case ESIR_NodeKind.IndexingExpression: return("[Indexing]"); case ESIR_NodeKind.NewObjectExpression: return("[New obj]"); case ESIR_NodeKind.NewArrayExpression: return("[New array]"); case ESIR_NodeKind.CastExpression: return("[Cast]"); case ESIR_NodeKind.ConditionalExpression: return("[Conditional]"); case ESIR_NodeKind.ExpressionList: return("[ExpressionList]"); default: Debug.Fail("IR node invalid or not implemented."); return("[invalid]"); } }
public static TCSymbol NewVariable(TypeData type, ESIR_Expression expr, SymbolFlags flags = 0) => new (new (type, expr), flags);
internal TCVariable(TypeData type, ESIR_Expression irExpr) { Type = type; IRExpression = irExpr; }
internal ESIR_UnaryExpression(ESIR_NodeKind op, ESIR_Expression inner) { kind = op; innerNode = inner; }
internal ESIR_ConditionalStatement(ESIR_Expression condition, ESIR_Statement thenStmt, ESIR_Statement?elseStmt) { conditionNode = condition; thenNode = thenStmt; elseNode = elseStmt; }
internal ESIR_SimpleBinaryExpression(ESIR_NodeKind op, ESIR_Expression left, ESIR_Expression right) { kind = op; leftNode = left; rightNode = right; }
internal ESIR_IndexingExpression(ESIR_Expression indexed, ESIR_List <ESIR_Expression> indices) { indexedNode = indexed; indicesNode = indices; }
public static ESIR_MemberAccessExpression MemberAccessExpression(ESIR_Expression parent, ArrayPointer <byte> name) => MemberAccessExpression(parent, ValueNode(name));
internal ESIR_CastExpression(ESIR_Expression expr, ESIR_TypeNode elemType) { destTypeNode = elemType; exprNode = expr; }
internal ESIR_ConditionalExpression(ESIR_Expression condition, ESIR_Expression thenExpr, ESIR_Expression elseExpr) { conditionNode = condition; thenNode = thenExpr; elseNode = elseExpr; }
private string GetNiceExpr(ESIR_Expression node) { Debug.Assert(node is not null); if (node is null) { return("[EXPR NODE NULL]"); } switch (node.Kind) { case ESIR_NodeKind.ErrorExpression: return("[ERROR]"); case ESIR_NodeKind.AssignExpression when node is ESIR_AssignExpression assignExpr: return($"{GetExprLabel (assignExpr.Assignee)} = {GetExprLabel (assignExpr.Value)}"); #region Binary case ESIR_NodeKind.BinaryExprConcat when node is ESIR_SimpleBinaryExpression binaryExpr: return($"{GetExprLabel (binaryExpr.ExprLeft)} .. {GetExprLabel (binaryExpr.ExprRight)}"); case ESIR_NodeKind.BinaryExprPower when node is ESIR_SimpleBinaryExpression binaryExpr: return($"{GetExprLabel (binaryExpr.ExprLeft)} ** {GetExprLabel (binaryExpr.ExprRight)}"); case ESIR_NodeKind.BinaryExprMultiply when node is ESIR_SimpleBinaryExpression binaryExpr: return($"{GetExprLabel (binaryExpr.ExprLeft)} * {GetExprLabel (binaryExpr.ExprRight)}"); case ESIR_NodeKind.BinaryExprDivide when node is ESIR_SimpleBinaryExpression binaryExpr: return($"{GetExprLabel (binaryExpr.ExprLeft)} / {GetExprLabel (binaryExpr.ExprRight)}"); case ESIR_NodeKind.BinaryExprModulo when node is ESIR_SimpleBinaryExpression binaryExpr: return($"{GetExprLabel (binaryExpr.ExprLeft)} % {GetExprLabel (binaryExpr.ExprRight)}"); case ESIR_NodeKind.BinaryExprAdd when node is ESIR_SimpleBinaryExpression binaryExpr: return($"{GetExprLabel (binaryExpr.ExprLeft)} + {GetExprLabel (binaryExpr.ExprRight)}"); case ESIR_NodeKind.BinaryExprSubtract when node is ESIR_SimpleBinaryExpression binaryExpr: return($"{GetExprLabel (binaryExpr.ExprLeft)} - {GetExprLabel (binaryExpr.ExprRight)}"); case ESIR_NodeKind.BinaryExprShiftLeft when node is ESIR_SimpleBinaryExpression binaryExpr: return($"{GetExprLabel (binaryExpr.ExprLeft)} << {GetExprLabel (binaryExpr.ExprRight)}"); case ESIR_NodeKind.BinaryExprShiftRight when node is ESIR_SimpleBinaryExpression binaryExpr: return($"{GetExprLabel (binaryExpr.ExprLeft)} >> {GetExprLabel (binaryExpr.ExprRight)}"); case ESIR_NodeKind.BinaryExprShiftRightUnsigned when node is ESIR_SimpleBinaryExpression binaryExpr: return($"{GetExprLabel (binaryExpr.ExprLeft)} >>> {GetExprLabel (binaryExpr.ExprRight)}"); case ESIR_NodeKind.BinaryExprLesserThan when node is ESIR_SimpleBinaryExpression binaryExpr: return($"{GetExprLabel (binaryExpr.ExprLeft)} < {GetExprLabel (binaryExpr.ExprRight)}"); case ESIR_NodeKind.BinaryExprGreaterThan when node is ESIR_SimpleBinaryExpression binaryExpr: return($"{GetExprLabel (binaryExpr.ExprLeft)} > {GetExprLabel (binaryExpr.ExprRight)}"); case ESIR_NodeKind.BinaryExprLesserThanEqual when node is ESIR_SimpleBinaryExpression binaryExpr: return($"{GetExprLabel (binaryExpr.ExprLeft)} <= {GetExprLabel (binaryExpr.ExprRight)}"); case ESIR_NodeKind.BinaryExprGreaterThanEqual when node is ESIR_SimpleBinaryExpression binaryExpr: return($"{GetExprLabel (binaryExpr.ExprLeft)} >= {GetExprLabel (binaryExpr.ExprRight)}"); case ESIR_NodeKind.BinaryExprEquals when node is ESIR_SimpleBinaryExpression binaryExpr: return($"{GetExprLabel (binaryExpr.ExprLeft)} == {GetExprLabel (binaryExpr.ExprRight)}"); case ESIR_NodeKind.BinaryExprNotEquals when node is ESIR_SimpleBinaryExpression binaryExpr: return($"{GetExprLabel (binaryExpr.ExprLeft)} != {GetExprLabel (binaryExpr.ExprRight)}"); case ESIR_NodeKind.BinaryExprBitAnd when node is ESIR_SimpleBinaryExpression binaryExpr: return($"{GetExprLabel (binaryExpr.ExprLeft)} & {GetExprLabel (binaryExpr.ExprRight)}"); case ESIR_NodeKind.BinaryExprBitOr when node is ESIR_SimpleBinaryExpression binaryExpr: return($"{GetExprLabel (binaryExpr.ExprLeft)} | {GetExprLabel (binaryExpr.ExprRight)}"); case ESIR_NodeKind.BinaryExprBitXor when node is ESIR_SimpleBinaryExpression binaryExpr: return($"{GetExprLabel (binaryExpr.ExprLeft)} ^ {GetExprLabel (binaryExpr.ExprRight)}"); case ESIR_NodeKind.BinaryExprLogicalAnd when node is ESIR_SimpleBinaryExpression binaryExpr: return($"{GetExprLabel (binaryExpr.ExprLeft)} && {GetExprLabel (binaryExpr.ExprRight)}"); case ESIR_NodeKind.BinaryExprLogicalOr when node is ESIR_SimpleBinaryExpression binaryExpr: return($"{GetExprLabel (binaryExpr.ExprLeft)} || {GetExprLabel (binaryExpr.ExprRight)}"); #endregion #region Unary case ESIR_NodeKind.UnaryNegative when node is ESIR_UnaryExpression unaryExpr: return($"-{GetExprLabel (unaryExpr.ExprInner)}"); case ESIR_NodeKind.UnaryLogicalNot when node is ESIR_UnaryExpression unaryExpr: return($"!{GetExprLabel (unaryExpr.ExprInner)}"); case ESIR_NodeKind.UnaryBitNot when node is ESIR_UnaryExpression unaryExpr: return($"~{GetExprLabel (unaryExpr.ExprInner)}"); case ESIR_NodeKind.UnaryDereference when node is ESIR_UnaryExpression unaryExpr: return($"*{GetExprLabel (unaryExpr.ExprInner)}"); case ESIR_NodeKind.UnaryPreIncrement when node is ESIR_UnaryExpression unaryExpr: return($"++{GetExprLabel (unaryExpr.ExprInner)}"); case ESIR_NodeKind.UnaryPreDecrement when node is ESIR_UnaryExpression unaryExpr: return($"--{GetExprLabel (unaryExpr.ExprInner)}"); case ESIR_NodeKind.UnaryPostIncrement when node is ESIR_UnaryExpression unaryExpr: return($"{GetExprLabel (unaryExpr.ExprInner)}++"); case ESIR_NodeKind.UnaryPostDecrement when node is ESIR_UnaryExpression unaryExpr: return($"{GetExprLabel (unaryExpr.ExprInner)}--"); #endregion #region Literals case ESIR_NodeKind.LiteralTrue: return("True"); case ESIR_NodeKind.LiteralFalse: return("False"); case ESIR_NodeKind.LiteralInt when node is ESIR_LiteralExpression litExpr: return(litExpr.Value.Kind == ESIR_NodeKind.ValueUInt ? $"{litExpr.Value.GetUInt ()}u" : $"{litExpr.Value.GetInt ()}i"); case ESIR_NodeKind.LiteralFloat when node is ESIR_LiteralExpression litExpr: return(litExpr.Value.Kind == ESIR_NodeKind.ValueFloat32 ? $"{litExpr.Value.GetFloat32 ()}f32" : $"{litExpr.Value.GetFloat64 ()}f64"); case ESIR_NodeKind.LiteralChar when node is ESIR_LiteralExpression litExpr: return($"'{(char) litExpr.Value.GetInt ()}'"); case ESIR_NodeKind.LiteralNull when node is ESIR_NullLiteralExpression: return("[null]"); #endregion #region Values case ESIR_NodeKind.StringConstant when node is ESIR_StringConstantExpression stringConstExpr: return($"str{stringConstExpr.Index}"); case ESIR_NodeKind.StaticVariableExpression when node is ESIR_StaticVariableExpression staticVarExpr: return($"[SVar {GetString (staticVarExpr.Name)}]"); case ESIR_NodeKind.ArgumentExpression when node is ESIR_ArgumentExpression argExpr: return($"arg{argExpr.Index}"); case ESIR_NodeKind.LocalValueExpression when node is ESIR_LocalValueExpression localExpr: return($"local{localExpr.Index}"); case ESIR_NodeKind.DefaultValueExpression when node is ESIR_DefaultValueExpression: return("[default]"); #endregion case ESIR_NodeKind.MemberAccessExpression when node is ESIR_MemberAccessExpression accessExpr: return($"{GetExprLabel (accessExpr.ExprParent)}.{GetString (accessExpr.Name)}"); case ESIR_NodeKind.FunctionCallExpression when node is ESIR_FunctionCallExpression callExpr: return($"{GetString (callExpr.Name)}{(callExpr.Arguments.Elements.Length > 0 ? " ([...])" : "")}"); case ESIR_NodeKind.IndexingExpression when node is ESIR_IndexingExpression indexExpr: return($"{GetExprLabel (indexExpr.IndexedExpr)} [{new string (',', indexExpr.Indices.Elements.Length - 1)}]"); case ESIR_NodeKind.NewObjectExpression when node is ESIR_NewObjectExpression newObjExpr: return($"new ({GetTypeName (newObjExpr.Type)})"); case ESIR_NodeKind.NewArrayExpression when node is ESIR_NewArrayExpression newArrExpr: return($"array ({GetTypeName (newArrExpr.ElementType)} [{new string (',', newArrExpr.Ranks.Elements.Length - 1)}])"); case ESIR_NodeKind.CastExpression when node is ESIR_CastExpression castExpr: return($"cast ({GetExprLabel (castExpr.Expression)} -> {GetTypeName (castExpr.DestType)})"); case ESIR_NodeKind.ConditionalExpression when node is ESIR_ConditionalExpression condExpr: return($"{GetExprLabel (condExpr.Condition)} ? {GetExprLabel (condExpr.ThenExpression)} : {GetExprLabel (condExpr.ElseExpression)}"); case ESIR_NodeKind.ExpressionList when node is ESIR_ExpressionList exprList: if (exprList.Expressions.Elements.Length == 1) { return(GetNiceExpr(exprList.Expressions.Elements [0])); } else { return("[ExpressionList]"); } default: Debug.Fail("IR node invalid or not implemented."); return("[invalid]"); } }
public static ESIR_SimpleBinaryExpression SimpleBinaryExpression(ESIR_NodeKind kind, ESIR_Expression left, ESIR_Expression right) { if (kind < ESIR_NodeKind.BinaryExprConcat || kind > ESIR_NodeKind.BinaryExprLogicalOr) { throw new ArgumentOutOfRangeException(nameof(kind), "Kind is not a simple binary expression."); } var node = ESIR_NodeCache.Shared.TryGetNode(kind, left, right, out var hash); if (node is not null) { return((ESIR_SimpleBinaryExpression)node); } var ret = new ESIR_SimpleBinaryExpression(kind, left, right); if (hash >= 0) { ESIR_NodeCache.Shared.AddNode(ret, hash); } return(ret); }
private void AddExprStmtToTree(ESIR_Expression expr, TreeViewItem parentItem) { var exprItem = AddNodeToTree($"Expression {GetNiceExpr (expr)}", parentItem); AddIRNodeToTree(expr, exprItem); }
internal ESIR_AssignExpression(ESIR_Expression assignee, ESIR_Expression value) { assigneeNode = assignee; valueNode = value; }
public static ESIR_ArgumentValue ArgumentValue(ES_ArgumentType argType, ESIR_Expression expression) => ArgumentValue(ValueNode((int)argType), expression);
internal ESIR_ExpressionStatement(ESIR_Expression label) => exprNode = label;