private string WriteExpr(Expression expr, RegisterFile registerFile, StringBuilder programBuilder, string registerToUse = "") { #region INT_EXPRESSIONS if (expr == null) { return(""); } else if (expr is DecValue) { var register = expr.ToString(); for (int x = 0; x < registerFile.stack.Count(); x++) { if (registerFile.stack.ElementAt(x).Key == savedValue) { indexFound = true; //inStack = true; inCycle = true; register = registerFile.RegisterPosition(savedValue);//registerFile.stack.ElementAt(x).Value.positioninStack; registerFile.stackx86.positioninStack = register; registerFile.stackx86.idValue = expr.ToString(); registerFile.stack[registerFile.stack.ElementAt(x).Key] = registerFile.stackx86; } else { for (int i = 0; i < registerFile.savedTemporals.Count(); i++) { if (registerFile.savedTemporals.ElementAt(i).Key == savedValue) { indexFound = false; register = registerFile.RegisterPosition(savedValue);//registerFile.stack.ElementAt(i).Value.positioninStack; break; } } } } if (indexFound == true && inCycle == true)//inStack == true) { programBuilder.AppendFormat("\t mov DWORD PTR [ebp-{0}], {1}", register, expr.ToString()); programBuilder.AppendFormat("\t# Mueve {0} a la posiciĆ³n en la pila {1}", expr.ToString(), register); programBuilder.AppendLine(); register = string.Format("DWORD PTR [ebp-{0}]", register); indexFound = false; } else if (indexFound == false || inStack == true || inCycle == true) { var reg = registerFile.FirstAvailableRegister(); programBuilder.AppendFormat("\t mov {0} , {1}", reg, expr.ToString()); programBuilder.AppendFormat("\t# Mueve {0} a {1}", expr.ToString(), reg); programBuilder.AppendLine(); register = reg; } return(register); } else if (expr is IdValue) { var register = expr.ToString(); var firstAvailableReg = registerFile.FirstAvailableRegister(); for (int x = 0; x < registerFile.stack.Count(); x++) { if (registerFile.stack.ElementAt(x).Key == register) { register = registerFile.stack.ElementAt(x).Value.positioninStack; } } programBuilder.AppendFormat("\t mov {0}, DWORD PTR [ebp-{1}]", firstAvailableReg, register); programBuilder.AppendFormat("\t# Mueve {0} a la pos ebp - {1}", expr.ToString(), register); programBuilder.AppendLine(); register = firstAvailableReg; registerFile.FreeRegister(firstAvailableReg); return(register); } else if (expr is AddExpression) { if (string.IsNullOrEmpty(registerToUse)) { registerToUse = registerFile.FirstAvailableRegister(); } var add = expr as AddExpression; var leftRegister = WriteExpr(add.Right, registerFile, programBuilder); var register = registerToUse; programBuilder.AppendFormat("\t add {0}, {1}", register, leftRegister); programBuilder.AppendFormat("\t\t# {0} + {1}", register, leftRegister); programBuilder.AppendLine(); registerFile.FreeRegister(leftRegister); var rightRegister = WriteExpr(add.Left, registerFile, programBuilder, register); if (register != rightRegister) { programBuilder.AppendFormat("\t add {0}, {1}", register, rightRegister); programBuilder.AppendFormat("\t\t# {0} + {1}", register, rightRegister); programBuilder.AppendLine(); registerFile.FreeRegister(rightRegister); } return(register); } else if (expr is SubExpression) { if (string.IsNullOrEmpty(registerToUse)) { registerToUse = registerFile.FirstAvailableRegister(); } var add = expr as SubExpression; var leftRegister = WriteExpr(add.Right, registerFile, programBuilder); var register = registerToUse; programBuilder.AppendFormat("\t sub {0}, {1}", register, leftRegister); programBuilder.AppendFormat("\t\t# {0} - {1}", register, leftRegister); programBuilder.AppendLine(); registerFile.FreeRegister(leftRegister); var rightRegister = WriteExpr(add.Left, registerFile, programBuilder, register); if (register != rightRegister) { programBuilder.AppendFormat("\t sub {0}, {1}", register, rightRegister); programBuilder.AppendFormat("\t\t# {0} - {1}", register, rightRegister); programBuilder.AppendLine(); registerFile.FreeRegister(rightRegister); } return(register); } else if (expr is MulExpression) { if (string.IsNullOrEmpty(registerToUse)) { registerToUse = registerFile.FirstAvailableRegister(); } var add = expr as MulExpression; var leftRegister = WriteExpr(add.Right, registerFile, programBuilder); var register = registerToUse; programBuilder.AppendFormat("\t mul {0}, {1}", register, leftRegister); programBuilder.AppendFormat("\t\t# {0} * {1}", register, leftRegister); programBuilder.AppendLine(); registerFile.FreeRegister(leftRegister); var rightRegister = WriteExpr(add.Left, registerFile, programBuilder, register); if (register != rightRegister) { programBuilder.AppendFormat("\t mul {0}, {1}", register, rightRegister); programBuilder.AppendFormat("\t\t# {0} * {1}", register, rightRegister); programBuilder.AppendLine(); registerFile.FreeRegister(rightRegister); } return(register); } else if (expr is DivisionExpression) { if (string.IsNullOrEmpty(registerToUse)) { registerToUse = registerFile.FirstAvailableRegister(); } var add = expr as DivisionExpression; var leftRegister = WriteExpr(add.Right, registerFile, programBuilder); var register = registerToUse; programBuilder.AppendFormat("\t div {0}, {1}", register, leftRegister); programBuilder.AppendFormat("\t\t# {0} / {1}", register, leftRegister); programBuilder.AppendLine(); registerFile.FreeRegister(leftRegister); var rightRegister = WriteExpr(add.Left, registerFile, programBuilder, register); if (register != rightRegister) { programBuilder.AppendFormat("\t div {0}, {1}", register, rightRegister); programBuilder.AppendFormat("\t\t# {0} / {1}", register, rightRegister); programBuilder.AppendLine(); registerFile.FreeRegister(rightRegister); } return(register); } else if (expr is ModExpression) { if (string.IsNullOrEmpty(registerToUse)) { registerToUse = registerFile.FirstAvailableRegister(); } var add = expr as ModExpression; var leftRegister = WriteExpr(add.Right, registerFile, programBuilder); var register = registerToUse; programBuilder.AppendFormat("\t mov {0}, {1}", register, leftRegister); programBuilder.AppendLine(); programBuilder.AppendFormat("\t sar {0}, 31", leftRegister); programBuilder.AppendLine(); // register = leftRegister; registerFile.FreeRegister(leftRegister); var rightRegister = WriteExpr(add.Left, registerFile, programBuilder, register); if (register != rightRegister) { programBuilder.AppendFormat("\t idiv {0}", rightRegister); programBuilder.AppendFormat("\t\t# {0} % {1}", register, rightRegister); programBuilder.AppendLine(); registerFile.FreeRegister(rightRegister); } return(register); } else if (expr is ModExpression) { if (string.IsNullOrEmpty(registerToUse)) { registerToUse = registerFile.FirstAvailableRegister(); } var add = expr as ModExpression; var leftRegister = WriteExpr(add.Right, registerFile, programBuilder); var register = registerToUse; programBuilder.AppendFormat("\t div {0}, {1}", register, leftRegister); programBuilder.AppendFormat("\t\t# {0} % {1}", register, leftRegister); programBuilder.AppendLine(); registerFile.FreeRegister(leftRegister); var rightRegister = WriteExpr(add.Left, registerFile, programBuilder, register); if (register != rightRegister) { programBuilder.AppendFormat("\t move {0}, {1}", register, rightRegister); programBuilder.AppendFormat("\t\t# {0} / {1}", register, rightRegister); programBuilder.AppendLine(); programBuilder.AppendFormat("\t mfhi {0}", rightRegister); programBuilder.AppendFormat("\t\t# Pasa el valor {0} para guardar el MOD", rightRegister); programBuilder.AppendLine(); registerFile.FreeRegister(rightRegister); } return(register); } #endregion #region BITWISE_OP_EXPRESSIONS else if (expr is BitwiseAndExpression) { if (string.IsNullOrEmpty(registerToUse)) { registerToUse = registerFile.FirstAvailableRegister(); } var add = expr as BitwiseAndExpression; var leftRegister = WriteExpr(add.Right, registerFile, programBuilder); var register = registerToUse; programBuilder.AppendFormat("\t and {0}, {1}", register, leftRegister); programBuilder.AppendFormat("\t\t# {0} & {1}", register, leftRegister); programBuilder.AppendLine(); registerFile.FreeRegister(leftRegister); var rightRegister = WriteExpr(add.Left, registerFile, programBuilder, register); if (register != rightRegister) { programBuilder.AppendFormat("\t and {0}, {1}", register, rightRegister); programBuilder.AppendFormat("\t\t# {0} & {1}", register, rightRegister); programBuilder.AppendLine(); registerFile.FreeRegister(rightRegister); } return(register); } else if (expr is BitwiseOrExpression) { if (string.IsNullOrEmpty(registerToUse)) { registerToUse = registerFile.FirstAvailableRegister(); } var add = expr as BitwiseOrExpression; var leftRegister = WriteExpr(add.Right, registerFile, programBuilder); var register = registerToUse; programBuilder.AppendFormat("\t or {0}, {1}", register, leftRegister); programBuilder.AppendFormat("\t\t# {0} | {1}", register, leftRegister); programBuilder.AppendLine(); registerFile.FreeRegister(leftRegister); var rightRegister = WriteExpr(add.Left, registerFile, programBuilder, register); if (register != rightRegister) { programBuilder.AppendFormat("\t or {0}, {1}", register, rightRegister); programBuilder.AppendFormat("\t\t# {0} | {1}", register, rightRegister); programBuilder.AppendLine(); registerFile.FreeRegister(rightRegister); } return(register); } else if (expr is BitwiseXorExpression) { if (string.IsNullOrEmpty(registerToUse)) { registerToUse = registerFile.FirstAvailableRegister(); } var add = expr as BitwiseXorExpression; var leftRegister = WriteExpr(add.Right, registerFile, programBuilder); var register = registerToUse; programBuilder.AppendFormat("\t xor {0}, {1}", register, leftRegister); programBuilder.AppendFormat("\t\t# {0} ^ {1}", register, leftRegister); programBuilder.AppendLine(); registerFile.FreeRegister(leftRegister); var rightRegister = WriteExpr(add.Left, registerFile, programBuilder, register); if (register != rightRegister) { programBuilder.AppendFormat("\t xor {0}, {1}", register, rightRegister); programBuilder.AppendFormat("\t\t# {0} ^ {1}", register, rightRegister); programBuilder.AppendLine(); registerFile.FreeRegister(rightRegister); } return(register); } else if (expr is LessThanExpression) { if (string.IsNullOrEmpty(registerToUse)) { registerToUse = registerFile.FirstAvailableRegister(); } var add = expr as LessThanExpression; var leftRegister = WriteExpr(add.Right, registerFile, programBuilder); var register = registerToUse; programBuilder.AppendFormat("\t mov {0}, {1}", register, leftRegister); programBuilder.AppendFormat("\t# Mueve {0} a {1} para hacer el cmp", register, leftRegister); programBuilder.AppendLine(); registerFile.FreeRegister(leftRegister); var rightRegister = WriteExpr(add.Left, registerFile, programBuilder, register); if (register != rightRegister) { programBuilder.AppendFormat("\t cmp {0}, {1}", register, rightRegister); programBuilder.AppendFormat("\t\t# {0} < {1}", register, rightRegister); programBuilder.AppendLine(); registerFile.FreeRegister(rightRegister); } labelCount += 1; programBuilder.AppendFormat("\t jge .L{0}", labelCount); programBuilder.AppendFormat("\t\t# Salta al label {0} si es >=.", labelCount); programBuilder.AppendLine(); programBuilder.AppendFormat(".L{0}", labelCount); programBuilder.AppendLine(); return(register); } else if (expr is LessOrEqualToExpression) { if (string.IsNullOrEmpty(registerToUse)) { registerToUse = registerFile.FirstAvailableRegister(); } var add = expr as LessOrEqualToExpression; var leftRegister = WriteExpr(add.Right, registerFile, programBuilder); var register = registerToUse; programBuilder.AppendFormat("\t mov {0}, {1}", register, leftRegister); programBuilder.AppendFormat("\t# Mueve {0} a {1} para hacer el cmp", register, leftRegister); programBuilder.AppendLine(); registerFile.FreeRegister(leftRegister); var rightRegister = WriteExpr(add.Left, registerFile, programBuilder, register); if (register != rightRegister) { programBuilder.AppendFormat("\t cmp {0}, {1}", register, rightRegister); programBuilder.AppendFormat("\t\t# {0} < {1}", register, rightRegister); programBuilder.AppendLine(); registerFile.FreeRegister(rightRegister); } labelCount += 1; programBuilder.AppendFormat("\t jg .L{0}", labelCount); programBuilder.AppendFormat("\t\t# Salta al label {0} si es >=.", labelCount); programBuilder.AppendLine(); programBuilder.AppendFormat(".L{0}", labelCount); programBuilder.AppendLine(); return(register); } else if (expr is GreaterThanExpression) { if (string.IsNullOrEmpty(registerToUse)) { registerToUse = registerFile.FirstAvailableRegister(); } var add = expr as GreaterThanExpression; var leftRegister = WriteExpr(add.Right, registerFile, programBuilder); var register = registerToUse; programBuilder.AppendFormat("\t mov {0}, {1}", register, leftRegister); programBuilder.AppendFormat("\t# Mueve {0} a {1} para hacer el cmp", register, leftRegister); programBuilder.AppendLine(); registerFile.FreeRegister(leftRegister); var rightRegister = WriteExpr(add.Left, registerFile, programBuilder, register); if (register != rightRegister) { programBuilder.AppendFormat("\t cmp {0}, {1}", register, rightRegister); programBuilder.AppendFormat("\t\t# {0} < {1}", register, rightRegister); programBuilder.AppendLine(); registerFile.FreeRegister(rightRegister); } labelCount += 1; programBuilder.AppendFormat("\t jle .L{0}", labelCount); programBuilder.AppendFormat("\t\t# Salta al label {0} si es <.", labelCount); programBuilder.AppendLine(); programBuilder.AppendFormat(".L{0}", labelCount); programBuilder.AppendLine(); return(register); } else if (expr is GreaterOrEqualExpression) { if (string.IsNullOrEmpty(registerToUse)) { registerToUse = registerFile.FirstAvailableRegister(); } var add = expr as GreaterOrEqualExpression; var leftRegister = WriteExpr(add.Right, registerFile, programBuilder); var register = registerToUse; programBuilder.AppendFormat("\t mov {0}, {1}", register, leftRegister); programBuilder.AppendFormat("\t# Mueve {0} a {1} para hacer el cmp", register, leftRegister); programBuilder.AppendLine(); registerFile.FreeRegister(leftRegister); var rightRegister = WriteExpr(add.Left, registerFile, programBuilder, register); if (register != rightRegister) { programBuilder.AppendFormat("\t cmp {0}, {1}", register, rightRegister); programBuilder.AppendFormat("\t\t# {0} < {1}", register, rightRegister); programBuilder.AppendLine(); registerFile.FreeRegister(rightRegister); } labelCount += 1; programBuilder.AppendFormat("\t jl .L{0}", labelCount); programBuilder.AppendFormat("\t\t# Salta al label {0} si es <.", labelCount); programBuilder.AppendLine(); programBuilder.AppendFormat(".L{0}", labelCount); programBuilder.AppendLine(); return(register); } else if (expr is EqualsExpression) { if (string.IsNullOrEmpty(registerToUse)) { registerToUse = registerFile.FirstAvailableRegister(); } var add = expr as EqualsExpression; var leftRegister = WriteExpr(add.Right, registerFile, programBuilder); var register = registerToUse; programBuilder.AppendFormat("\t mov {0}, {1}", register, leftRegister); programBuilder.AppendFormat("\t# Mueve {0} a {1} para hacer el cmp", register, leftRegister); programBuilder.AppendLine(); registerFile.FreeRegister(leftRegister); var rightRegister = WriteExpr(add.Left, registerFile, programBuilder, register); if (register != rightRegister) { programBuilder.AppendFormat("\t cmp {0}, {1}", register, rightRegister); programBuilder.AppendFormat("\t\t# {0} < {1}", register, rightRegister); programBuilder.AppendLine(); registerFile.FreeRegister(rightRegister); } labelCount += 1; programBuilder.AppendFormat("\t jne .L{0}", labelCount); programBuilder.AppendFormat("\t\t# Salta al label {0} si es <.", labelCount); programBuilder.AppendLine(); return(register); } #endregion #region LOGICAL_EXPR else if (expr is LogicalOrExpression) { if (string.IsNullOrEmpty(registerToUse)) { registerToUse = registerFile.FirstAvailableRegister(); } var add = expr as BitwiseAndExpression; var leftRegister = WriteExpr(add.Right, registerFile, programBuilder); var register = registerToUse; programBuilder.AppendFormat("\t cmp {0}, 0", leftRegister); programBuilder.AppendFormat("\t\t# Compara {0} con 0", leftRegister); programBuilder.AppendLine(); programBuilder.AppendFormat("\t jne .L{0}", labelCount); programBuilder.AppendLine(); registerFile.FreeRegister(leftRegister); var rightRegister = WriteExpr(add.Left, registerFile, programBuilder, register); if (register != rightRegister) { programBuilder.AppendFormat("\t cmp {0}, 0", rightRegister); programBuilder.AppendFormat("\t\t# Compara {0} con 0", rightRegister); programBuilder.AppendLine(); programBuilder.AppendFormat("\t jne .L{0}", labelCount); programBuilder.AppendLine(); registerFile.FreeRegister(rightRegister); } return(register); } else if (expr is LogicAndExpression) { { registerToUse = registerFile.FirstAvailableRegister(); } var add = expr as BitwiseAndExpression; var leftRegister = WriteExpr(add.Right, registerFile, programBuilder); var register = registerToUse; programBuilder.AppendFormat("\t cmp {0}, 0", leftRegister); programBuilder.AppendFormat("\t\t# Compara {0} con 0", leftRegister); programBuilder.AppendLine(); programBuilder.AppendFormat("\t je .L{0}", labelCount); programBuilder.AppendLine(); registerFile.FreeRegister(leftRegister); var rightRegister = WriteExpr(add.Left, registerFile, programBuilder, register); if (register != rightRegister) { programBuilder.AppendFormat("\t cmp {0}, 0", rightRegister); programBuilder.AppendFormat("\t\t# Compara {0} con 0", rightRegister); programBuilder.AppendLine(); programBuilder.AppendFormat("\t je .L{0}", labelCount); programBuilder.AppendLine(); registerFile.FreeRegister(rightRegister); } return(register); #endregion #region ASSIGN_EXPRESSIONS } else if (expr is AdditionAssignmentExpression) { var add = expr as AdditionAssignmentExpression; var leftRegister = WriteExpr(add.Right, registerFile, programBuilder); programBuilder.AppendFormat("\t add {0}, {1}", leftRegister, add.Left); programBuilder.AppendFormat("\t# {0}", expr.ToString()); programBuilder.AppendLine(); } else if (expr is SubtractionAsigExpression) { var sub = expr as SubtractionAsigExpression; var leftRegister = WriteExpr(sub.Right, registerFile, programBuilder); programBuilder.AppendFormat("\t sub {0}, {1}", leftRegister, sub.Left); programBuilder.AppendFormat("\t# {0}", expr.ToString()); programBuilder.AppendLine(); } else if (expr is MultiplicationAsigExpression) { var sub = expr as MultiplicationAsigExpression; var leftRegister = WriteExpr(sub.Right, registerFile, programBuilder); programBuilder.AppendFormat("\t mul {0}, {1}", leftRegister, sub.Left); programBuilder.AppendFormat("\t# {0}", expr.ToString()); programBuilder.AppendLine(); } else if (expr is DivisionAsigExpression) { var sub = expr as DivisionAsigExpression; var leftRegister = WriteExpr(sub.Right, registerFile, programBuilder); programBuilder.AppendFormat("\t div {0}, {1}", leftRegister, sub.Left); programBuilder.AppendFormat("\t# {0}", expr.ToString()); programBuilder.AppendLine(); } else if (expr is AssignExpression) { var assign = expr as AssignExpression; foreach (var id in registerFile.stack) { if (id.Key == assign.Left.ToString()) { savedValue = id.Key; inStack = true; } } if (inStack == false) { var pos = registerFile.stack.Last().Value.positioninStack; registerFile.stackx86.idValue = assign.Right.ToString(); savedValue = assign.Left.ToString(); registerFile.stackx86.positioninStack = Convert.ToString(Convert.ToInt32(pos) + 4); registerFile.stack.Add(assign.Left.ToString(), registerFile.stackx86); inStack = true; } var assignRegister = WriteExpr(assign.Right, registerFile, programBuilder); if (assign.Left is PointerArrayAccessExpr) { isArray = true; registerFile.FreeRegister(assignRegister); WriteExpr(assign.Left, registerFile, programBuilder); return(assignRegister); } else { if (inStack == false) { programBuilder.AppendFormat("\t mov {0}, {1}", assignRegister, assign.Left.ToString()); programBuilder.AppendLine(); } inStack = false; return(assignRegister); } } #endregion #region POST_PRE_INCREMENT_DECREMENT else if (expr is PostIncrementExpression) { var postIncrement = expr as PostIncrementExpression; var register = registerFile.RegisterPosition(postIncrement.Expression.ToString()); programBuilder.AppendFormat("\t add DWORD PTR [epb-{0}], 1", register); programBuilder.AppendFormat("\t# {0}", expr.ToString()); programBuilder.AppendLine(); return(register); } else if (expr is PreIncrementExpression) { } else if (expr is PostDecrementExpression) { } else if (expr is PreDecrementExpression) { } #endregion #region FUNTIONCALL_EXPRESSION else if (expr is FunctionCallExpression) { WriteFunctionCallExp(expr as FunctionCallExpression, programBuilder); } #endregion #region ARRAY_EXPRESSION else if (expr is PointerArrayAccessExpr) { } #endregion return(registerFile.FirstAvailableRegister()); }
private string WriteExpr(Expression expr, RegisterFile registerFile, StringBuilder programBuilder, string registerToUse = "") { #region INT_EXPRESSIONS if (expr == null) { return ""; } else if (expr is DecValue) { var register = expr.ToString(); for (int x = 0; x < registerFile.stack.Count(); x++) { if (registerFile.stack.ElementAt(x).Key == savedValue) { indexFound = true; //inStack = true; inCycle = true; register = registerFile.RegisterPosition(savedValue);//registerFile.stack.ElementAt(x).Value.positioninStack; registerFile.stackx86.positioninStack = register; registerFile.stackx86.idValue = expr.ToString(); registerFile.stack[registerFile.stack.ElementAt(x).Key] = registerFile.stackx86; } else for (int i = 0; i < registerFile.savedTemporals.Count(); i++) { if (registerFile.savedTemporals.ElementAt(i).Key == savedValue) { indexFound = false; register = registerFile.RegisterPosition(savedValue);//registerFile.stack.ElementAt(i).Value.positioninStack; break; } } } if (indexFound == true && inCycle == true)//inStack == true) { programBuilder.AppendFormat("\t mov DWORD PTR [ebp-{0}], {1}", register, expr.ToString()); programBuilder.AppendFormat("\t# Mueve {0} a la posiciĆ³n en la pila {1}", expr.ToString(), register); programBuilder.AppendLine(); register = string.Format("DWORD PTR [ebp-{0}]", register); indexFound = false; } else if (indexFound == false || inStack == true || inCycle == true) { var reg = registerFile.FirstAvailableRegister(); programBuilder.AppendFormat("\t mov {0} , {1}", reg, expr.ToString()); programBuilder.AppendFormat("\t# Mueve {0} a {1}", expr.ToString(), reg); programBuilder.AppendLine(); register = reg; } return register; } else if (expr is IdValue) { var register = expr.ToString(); var firstAvailableReg = registerFile.FirstAvailableRegister(); for (int x = 0; x < registerFile.stack.Count(); x++) { if (registerFile.stack.ElementAt(x).Key == register) { register = registerFile.stack.ElementAt(x).Value.positioninStack; } } programBuilder.AppendFormat("\t mov {0}, DWORD PTR [ebp-{1}]", firstAvailableReg, register); programBuilder.AppendFormat("\t# Mueve {0} a la pos ebp - {1}", expr.ToString(), register); programBuilder.AppendLine(); register = firstAvailableReg; registerFile.FreeRegister(firstAvailableReg); return register; } else if (expr is AddExpression) { if (string.IsNullOrEmpty(registerToUse)) { registerToUse = registerFile.FirstAvailableRegister(); } var add = expr as AddExpression; var leftRegister = WriteExpr(add.Right, registerFile, programBuilder); var register = registerToUse; programBuilder.AppendFormat("\t add {0}, {1}", register, leftRegister); programBuilder.AppendFormat("\t\t# {0} + {1}", register, leftRegister); programBuilder.AppendLine(); registerFile.FreeRegister(leftRegister); var rightRegister = WriteExpr(add.Left, registerFile, programBuilder, register); if (register != rightRegister) { programBuilder.AppendFormat("\t add {0}, {1}", register, rightRegister); programBuilder.AppendFormat("\t\t# {0} + {1}", register, rightRegister); programBuilder.AppendLine(); registerFile.FreeRegister(rightRegister); } return register; } else if (expr is SubExpression) { if (string.IsNullOrEmpty(registerToUse)) { registerToUse = registerFile.FirstAvailableRegister(); } var add = expr as SubExpression; var leftRegister = WriteExpr(add.Right, registerFile, programBuilder); var register = registerToUse; programBuilder.AppendFormat("\t sub {0}, {1}", register, leftRegister); programBuilder.AppendFormat("\t\t# {0} - {1}", register, leftRegister); programBuilder.AppendLine(); registerFile.FreeRegister(leftRegister); var rightRegister = WriteExpr(add.Left, registerFile, programBuilder, register); if (register != rightRegister) { programBuilder.AppendFormat("\t sub {0}, {1}", register, rightRegister); programBuilder.AppendFormat("\t\t# {0} - {1}", register, rightRegister); programBuilder.AppendLine(); registerFile.FreeRegister(rightRegister); } return register; } else if (expr is MulExpression) { if (string.IsNullOrEmpty(registerToUse)) { registerToUse = registerFile.FirstAvailableRegister(); } var add = expr as MulExpression; var leftRegister = WriteExpr(add.Right, registerFile, programBuilder); var register = registerToUse; programBuilder.AppendFormat("\t mul {0}, {1}", register, leftRegister); programBuilder.AppendFormat("\t\t# {0} * {1}", register, leftRegister); programBuilder.AppendLine(); registerFile.FreeRegister(leftRegister); var rightRegister = WriteExpr(add.Left, registerFile, programBuilder, register); if (register != rightRegister) { programBuilder.AppendFormat("\t mul {0}, {1}", register, rightRegister); programBuilder.AppendFormat("\t\t# {0} * {1}", register, rightRegister); programBuilder.AppendLine(); registerFile.FreeRegister(rightRegister); } return register; } else if (expr is DivisionExpression) { if (string.IsNullOrEmpty(registerToUse)) { registerToUse = registerFile.FirstAvailableRegister(); } var add = expr as DivisionExpression; var leftRegister = WriteExpr(add.Right, registerFile, programBuilder); var register = registerToUse; programBuilder.AppendFormat("\t div {0}, {1}", register, leftRegister); programBuilder.AppendFormat("\t\t# {0} / {1}", register, leftRegister); programBuilder.AppendLine(); registerFile.FreeRegister(leftRegister); var rightRegister = WriteExpr(add.Left, registerFile, programBuilder, register); if (register != rightRegister) { programBuilder.AppendFormat("\t div {0}, {1}", register, rightRegister); programBuilder.AppendFormat("\t\t# {0} / {1}", register, rightRegister); programBuilder.AppendLine(); registerFile.FreeRegister(rightRegister); } return register; } else if (expr is ModExpression) { if (string.IsNullOrEmpty(registerToUse)) { registerToUse = registerFile.FirstAvailableRegister(); } var add = expr as ModExpression; var leftRegister = WriteExpr(add.Right, registerFile, programBuilder); var register = registerToUse; programBuilder.AppendFormat("\t mov {0}, {1}", register, leftRegister); programBuilder.AppendLine(); programBuilder.AppendFormat("\t sar {0}, 31", leftRegister); programBuilder.AppendLine(); // register = leftRegister; registerFile.FreeRegister(leftRegister); var rightRegister = WriteExpr(add.Left, registerFile, programBuilder, register); if (register != rightRegister) { programBuilder.AppendFormat("\t idiv {0}", rightRegister); programBuilder.AppendFormat("\t\t# {0} % {1}", register, rightRegister); programBuilder.AppendLine(); registerFile.FreeRegister(rightRegister); } return register; } else if (expr is ModExpression) { if (string.IsNullOrEmpty(registerToUse)) { registerToUse = registerFile.FirstAvailableRegister(); } var add = expr as ModExpression; var leftRegister = WriteExpr(add.Right, registerFile, programBuilder); var register = registerToUse; programBuilder.AppendFormat("\t div {0}, {1}", register, leftRegister); programBuilder.AppendFormat("\t\t# {0} % {1}", register, leftRegister); programBuilder.AppendLine(); registerFile.FreeRegister(leftRegister); var rightRegister = WriteExpr(add.Left, registerFile, programBuilder, register); if (register != rightRegister) { programBuilder.AppendFormat("\t move {0}, {1}", register, rightRegister); programBuilder.AppendFormat("\t\t# {0} / {1}", register, rightRegister); programBuilder.AppendLine(); programBuilder.AppendFormat("\t mfhi {0}", rightRegister); programBuilder.AppendFormat("\t\t# Pasa el valor {0} para guardar el MOD", rightRegister); programBuilder.AppendLine(); registerFile.FreeRegister(rightRegister); } return register; } #endregion #region BITWISE_OP_EXPRESSIONS else if (expr is BitwiseAndExpression) { if (string.IsNullOrEmpty(registerToUse)) { registerToUse = registerFile.FirstAvailableRegister(); } var add = expr as BitwiseAndExpression; var leftRegister = WriteExpr(add.Right, registerFile, programBuilder); var register = registerToUse; programBuilder.AppendFormat("\t and {0}, {1}", register, leftRegister); programBuilder.AppendFormat("\t\t# {0} & {1}", register, leftRegister); programBuilder.AppendLine(); registerFile.FreeRegister(leftRegister); var rightRegister = WriteExpr(add.Left, registerFile, programBuilder, register); if (register != rightRegister) { programBuilder.AppendFormat("\t and {0}, {1}", register, rightRegister); programBuilder.AppendFormat("\t\t# {0} & {1}", register, rightRegister); programBuilder.AppendLine(); registerFile.FreeRegister(rightRegister); } return register; } else if (expr is BitwiseOrExpression) { if (string.IsNullOrEmpty(registerToUse)) { registerToUse = registerFile.FirstAvailableRegister(); } var add = expr as BitwiseOrExpression; var leftRegister = WriteExpr(add.Right, registerFile, programBuilder); var register = registerToUse; programBuilder.AppendFormat("\t or {0}, {1}", register, leftRegister); programBuilder.AppendFormat("\t\t# {0} | {1}", register, leftRegister); programBuilder.AppendLine(); registerFile.FreeRegister(leftRegister); var rightRegister = WriteExpr(add.Left, registerFile, programBuilder, register); if (register != rightRegister) { programBuilder.AppendFormat("\t or {0}, {1}", register, rightRegister); programBuilder.AppendFormat("\t\t# {0} | {1}", register, rightRegister); programBuilder.AppendLine(); registerFile.FreeRegister(rightRegister); } return register; } else if (expr is BitwiseXorExpression) { if (string.IsNullOrEmpty(registerToUse)) { registerToUse = registerFile.FirstAvailableRegister(); } var add = expr as BitwiseXorExpression; var leftRegister = WriteExpr(add.Right, registerFile, programBuilder); var register = registerToUse; programBuilder.AppendFormat("\t xor {0}, {1}", register, leftRegister); programBuilder.AppendFormat("\t\t# {0} ^ {1}", register, leftRegister); programBuilder.AppendLine(); registerFile.FreeRegister(leftRegister); var rightRegister = WriteExpr(add.Left, registerFile, programBuilder, register); if (register != rightRegister) { programBuilder.AppendFormat("\t xor {0}, {1}", register, rightRegister); programBuilder.AppendFormat("\t\t# {0} ^ {1}", register, rightRegister); programBuilder.AppendLine(); registerFile.FreeRegister(rightRegister); } return register; } else if (expr is LessThanExpression) { if (string.IsNullOrEmpty(registerToUse)) { registerToUse = registerFile.FirstAvailableRegister(); } var add = expr as LessThanExpression; var leftRegister = WriteExpr(add.Right, registerFile, programBuilder); var register = registerToUse; programBuilder.AppendFormat("\t mov {0}, {1}", register, leftRegister); programBuilder.AppendFormat("\t# Mueve {0} a {1} para hacer el cmp", register, leftRegister); programBuilder.AppendLine(); registerFile.FreeRegister(leftRegister); var rightRegister = WriteExpr(add.Left, registerFile, programBuilder, register); if (register != rightRegister) { programBuilder.AppendFormat("\t cmp {0}, {1}", register, rightRegister); programBuilder.AppendFormat("\t\t# {0} < {1}", register, rightRegister); programBuilder.AppendLine(); registerFile.FreeRegister(rightRegister); } labelCount += 1; programBuilder.AppendFormat("\t jge .L{0}", labelCount); programBuilder.AppendFormat("\t\t# Salta al label {0} si es >=.", labelCount); programBuilder.AppendLine(); programBuilder.AppendFormat(".L{0}", labelCount); programBuilder.AppendLine(); return register; } else if (expr is LessOrEqualToExpression) { if (string.IsNullOrEmpty(registerToUse)) { registerToUse = registerFile.FirstAvailableRegister(); } var add = expr as LessOrEqualToExpression; var leftRegister = WriteExpr(add.Right, registerFile, programBuilder); var register = registerToUse; programBuilder.AppendFormat("\t mov {0}, {1}", register, leftRegister); programBuilder.AppendFormat("\t# Mueve {0} a {1} para hacer el cmp", register, leftRegister); programBuilder.AppendLine(); registerFile.FreeRegister(leftRegister); var rightRegister = WriteExpr(add.Left, registerFile, programBuilder, register); if (register != rightRegister) { programBuilder.AppendFormat("\t cmp {0}, {1}", register, rightRegister); programBuilder.AppendFormat("\t\t# {0} < {1}", register, rightRegister); programBuilder.AppendLine(); registerFile.FreeRegister(rightRegister); } labelCount += 1; programBuilder.AppendFormat("\t jg .L{0}", labelCount); programBuilder.AppendFormat("\t\t# Salta al label {0} si es >=.", labelCount); programBuilder.AppendLine(); programBuilder.AppendFormat(".L{0}", labelCount); programBuilder.AppendLine(); return register; } else if (expr is GreaterThanExpression) { if (string.IsNullOrEmpty(registerToUse)) { registerToUse = registerFile.FirstAvailableRegister(); } var add = expr as GreaterThanExpression; var leftRegister = WriteExpr(add.Right, registerFile, programBuilder); var register = registerToUse; programBuilder.AppendFormat("\t mov {0}, {1}", register, leftRegister); programBuilder.AppendFormat("\t# Mueve {0} a {1} para hacer el cmp", register, leftRegister); programBuilder.AppendLine(); registerFile.FreeRegister(leftRegister); var rightRegister = WriteExpr(add.Left, registerFile, programBuilder, register); if (register != rightRegister) { programBuilder.AppendFormat("\t cmp {0}, {1}", register, rightRegister); programBuilder.AppendFormat("\t\t# {0} < {1}", register, rightRegister); programBuilder.AppendLine(); registerFile.FreeRegister(rightRegister); } labelCount += 1; programBuilder.AppendFormat("\t jle .L{0}", labelCount); programBuilder.AppendFormat("\t\t# Salta al label {0} si es <.", labelCount); programBuilder.AppendLine(); programBuilder.AppendFormat(".L{0}", labelCount); programBuilder.AppendLine(); return register; } else if (expr is GreaterOrEqualExpression) { if (string.IsNullOrEmpty(registerToUse)) { registerToUse = registerFile.FirstAvailableRegister(); } var add = expr as GreaterOrEqualExpression; var leftRegister = WriteExpr(add.Right, registerFile, programBuilder); var register = registerToUse; programBuilder.AppendFormat("\t mov {0}, {1}", register, leftRegister); programBuilder.AppendFormat("\t# Mueve {0} a {1} para hacer el cmp", register, leftRegister); programBuilder.AppendLine(); registerFile.FreeRegister(leftRegister); var rightRegister = WriteExpr(add.Left, registerFile, programBuilder, register); if (register != rightRegister) { programBuilder.AppendFormat("\t cmp {0}, {1}", register, rightRegister); programBuilder.AppendFormat("\t\t# {0} < {1}", register, rightRegister); programBuilder.AppendLine(); registerFile.FreeRegister(rightRegister); } labelCount += 1; programBuilder.AppendFormat("\t jl .L{0}", labelCount); programBuilder.AppendFormat("\t\t# Salta al label {0} si es <.", labelCount); programBuilder.AppendLine(); programBuilder.AppendFormat(".L{0}", labelCount); programBuilder.AppendLine(); return register; } else if (expr is EqualsExpression) { if (string.IsNullOrEmpty(registerToUse)) { registerToUse = registerFile.FirstAvailableRegister(); } var add = expr as EqualsExpression; var leftRegister = WriteExpr(add.Right, registerFile, programBuilder); var register = registerToUse; programBuilder.AppendFormat("\t mov {0}, {1}", register, leftRegister); programBuilder.AppendFormat("\t# Mueve {0} a {1} para hacer el cmp", register, leftRegister); programBuilder.AppendLine(); registerFile.FreeRegister(leftRegister); var rightRegister = WriteExpr(add.Left, registerFile, programBuilder, register); if (register != rightRegister) { programBuilder.AppendFormat("\t cmp {0}, {1}", register, rightRegister); programBuilder.AppendFormat("\t\t# {0} < {1}", register, rightRegister); programBuilder.AppendLine(); registerFile.FreeRegister(rightRegister); } labelCount += 1; programBuilder.AppendFormat("\t jne .L{0}", labelCount); programBuilder.AppendFormat("\t\t# Salta al label {0} si es <.", labelCount); programBuilder.AppendLine(); return register; } #endregion #region LOGICAL_EXPR else if (expr is LogicalOrExpression) { if (string.IsNullOrEmpty(registerToUse)) { registerToUse = registerFile.FirstAvailableRegister(); } var add = expr as BitwiseAndExpression; var leftRegister = WriteExpr(add.Right, registerFile, programBuilder); var register = registerToUse; programBuilder.AppendFormat("\t cmp {0}, 0", leftRegister); programBuilder.AppendFormat("\t\t# Compara {0} con 0", leftRegister); programBuilder.AppendLine(); programBuilder.AppendFormat("\t jne .L{0}", labelCount); programBuilder.AppendLine(); registerFile.FreeRegister(leftRegister); var rightRegister = WriteExpr(add.Left, registerFile, programBuilder, register); if (register != rightRegister) { programBuilder.AppendFormat("\t cmp {0}, 0", rightRegister); programBuilder.AppendFormat("\t\t# Compara {0} con 0", rightRegister); programBuilder.AppendLine(); programBuilder.AppendFormat("\t jne .L{0}", labelCount); programBuilder.AppendLine(); registerFile.FreeRegister(rightRegister); } return register; } else if (expr is LogicAndExpression) { { registerToUse = registerFile.FirstAvailableRegister(); } var add = expr as BitwiseAndExpression; var leftRegister = WriteExpr(add.Right, registerFile, programBuilder); var register = registerToUse; programBuilder.AppendFormat("\t cmp {0}, 0", leftRegister); programBuilder.AppendFormat("\t\t# Compara {0} con 0", leftRegister); programBuilder.AppendLine(); programBuilder.AppendFormat("\t je .L{0}", labelCount); programBuilder.AppendLine(); registerFile.FreeRegister(leftRegister); var rightRegister = WriteExpr(add.Left, registerFile, programBuilder, register); if (register != rightRegister) { programBuilder.AppendFormat("\t cmp {0}, 0", rightRegister); programBuilder.AppendFormat("\t\t# Compara {0} con 0", rightRegister); programBuilder.AppendLine(); programBuilder.AppendFormat("\t je .L{0}", labelCount); programBuilder.AppendLine(); registerFile.FreeRegister(rightRegister); } return register; #endregion #region ASSIGN_EXPRESSIONS } else if (expr is AdditionAssignmentExpression) { var add = expr as AdditionAssignmentExpression; var leftRegister = WriteExpr(add.Right, registerFile, programBuilder); programBuilder.AppendFormat("\t add {0}, {1}", leftRegister, add.Left); programBuilder.AppendFormat("\t# {0}", expr.ToString()); programBuilder.AppendLine(); } else if (expr is SubtractionAsigExpression) { var sub = expr as SubtractionAsigExpression; var leftRegister = WriteExpr(sub.Right, registerFile, programBuilder); programBuilder.AppendFormat("\t sub {0}, {1}", leftRegister, sub.Left); programBuilder.AppendFormat("\t# {0}", expr.ToString()); programBuilder.AppendLine(); } else if (expr is MultiplicationAsigExpression) { var sub = expr as MultiplicationAsigExpression; var leftRegister = WriteExpr(sub.Right, registerFile, programBuilder); programBuilder.AppendFormat("\t mul {0}, {1}", leftRegister, sub.Left); programBuilder.AppendFormat("\t# {0}", expr.ToString()); programBuilder.AppendLine(); } else if (expr is DivisionAsigExpression) { var sub = expr as DivisionAsigExpression; var leftRegister = WriteExpr(sub.Right, registerFile, programBuilder); programBuilder.AppendFormat("\t div {0}, {1}", leftRegister, sub.Left); programBuilder.AppendFormat("\t# {0}", expr.ToString()); programBuilder.AppendLine(); } else if (expr is AssignExpression) { var assign = expr as AssignExpression; foreach (var id in registerFile.stack) { if (id.Key == assign.Left.ToString()) { savedValue = id.Key; inStack = true; } } if (inStack == false) { var pos = registerFile.stack.Last().Value.positioninStack; registerFile.stackx86.idValue = assign.Right.ToString(); savedValue = assign.Left.ToString(); registerFile.stackx86.positioninStack = Convert.ToString(Convert.ToInt32(pos) + 4); registerFile.stack.Add(assign.Left.ToString(), registerFile.stackx86); inStack = true; } var assignRegister = WriteExpr(assign.Right, registerFile, programBuilder); if (assign.Left is PointerArrayAccessExpr) { isArray = true; registerFile.FreeRegister(assignRegister); WriteExpr(assign.Left, registerFile, programBuilder); return assignRegister; } else { if (inStack == false) { programBuilder.AppendFormat("\t mov {0}, {1}", assignRegister, assign.Left.ToString()); programBuilder.AppendLine(); } inStack = false; return assignRegister; } } #endregion #region POST_PRE_INCREMENT_DECREMENT else if (expr is PostIncrementExpression) { var postIncrement = expr as PostIncrementExpression; var register = registerFile.RegisterPosition(postIncrement.Expression.ToString()); programBuilder.AppendFormat("\t add DWORD PTR [epb-{0}], 1", register); programBuilder.AppendFormat("\t# {0}", expr.ToString()); programBuilder.AppendLine(); return register; } else if (expr is PreIncrementExpression) { } else if (expr is PostDecrementExpression) { } else if (expr is PreDecrementExpression) { } #endregion #region FUNTIONCALL_EXPRESSION else if (expr is FunctionCallExpression) { WriteFunctionCallExp(expr as FunctionCallExpression, programBuilder); } #endregion #region ARRAY_EXPRESSION else if (expr is PointerArrayAccessExpr) { } #endregion return registerFile.FirstAvailableRegister(); }