public static void Reduce(ref Stack <Term> SS, ref Stack <Term> ST) { var rightOperand = ST.Pop(); var operatorTerm = SS.Pop(); Term leftOperand = null; if (ST.Count > 0 && (operatorTerm.Type != TermType.dec && operatorTerm.Type != TermType.inc && operatorTerm.Type != TermType.compl && operatorTerm.Type != TermType.reference && operatorTerm.Type != TermType.dereference && operatorTerm.Type != TermType.not)) { leftOperand = ST.Pop(); } ADExpression expression = new ADExpression(); if (rightOperand.Expression != null) { expression.Right = rightOperand.Expression; } else { expression.Right = GetExpression(rightOperand.STRecord); } expression.Operator = operatorTerm.Type; if (leftOperand != null) { if (leftOperand.Expression != null) { expression.Left = leftOperand.Expression; } else { expression.Left = GetExpression(leftOperand.STRecord); } } if (expression.Operator == TermType.asgn) { if (leftOperand.STRecord.Type != STType.variable && leftOperand.STRecord.Type != STType.array) { ParserFunctions.SyntaxError("Na leve strane operace prirazeni musi byt promenna."); } } ST.Push(new Term() { Type = TermType.id, Expression = expression }); }
public static string PrintOperation(ADExpression expression, bool dereference = false) { string result = string.Empty; if (expression.Right != null) { result += ("popq %rsi") + Environment.NewLine; } if (expression.Left != null) { result += ("popq %rdx") + Environment.NewLine; } switch (expression.Operator) { case TermType.plus: if (expression.Left is ADVariable && (expression.Left as ADVariable).STRecord.Type == Parser.SymbolTable.STType.array && !dereference) { result += "#Nasobim index 8 kvuli poli" + Environment.NewLine; result += "pushq %rdx" + Environment.NewLine; result += "movq %rsi, %rax" + Environment.NewLine; result += "movq $8, %rcx" + Environment.NewLine; result += "mulq %rcx" + Environment.NewLine; result += "movq %rax, %rsi" + Environment.NewLine; result += "popq %rdx" + Environment.NewLine; } result += ("addq %rsi, %rdx") + Environment.NewLine; break; case TermType.compl: result += "notq %rsi" + Environment.NewLine; result += "movq %rsi, %rdx" + Environment.NewLine; break; case TermType.minus: result += ("subq %rsi, %rdx") + Environment.NewLine; break; case TermType.binAnd: result += ("andq %rsi, %rdx") + Environment.NewLine; break; case TermType.mul: result += ("movq %rsi, %rax") + Environment.NewLine; result += ("mulq %rdx") + Environment.NewLine; result += ("movq %rax, %rdx") + Environment.NewLine; break; case TermType.div: result += "movq %rdx, %rcx" + Environment.NewLine; result += "xorq %rdx, %rdx" + Environment.NewLine; result += "movq %rcx, %rax" + Environment.NewLine; result += "divq %rsi" + Environment.NewLine; result += "movq %rax, %rdx" + Environment.NewLine; break; case TermType.left: result += ("mov %sil, %cl") + Environment.NewLine; result += ("shlq %cl, %rdx") + Environment.NewLine; break; case TermType.right: result += ("mov %sil, %cl") + Environment.NewLine; result += ("shrq %cl, %rdx") + Environment.NewLine; break; case TermType.binOr: result += ("orq %rsi, %rdx") + Environment.NewLine; break; case TermType.rightEq: result += PrintExpression(new ADExpression { Left = expression.Left, Operator = TermType.right, Right = expression.Right }); result += PrintAssignRdx(expression.Left); break; case TermType.mod: result += "movq %rdx, %rcx" + Environment.NewLine; result += "xorq %rdx, %rdx" + Environment.NewLine; result += "movq %rcx, %rax" + Environment.NewLine; result += "divq %rsi" + Environment.NewLine; break; case TermType.modEq: result += PrintExpression(new ADExpression { Left = expression.Left, Operator = TermType.mod, Right = expression.Right }); result += PrintAssignRdx(expression.Left); break; case TermType.leftEq: result += PrintExpression(new ADExpression { Left = expression.Left, Operator = TermType.left, Right = expression.Right }); result += PrintAssignRdx(expression.Left); break; case TermType.reference: result += ($"leaq {(expression.Right as ADVariable).STRecord.Address}, %rdx") + Environment.NewLine; break; case TermType.dereference: result += ("popq %rdx") + Environment.NewLine; result += ("movq (%rdx), %rcx") + Environment.NewLine; result += ("movq %rcx, %rdx") + Environment.NewLine; break; case TermType.less: result += ("cmpq %rsi, %rdx") + Environment.NewLine; result += ("setl %cl") + Environment.NewLine; result += ("xorq %rdx, %rdx") + Environment.NewLine; result += ("mov %cl, %dl") + Environment.NewLine; break; case TermType.lessEq: result += ("cmpq %rsi, %rdx") + Environment.NewLine; result += ("setle %cl") + Environment.NewLine; result += ("xorq %rdx, %rdx") + Environment.NewLine; result += ("mov %cl, %dl") + Environment.NewLine; break; case TermType.grt: result += ("cmpq %rsi, %rdx") + Environment.NewLine; result += ("setg %cl") + Environment.NewLine; result += ("xorq %rdx, %rdx") + Environment.NewLine; result += ("mov %cl, %dl") + Environment.NewLine; break; case TermType.grtEq: result += ("cmpq %rsi, %rdx") + Environment.NewLine; result += ("setge %cl") + Environment.NewLine; result += ("xorq %rdx, %rdx") + Environment.NewLine; result += ("mov %cl, %dl") + Environment.NewLine; break; case TermType.eq: result += ("cmpq %rsi, %rdx") + Environment.NewLine; result += ("sete %cl") + Environment.NewLine; result += ("xorq %rdx, %rdx") + Environment.NewLine; result += ("mov %cl, %dl") + Environment.NewLine; break; case TermType.negEq: result += ("cmpq %rsi, %rdx") + Environment.NewLine; result += ("setne %cl") + Environment.NewLine; result += ("xorq %rdx, %rdx") + Environment.NewLine; result += ("mov %cl, %dl") + Environment.NewLine; break; case TermType.logAnd: result += GetLogicalExpression("%rdx"); result += GetLogicalExpression("%rsi"); result += ("andq %rsi, %rdx") + Environment.NewLine; break; case TermType.logOr: result += ("orq %rsi, %rdx") + Environment.NewLine; break; case TermType.xorEq: result += PrintExpression(new ADExpression { Left = expression.Left, Operator = TermType.xor, Right = expression.Right }); result += PrintAssignRdx(expression.Left); break; case TermType.xor: result += "xorq %rsi, %rdx" + Environment.NewLine; break; case TermType.mulEq: result += PrintExpression(new ADExpression { Left = expression.Left, Operator = TermType.mul, Right = expression.Right }); result += PrintAssignRdx(expression.Left); break; case TermType.plusEq: result += PrintExpression(new ADExpression { Left = expression.Left, Operator = TermType.plus, Right = expression.Right }); result += PrintAssignRdx(expression.Left); break; case TermType.minusEq: result += PrintExpression(new ADExpression { Left = expression.Left, Operator = TermType.minus, Right = expression.Right }); result += PrintAssignRdx(expression.Left); break; } result += ("pushq %rdx") + Environment.NewLine; return(result); }
public static IADExpression Precedence(TokenType endType, bool decl = false) { Stack <Term> SS = new Stack <Term>(); // Sign stack Stack <Term> ST = new Stack <Term>(); // Term stack int numOfLeftB = 0; int numOfRightB = 0; bool mustBeId = true; Term actualTerm = null; SS.Push(new Term() { Type = TermType.end }); while (true) { if (actualTerm == null || actualTerm.Type != TermType.end) { actualTerm = GetNextTerm(endType, numOfLeftB, numOfRightB, ref SS, decl); } var stackSym = SS.Peek(); if (actualTerm.Type == TermType.leftBr) { numOfLeftB++; } if (actualTerm.Type == TermType.rightBr) { numOfRightB++; } if ((numOfRightB > numOfLeftB) && endType == TokenType.semiType) { ParserFunctions.SyntaxError("Neocekavany konec vyrazu."); } if (actualTerm.Type == TermType.leftABtype) { if (ST.Count == 0) { ParserFunctions.SyntaxError("Vyraz nemuze zacinat znakem \'[\'"); } var arrayTerm = ST.Pop(); var record = arrayTerm.STRecord; MainFSM.Index--; var arrayValue = new ADArrayValue() { STRecord = record }; arrayValue.ComputeIndexes(); if (arrayTerm.Expression != null) { arrayValue.ArrayExpression = arrayTerm.Expression; } arrayTerm.Expression = arrayValue; actualTerm = GetNextTerm(endType, numOfLeftB, numOfRightB, ref SS, decl); if (actualTerm.Type == TermType.leftBr) { MainFSM.Index--; var fceCall = ParserFunctions.fce_call(); fceCall.Expression = arrayValue; ST.Push(new Term() { Expression = fceCall, Type = TermType.id }); actualTerm = GetNextTerm(endType, numOfLeftB, numOfRightB, ref SS, decl); } else { ST.Push(arrayTerm); } } if (mustBeId && actualTerm.Type == TermType.binAnd) { actualTerm.Type = TermType.reference; } else if (mustBeId && actualTerm.Type == TermType.mul) { actualTerm.Type = TermType.dereference; } if (actualTerm.Type == TermType.inc || actualTerm.Type == TermType.dec) { var expr = new ADExpression(); expr.Operator = actualTerm.Type; if (mustBeId) { actualTerm = GetNextTerm(endType, numOfLeftB, numOfRightB, ref SS, decl); if (actualTerm.Type != TermType.id) { ParserFunctions.SyntaxError("Byl ocekavan identifikator."); } expr.Right = GetExpression(actualTerm.STRecord); mustBeId = false; } else { actualTerm = ST.Pop(); expr.Left = GetExpression(actualTerm.STRecord); } var newTerm = new Term { Expression = expr }; ST.Push(newTerm); continue; } switch (precTable[(int)stackSym.Type, (int)actualTerm.Type]) { case L: if (actualTerm.Type == TermType.id) { if (mustBeId) { ST.Push(actualTerm); mustBeId = false; } else { ParserFunctions.SyntaxError("Byl ocekavan operator."); } } else if ((actualTerm.Type != TermType.id) && (actualTerm.Type != TermType.end)) { if (!mustBeId || actualTerm.Type == TermType.leftBr || actualTerm.Type == TermType.rightBr) { SS.Push(actualTerm); mustBeId = true; } else if (mustBeId && (actualTerm.Type == TermType.not || actualTerm.Type == TermType.minus || actualTerm.Type == TermType.plus || actualTerm.Type == TermType.compl || actualTerm.Type == TermType.reference || actualTerm.Type == TermType.dereference)) { SS.Push(actualTerm); } else { ParserFunctions.SyntaxError("Byla ocekavana hodnota typu long."); } } break; case G: if (actualTerm.Type == TermType.rightBr) { while (stackSym.Type != TermType.leftBr) { Reduce(ref SS, ref ST); stackSym = SS.Peek(); } SS.Pop(); } else { Reduce(ref SS, ref ST); if (actualTerm.Type != TermType.end) { SS.Push(actualTerm); mustBeId = true; } } break; case E: SS.Pop(); break; case B: ParserFunctions.SyntaxError("Chyba ve vyrazu."); break; case S: break; } if (actualTerm.Type == TermType.end && stackSym.Type == TermType.end) { break; } } MainFSM.Index--; if (ST.Count > 0) { var result = ST.Pop(); if (result.Expression == null) { if (result.STRecord.Type == STType.constant) { result.Expression = new ADConstant { Value = result.STRecord.Value }; } else if (result.STRecord.Type == STType.variable || result.STRecord.Type == STType.array || result.STRecord.Type == STType.str) { result.Expression = new ADVariable { Name = result.STRecord.Name, Type = ADVariable.VarType.variable, STRecord = result.STRecord }; } else if (result.STRecord.Type == STType.function) { result.Expression = ParserFunctions.fce_call(); } } return(result.Expression); } return(null); }