package Compiler; import java.util.ArrayList; import java.util.List; import Compiler.Expression.*; import Compiler.Statement.*; public class Translator{ List CCode = new ArrayList<>(); private Environment environment = new Environment(); public List compileToC(List statements){ CCode.add("#include "); CCode.add("#include "); CCode.add("int main(){"); try{ for (Statement statement: statements){ evaluateStatement(statement); } } catch (Error e){ } CCode.add("}"); for(String t:CCode){ System.out.println(t); } System.out.println(""); return CCode; } private void evaluateStatement(Statement statement){ switch(statement.getStatmentType()){ case "exprStmt": evalExpressionStatement((ExpressionStatement)statement); break; case "varDec": evalVariableDeclaration((VariableDeclaration)statement); break; case "stringDec": evalStringDeclaration((StringDeclaration)statement); break; case "block": evalBlockStatement((BlockStatement)statement); break; case "print": evalPrintStatement((PrintStatement)statement); break; case "ifStmt": evalIfStatement((IfStatement)statement); break; case "doStmt": evalDoStatement((DoStatement)statement); break; case "dowhileStmt": evalDoWhileStatement((DoWhileStatement)statement); break; } } private void evalExpressionStatement(ExpressionStatement stmt){ evaluateExpression(stmt.expr); } private void evalStringDeclaration(StringDeclaration stringdec){ environment.defineVariable(stringdec.name.text, "string"); int size = (int)((Expression.Literal)stringdec.length).value.value; size++; CCode.add("char "+stringdec.name.text+"["+size+"];"); } private void evalVariableDeclaration(VariableDeclaration vardec){ environment.defineVariable(vardec.name.text, vardec.type); if(vardec.type.equals("int")){ CCode.add("int "+vardec.name.text+";"); } else if(vardec.type.equals("real")){ CCode.add("float "+vardec.name.text+";"); } } private void evalBlockStatement(BlockStatement block){ for(Statement stmt:block.statements){ evaluateStatement(stmt); } } private void evalPrintStatement(PrintStatement print){ String types=""; String values=""; boolean first=true; for(Expression expr:print.exprList){ if(!first){ values+=","; }else{ first=false; } String exprType=""; if(expr instanceof Expression.Literal){ exprType=((Expression.Literal)expr).type; } else if (expr instanceof Expression.Variable){ exprType=(String)environment.getVariable((((Expression.Variable)expr).name).text); } if (exprType.equals("int")){ types+="%d"; } else if (exprType.equals("double")){ types+="%f"; } else if (exprType.equals("string")){ types+="%s"; } values+=evaluateExpression(expr); } types+="\\n"; CCode.add("printf(\""+types+"\","+values+");"); } private void evalIfStatement(IfStatement ifstatement){ CCode.add("if("+evaluateExpression(ifstatement.condition)+"){"); evaluateStatement(ifstatement.ifBlock); if(!(ifstatement.elseBlock==null)){ CCode.add("}"); CCode.add("else {"); evaluateStatement(ifstatement.elseBlock); } CCode.add("}"); } private void evalDoStatement(DoStatement dostatement){ String start = evaluateExpression(dostatement.variable)+"="+evaluateExpression(dostatement.start); String stop = evaluateExpression(dostatement.variable)+"<="+evaluateExpression(dostatement.stop); String step = evaluateExpression(dostatement.variable)+"++"; if(!(dostatement.step==null)){ step = evaluateExpression(dostatement.variable)+"+="+evaluateExpression(dostatement.step); } CCode.add("for("+start+";"+stop+";"+step+"){"); evaluateStatement(dostatement.codeBlock); CCode.add("}"); } private void evalDoWhileStatement(DoWhileStatement dowhilestatement){ CCode.add("while("+evaluateExpression(dowhilestatement.condition)+"){"); evaluateStatement(dowhilestatement.codeBlock); CCode.add("}"); } private String evaluateExpression(Expression expression){ switch(expression.getExpressionType()){ case "binary": return evaluateBinaryExpression((Binary)expression); case "literal": return evaluateLiteralExpression((Literal)expression); case "bracket": return evaluateBracketedExpression((BracketedExpression)expression); case "assign": evaluateAssignmentExpression((AssignmentExpression)expression); return ""; case "var": return evaluateVariableExpression((Variable)expression); default: return null; } } private String evaluateBinaryExpression(Binary expr){ switch (expr.op.type){ case PLUS: //return "leftEval+rightEval" return evaluateExpression(expr.left)+"+"+evaluateExpression(expr.right); case STAR: return evaluateExpression(expr.left)+"*"+evaluateExpression(expr.right); case MINUS: return evaluateExpression(expr.left)+"-"+evaluateExpression(expr.right); case SLASH: return evaluateExpression(expr.left)+"/"+evaluateExpression(expr.right); case GREATER: return evaluateExpression(expr.left)+">"+evaluateExpression(expr.right); case LESS: return evaluateExpression(expr.left)+"<"+evaluateExpression(expr.right); case EQUALITY: return evaluateExpression(expr.left)+"=="+evaluateExpression(expr.right); default: break; } return null; } private String evaluateLiteralExpression(Literal expr){ return (expr.value.value).toString(); } private String evaluateBracketedExpression(BracketedExpression expr){ return evaluateExpression(expr.expr); } private void evaluateAssignmentExpression(AssignmentExpression expr){ if(expr.value instanceof Expression.Literal){ if(((Expression.Literal)expr.value).type.equals("string")){ CCode.add("strcpy("+expr.name.text+","+evaluateExpression(expr.value)+");"); } CCode.add(expr.name.text+"="+evaluateExpression(expr.value)+";"); } else{ CCode.add(expr.name.text+"="+evaluateExpression(expr.value)+";"); } } private String evaluateVariableExpression(Variable expr){ return expr.name.text; } }