public static string PrintAssignRdx(IADExpression left) { string result = string.Empty; result += ("movq %rdx, %rcx") + Environment.NewLine; if (left is ADExpression) { if ((left as ADExpression).Operator == TermType.dereference) { result += PrintExpression((left as ADExpression).Right, false, true); result += ("movq %rcx, (%rdx)") + Environment.NewLine; } } else if (left is ADVariable) { result += ($"movq %rcx, {(left as ADVariable).STRecord.Address}") + Environment.NewLine; } else if (left is ADArrayValue) { result += GetArrayValuePointer(left as ADArrayValue); result += "movq %rcx, (%rdx)" + Environment.NewLine; result += "movq (%rdx), %rdx" + Environment.NewLine; } return(result); }
public static void PrintExpression(IADExpression expression, string tab) { if (expression is ADConstant) { Console.WriteLine($"{tab}Constant: {((ADConstant)expression).Value}"); } if (expression is ADExpression) { var expr = expression as ADExpression; if (expr.Left != null) { PrintExpression(expr.Left, tab + '\t'); } Console.WriteLine($"{tab}\t{GetOperator(expr.Operator)}"); if (expr.Right != null) { PrintExpression(expr.Right, tab + '\t'); } } if (expression is ADArrayValue) { PrintArrayValue((ADArrayValue)expression, tab); } if (expression is ADSizeOfValue) { PrintSizeOf(tab); } if (expression is ADVariable) { PrintVariable((ADVariable)expression, tab); } if (expression is ADFunctionCall) { PrintFunctionCall((ADFunctionCall)expression, tab); } }
private static IADExpression GetExpression(STRecord stRecord) { IADExpression result = null; if (stRecord.Type == STType.constant) { result = new ADConstant { Value = stRecord.Value }; } else if (stRecord.Type == STType.variable || stRecord.Type == STType.array) { result = new ADVariable { Name = stRecord.Name, Type = ADVariable.VarType.variable, STRecord = stRecord }; } else if (stRecord.Type == STType.function) { MainFSM.Index--; result = ParserFunctions.fce_call(); } return(result); }
public static void PrintNode(IADNode node, string breakLabel = "", string continueLabel = "", string returnLabel = "", IADExpression forIncrement = null, string globalAssigns = "") { if (node is ADFunctionDeclaration) { Console.WriteLine($"# deklarace funkce {(node as ADFunctionDeclaration).Name}"); PrintFunctionDeclaration(node as ADFunctionDeclaration, globalAssigns); Console.WriteLine(); Console.WriteLine(); } else if (node is ADFunctionCall) { Console.WriteLine("# volani funkce"); Console.WriteLine(PrintFunctionCall(node as ADFunctionCall)); } else if (node is ADForLoop) { Console.WriteLine("# cykus for"); PrintForLoop(node as ADForLoop, returnLabel); } else if (node is ADWhileLoop) { Console.WriteLine("# cykus while"); PrintWhileLoop(node as ADWhileLoop, returnLabel); } else if (node is ADDoWhileLoop) { Console.WriteLine("# cykus do-while"); PrintDoWhileLoop(node as ADDoWhileLoop, returnLabel); } else if (node is ADStatementExpression) { Console.WriteLine(PrintExpression((node as ADStatementExpression).Expression)); } else if (node is ADCondition) { PrintCondition(node as ADCondition, breakLabel, continueLabel, returnLabel, forIncrement); } else if (node is ADBreak) { PrintBreak(breakLabel); } else if (node is ADContinue) { PrintContinue(continueLabel); } else if (node is ADInnerStatements) { foreach (var item in (node as ADInnerStatements).Statements) { PrintNode(item, breakLabel, continueLabel, returnLabel, forIncrement); } } else if (node is ADReturn) { Console.WriteLine(PrintExpression((node as ADReturn).Expression, false)); Console.WriteLine("movq %rdx, %rax"); Console.WriteLine($"jmp {returnLabel}"); } else if (node is ADArrayValue) { PrintArrayValue(node as ADArrayValue); } else if (node is ADVariableDeclarations) { foreach (var variable in (node as ADVariableDeclarations).Variables) { if (variable.Value != null && variable.Type != ADVariable.VarType.array) { Console.WriteLine($"# Prirazeni promenne {variable.Name}"); Console.WriteLine(PrintExpression(variable.Value)); Console.WriteLine($"movq %rdx, {variable.STRecord.Address}"); } } } }
public static string PrintExpression(IADExpression expression, bool recursive = false, bool dereference = false, string testFailsLabel = "", string testSuccessLabel = "") { string result = string.Empty; if (expression == null) { return(string.Empty); } if (expression is ADFunctionCall) { result += PrintFunctionCall(expression as ADFunctionCall); result += ("movq %rax, %rdx") + Environment.NewLine; result += ("pushq %rdx") + Environment.NewLine; } if (expression is ADSizeOfValue) { result += "movq $8, %rdx" + Environment.NewLine; result += "pushq %rdx" + Environment.NewLine; } if (expression is ADArrayValue) { result += PrintArrayValue(expression as ADArrayValue); result += ("pushq %rdx") + Environment.NewLine; } // PostOrder tree travelsal if (expression is ADExpression) { var expr = expression as ADExpression; if (expr.Operator == TermType.inc) { if (expr.Left == null) { result += ($"addq $1, {(expr.Right as ADVariable).STRecord.Address}") + Environment.NewLine; result += ($"pushq {(expr.Right as ADVariable).STRecord.Address}") + Environment.NewLine; } else if (expr.Right == null) { result += ($"pushq {(expr.Left as ADVariable).STRecord.Address}") + Environment.NewLine; result += ($"addq $1, {(expr.Left as ADVariable).STRecord.Address}") + Environment.NewLine; } } else if (expr.Operator == TermType.dec) { if (expr.Left == null) { result += ($"subq $1, {(expr.Right as ADVariable).STRecord.Address}") + Environment.NewLine; result += ($"pushq {(expr.Right as ADVariable).STRecord.Address}") + Environment.NewLine; } else if (expr.Right == null) { result += ($"pushq {(expr.Left as ADVariable).STRecord.Address}") + Environment.NewLine; result += ($"subq $1, {(expr.Left as ADVariable).STRecord.Address}") + Environment.NewLine; } } else if (expr.Operator == TermType.reference) { if ((expr.Right as ADVariable).STRecord.Access == Parser.SymbolTable.STAccess.global) { if ((expr.Right as ADVariable).STRecord.Type == Parser.SymbolTable.STType.function) { result += $"movabs ${(expr.Right as ADVariable).Name}, %rdx" + Environment.NewLine; } else { result += $"movq ${(expr.Right as ADVariable).STRecord.Address}, %rdx" + Environment.NewLine; } } else { result += ($"leaq {(expr.Right as ADVariable).STRecord.Address}, %rdx") + Environment.NewLine; } result += ("pushq %rdx") + Environment.NewLine; } else if (expr.Operator == TermType.dereference) { result += PrintExpression(expr.Right, true, true); result += ("popq %rdx") + Environment.NewLine; result += ("movq (%rdx), %rcx") + Environment.NewLine; result += ("movq %rcx, %rdx") + Environment.NewLine; result += ("pushq %rdx") + Environment.NewLine; } else if (expr.Operator == TermType.asgn) { result += $"# Prirazeni promenne" + Environment.NewLine; result += PrintExpression(expr.Right, false); result += PrintAssignRdx(expr.Left); recursive = true; } else if (expr.Operator == TermType.not) { result += PrintExpression(expr.Right, false); var label = GenerateLabel(); var endLabel = GenerateLabel(); result += ("cmp $0, %rdx") + Environment.NewLine; result += ($"je {label}") + Environment.NewLine; result += ("movq $0, %rdx") + Environment.NewLine; result += ($"jmp {endLabel}") + Environment.NewLine; result += ($"{label}:") + Environment.NewLine; result += ("movq $1, %rdx") + Environment.NewLine; result += ($"{endLabel}:") + Environment.NewLine; result += ("pushq %rdx") + Environment.NewLine; } else if (expr.Left == null && expr.Operator == TermType.minus) { result += PrintExpression(expr.Right); result += ("negq %rdx") + Environment.NewLine; result += ("pushq %rdx") + Environment.NewLine; } else if (expr.Operator == TermType.cCond) { result += ("# Tercialni operator") + Environment.NewLine; result += PrintExpression(expr.Left); var nextExpr = expr.Right as ADExpression; var elseLabel = GenerateLabel(); var endCondLabel = GenerateLabel(); result += ("cmp $0, %rdx") + Environment.NewLine; result += ($"je {elseLabel}") + Environment.NewLine; result += PrintExpression(nextExpr.Left); result += ($"jmp {endCondLabel}") + Environment.NewLine; result += ($"{elseLabel}:") + Environment.NewLine; result += PrintExpression(nextExpr.Right); result += ($"{endCondLabel}:") + Environment.NewLine; result += ("pushq %rdx") + Environment.NewLine; } else if (expr.Operator == TermType.logAnd && testFailsLabel != "") { result += PrintExpression(expr.Left, true); result += "cmp $0, %rdx" + Environment.NewLine; result += $"je {testFailsLabel}" + Environment.NewLine; result += PrintExpression(expr.Right, true); result += PrintOperation(expr); } else { result += PrintExpression(expr.Left, true); result += PrintExpression(expr.Right, true); result += PrintOperation(expr, dereference); } } if (expression is ADConstant) { result += ($"pushq ${(expression as ADConstant).Value}") + Environment.NewLine; } if (expression is ADVariable) { var variable = expression as ADVariable; result += ($"# promenna {variable.Name}") + Environment.NewLine; result += ($"pushq {variable.STRecord.Address}") + Environment.NewLine; } if (!recursive) { result += ("popq %rdx") + Environment.NewLine; } return(result); }
public static void PrintCondition(ADCondition condition, string breakLabel = "", string continueLabel = "", string returnLabel = "", IADExpression forIncrement = null) { var endLabel = GenerateLabel(); var elseLabel = GenerateLabel(); var bodyLabel = GenerateLabel(); if (condition.ElseBody != null) { Console.WriteLine(PrintExpression(condition.Condition, false, false, elseLabel, bodyLabel)); EvalCondition(elseLabel); } else { Console.WriteLine(PrintExpression(condition.Condition, false, false, endLabel, bodyLabel)); EvalCondition(endLabel); } Console.WriteLine($"{bodyLabel}:"); foreach (var item in condition.IfBody) { if (item is ADContinue && forIncrement != null) { Console.WriteLine(PrintExpression(forIncrement)); } PrintNode(item, breakLabel, continueLabel, returnLabel); } Console.WriteLine($"jmp {endLabel}"); if (condition.ElseBody != null) { Console.WriteLine($"{elseLabel}:"); foreach (var item in condition.ElseBody) { if (item is ADBreak) { PrintBreak(breakLabel); } else { PrintNode(item, breakLabel, continueLabel, returnLabel); } } } Console.WriteLine($"{endLabel}:"); }