compilers:matlab_to_llvm
Return to Home page
If you found any error, or if you want to partecipate to the editing of this wiki, please contact: admin [at] skenz.it
You can reuse, distribute or modify the content of this page, but you must cite in any document (or webpage) this url: https://www.skenz.it/compilers/matlab_to_llvm?do=diff&rev2%5B0%5D=1664053240&rev2%5B1%5D=1664053528&difftype=sidebyside
Differences
This shows you the differences between two versions of the page.
— | compilers:matlab_to_llvm [2024/04/08 22:34] (current) – created - external edit 127.0.0.1 | ||
---|---|---|---|
Line 1: | Line 1: | ||
+ | ====== From Matlab to LLVM ====== | ||
+ | |||
+ | ===== Background ===== | ||
+ | This page shows the implementation of a compiler that recognizes and translates part of the Matlab programming language into the LLVM IR syntax (more information about LLVM can be found [[https:// | ||
+ | ==== Implemented features ==== | ||
+ | List of the Matlab features Implemented | ||
+ | |||
+ | | ||
+ | * Basic data types | ||
+ | * int | ||
+ | * double | ||
+ | * arrays | ||
+ | * matrix | ||
+ | | ||
+ | * arithmetic: | ||
+ | * addition (+) | ||
+ | * subtraction (-) | ||
+ | * multiplication (*) | ||
+ | * multiplication element by element (.*) | ||
+ | * division(/) | ||
+ | * division element by element (./) | ||
+ | * comparison: | ||
+ | * equality ( == ) | ||
+ | * greater than (>) | ||
+ | * less than (<) | ||
+ | * greater than equal to (>= or = >) | ||
+ | * less than equal to (< = or =<) | ||
+ | * logical: | ||
+ | * AND (&) | ||
+ | * OR (|) | ||
+ | **Sub block of codes** | ||
+ | * if instruction | ||
+ | * else instruction | ||
+ | * for loop | ||
+ | * while loop | ||
+ | | ||
+ | * int type parameters | ||
+ | * int return type | ||
+ | | ||
+ | * disp/ | ||
+ | * with variables and text (fprintf) and with only one variable (disp) | ||
+ | |||
+ | ===== Compiler ===== | ||
+ | The compiler is built of two parts: a scanner and parser | ||
+ | |||
+ | ===== Scanner ===== | ||
+ | |||
+ | The scanner is able to recognize and retrieve tokens (terminal symbols) to the parser coupled with an object containing a value that represents the token. It identifies integers, doubles and ids (that will be used for variables, function names, etc...) and other significant Matlab keywords like: | ||
+ | |||
+ | * '' | ||
+ | * '' | ||
+ | * '' | ||
+ | * '' | ||
+ | * '' | ||
+ | * '' | ||
+ | * '' | ||
+ | * '' | ||
+ | |||
+ | And other syntax elements like punctuation and other symbols. | ||
+ | |||
+ | ==== Snippet of Matlab Scanner ==== | ||
+ | < | ||
+ | nl = \r|\n|\r\n | ||
+ | ws = [ \t] | ||
+ | id = [A-Za-z][A-Za-z0-9_]* | ||
+ | integer = ([1-9][0-9]*|0) | ||
+ | double = (([0-9]+\.[0-9]*) | ([0-9]*\.[0-9]+)) (e|E(' | ||
+ | |||
+ | %% | ||
+ | |||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | "/" | ||
+ | " | ||
+ | "<" | ||
+ | ">" | ||
+ | "< | ||
+ | " | ||
+ | "> | ||
+ | " | ||
+ | "&" | ||
+ | " | ||
+ | " | ||
+ | |||
+ | " | ||
+ | " | ||
+ | |||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | ";" | ||
+ | "," | ||
+ | ":" | ||
+ | |||
+ | {id} {return symbol(sym.ID, | ||
+ | {integer} {return symbol(sym.INT, | ||
+ | {double} | ||
+ | </ | ||
+ | |||
+ | ===== Parser ===== | ||
+ | |||
+ | The parser can take as input the tokens provided by the scanner and recognize the main grammatical rules of Matlab language. As a result, the LLVM IR code is produced. | ||
+ | |||
+ | ==== Data structures ==== | ||
+ | |||
+ | This snippet shows all variables and classes used to support the parser on the creation of the output program: | ||
+ | |||
+ | < | ||
+ | |||
+ | public HashMap <String, InfoVar> symbolTable; | ||
+ | |||
+ | public HashMap <String, InfoFun> functionTable; | ||
+ | |||
+ | public boolean isCorrect = true; | ||
+ | |||
+ | public StringBuffer stamentsBuff; | ||
+ | |||
+ | public ArrayList< | ||
+ | |||
+ | public int var_count = 0; | ||
+ | |||
+ | public int str_label = 0; | ||
+ | |||
+ | public int sub_label = 0; | ||
+ | |||
+ | public int else_label = 1; | ||
+ | |||
+ | public int tot_sub_label = 0; | ||
+ | |||
+ | public int cmp_count=0; | ||
+ | |||
+ | public boolean activate_while = false; | ||
+ | |||
+ | public boolean desctivate_while = false; | ||
+ | |||
+ | public boolean activate_for = false; | ||
+ | |||
+ | public boolean desctivate_for = false; | ||
+ | |||
+ | public String ret_id = ""; | ||
+ | |||
+ | public BufferedWriter bwr; | ||
+ | |||
+ | public int genVarCount(){ | ||
+ | |||
+ | var_count++; | ||
+ | |||
+ | return var_count; | ||
+ | }; | ||
+ | |||
+ | public int genStrCount(){ | ||
+ | |||
+ | str_label++; | ||
+ | |||
+ | return str_label; | ||
+ | }; | ||
+ | |||
+ | public class InfoVar{ | ||
+ | |||
+ | public String reg_id; //First label assigned to the variable | ||
+ | public String load_to; //Reg id of the one who loaded an existing variable (default self reg_id) | ||
+ | public String type; //i32, double | ||
+ | public String value; //The real value of the variable (ex: 1 or 1.0) | ||
+ | public Integer align; | ||
+ | public Integer size1; //If the variable is an array then this is its size, otherwise size1 = -1 | ||
+ | public Integer size2; //If the variable is a matrix then this is its size, otherwise size1 = -1 | ||
+ | public boolean just_created; | ||
+ | |||
+ | public InfoVar() | ||
+ | { | ||
+ | reg_id = Integer.toString(genVarCount()); | ||
+ | load_to = Integer.toString(var_count); | ||
+ | size1 = size2 = -1; | ||
+ | } | ||
+ | InfoVar(Integer value, String type, Integer align) | ||
+ | { | ||
+ | this.just_created = true; | ||
+ | this.value = Integer.toString(value); | ||
+ | this.type = type; | ||
+ | this.align = align; | ||
+ | } | ||
+ | |||
+ | InfoVar(Double value, String type, Integer align) | ||
+ | { | ||
+ | this.just_created = true; | ||
+ | this.value = Double.toString(value); | ||
+ | this.type = type; | ||
+ | this.align = align; | ||
+ | } | ||
+ | |||
+ | |||
+ | } | ||
+ | |||
+ | public class InfoFun{ | ||
+ | |||
+ | ArrayList< | ||
+ | Integer numParam; | ||
+ | String funRet; | ||
+ | |||
+ | public InfoFun(ArrayList< | ||
+ | { | ||
+ | this.funParam = funParam; | ||
+ | this.numParam = funParam.size(); | ||
+ | this.funRet = " | ||
+ | } | ||
+ | </ | ||
+ | |||
+ | |||
+ | * '' | ||
+ | * '' | ||
+ | * '' | ||
+ | * '' | ||
+ | * '' | ||
+ | * '' | ||
+ | * '' | ||
+ | * '' | ||
+ | * '' | ||
+ | |||
+ | | ||
+ | * '' | ||
+ | * '' | ||
+ | * '' | ||
+ | |||
+ | * '' | ||
+ | * '' | ||
+ | * '' | ||
+ | * '' | ||
+ | * '' | ||
+ | * '' | ||
+ | * '' | ||
+ | * '' | ||
+ | * '' | ||
+ | * '' | ||
+ | |||
+ | ==== Grammar start ==== | ||
+ | |||
+ | The grammar starts with the main symbol prog and writes down by stamentsBuff that therefore is displayed | ||
+ | in the output file output.ll. The non terminal symbol function_defs is read by first so all the functions | ||
+ | definitions are goint to be displayed at the beggining before the @main, at the end of each function definition | ||
+ | the var_count is reset so the main function can use the new registers. Between functions and main there are the string | ||
+ | declarations to be consequently printed. | ||
+ | |||
+ | <code java> | ||
+ | prog ::= function_defs {: | ||
+ | if(parser.isCorrect) | ||
+ | { | ||
+ | bwr.write(" | ||
+ | |||
+ | bwr.write(stamentsBuff.toString()); | ||
+ | |||
+ | } | ||
+ | else | ||
+ | System.out.println(" | ||
+ | var_count = 0; | ||
+ | stamentsBuff.setLength(0); | ||
+ | |||
+ | : | ||
+ | if(parser.isCorrect) | ||
+ | { | ||
+ | for(String s : stringStatements) | ||
+ | { | ||
+ | bwr.write(s+" | ||
+ | } | ||
+ | |||
+ | bwr.write(" | ||
+ | |||
+ | bwr.write(stamentsBuff.toString()); | ||
+ | |||
+ | bwr.write(" | ||
+ | bwr.flush(); | ||
+ | |||
+ | bwr.close(); | ||
+ | } | ||
+ | else | ||
+ | System.out.println(" | ||
+ | |||
+ | :}; | ||
+ | |||
+ | </ | ||
+ | |||
+ | ==== Practical examples ==== | ||
+ | |||
+ | === Recognition of constants, variable, arrays and matrices ID === | ||
+ | In this example it can be seen that when a for or while feature is actived it is displayed | ||
+ | the their corresponded labels before any register is be load | ||
+ | <code java> | ||
+ | val ::= ID:x {: | ||
+ | if(!parser.symbolTable.containsKey(x)) | ||
+ | { | ||
+ | pSemError(" | ||
+ | }else{ | ||
+ | RESULT = parser.symbolTable.get(x); | ||
+ | //To load the variables inside the " | ||
+ | if(activate_while){ | ||
+ | tot_sub_label++; | ||
+ | sub_label = tot_sub_label; | ||
+ | stamentsBuff.append(" | ||
+ | stamentsBuff.append(" | ||
+ | activate_while = false; | ||
+ | desctivate_while = true; | ||
+ | } | ||
+ | //To load the variables inside the " | ||
+ | if(activate_for){ | ||
+ | tot_sub_label++; | ||
+ | sub_label = tot_sub_label; | ||
+ | stamentsBuff.append(" | ||
+ | stamentsBuff.append(" | ||
+ | activate_for = false; | ||
+ | } | ||
+ | stamentsBuff.append(" | ||
+ | RESULT.load_to = Integer.toString(var_count); | ||
+ | } | ||
+ | |||
+ | :} | ||
+ | | ID:x RO arit_op:y RC {: | ||
+ | if(!parser.symbolTable.containsKey(x)) | ||
+ | { | ||
+ | pSemError(" | ||
+ | }else{ | ||
+ | RESULT = parser.symbolTable.get(x); | ||
+ | if(!y.just_created) | ||
+ | stamentsBuff.append(" | ||
+ | else | ||
+ | stamentsBuff.append(" | ||
+ | stamentsBuff.append(" | ||
+ | RESULT.load_to = Integer.toString(var_count); | ||
+ | } | ||
+ | :} | ||
+ | | ID:x RO arit_op:i CM arit_op:j RC {: | ||
+ | if(!parser.symbolTable.containsKey(x)) | ||
+ | { | ||
+ | pSemError(" | ||
+ | }else{ | ||
+ | RESULT = parser.symbolTable.get(x); | ||
+ | stamentsBuff.append(" | ||
+ | stamentsBuff.append(" | ||
+ | stamentsBuff.append(" | ||
+ | RESULT.load_to = Integer.toString(var_count); | ||
+ | } | ||
+ | :} | ||
+ | | INT:x {: | ||
+ | RESULT = new InfoVar(x, " | ||
+ | :} | ||
+ | | DOUBLE:x {: | ||
+ | RESULT = new InfoVar(x, " | ||
+ | :} | ||
+ | ; | ||
+ | //Elements of vectors of a matrix | ||
+ | matrix_elements ::= matrix_elements: | ||
+ | x.add(y); | ||
+ | RESULT = x; | ||
+ | :} | ||
+ | | vect_elements: | ||
+ | RESULT = new ArrayList< | ||
+ | RESULT.add(x); | ||
+ | :} | ||
+ | ; | ||
+ | //Elements of variables or constants of a vector | ||
+ | vect_elements ::= vect_elements: | ||
+ | x.add(y); | ||
+ | RESULT = x; | ||
+ | :} | ||
+ | | elem:x {: | ||
+ | RESULT = new ArrayList< | ||
+ | RESULT.add(x); | ||
+ | :} | ||
+ | ; | ||
+ | </ | ||
+ | |||
+ | === Matrix and array definition === | ||
+ | |||
+ | Matrices definitions use also the array (vector) definitions since is just a list a of their | ||
+ | definitions. In the same way, the definition of the arrays is a list of InfoVar | ||
+ | |||
+ | <code java> | ||
+ | /Vector | ||
+ | | ID:id EQ SO vect_elements: | ||
+ | InfoVar nInfoVar = new InfoVar(); | ||
+ | Integer vector_Register = Integer.parseInt(nInfoVar.reg_id); | ||
+ | stamentsBuff.append(" | ||
+ | for(int i = 0; i< | ||
+ | { | ||
+ | InfoVar xTy = x.get(i); | ||
+ | stamentsBuff.append(" | ||
+ | stamentsBuff.append(" | ||
+ | } | ||
+ | |||
+ | nInfoVar.type = x.get(0).type; | ||
+ | nInfoVar.align = x.get(0).align; | ||
+ | nInfoVar.size1 = x.size(); | ||
+ | addSymbol(id, | ||
+ | |||
+ | :} | ||
+ | //Vector element assignment | ||
+ | | ID:id RO arit_op:x RC EQ arit_op:y {: | ||
+ | InfoVar idVar = parser.symbolTable.get(id); | ||
+ | if(!x.just_created) | ||
+ | stamentsBuff.append(" | ||
+ | else | ||
+ | stamentsBuff.append(" | ||
+ | stamentsBuff.append(" | ||
+ | :} | ||
+ | //Matrix | ||
+ | | ID:id EQ SO matrix_elements: | ||
+ | |||
+ | InfoVar nInfoVar = new InfoVar(); | ||
+ | Integer matrix_Register = Integer.parseInt(nInfoVar.reg_id); | ||
+ | stamentsBuff.append(" | ||
+ | for(int i = 0; i< | ||
+ | { | ||
+ | for(int j = 0; j< | ||
+ | { | ||
+ | InfoVar xTy = x.get(i).get(j); | ||
+ | stamentsBuff.append(" | ||
+ | stamentsBuff.append(" | ||
+ | stamentsBuff.append(" | ||
+ | } | ||
+ | } | ||
+ | |||
+ | nInfoVar.type = x.get(0).get(0).type; | ||
+ | nInfoVar.align = x.get(0).get(0).align; | ||
+ | nInfoVar.size1 = x.size(); | ||
+ | nInfoVar.size2 = x.get(0).size(); | ||
+ | addSymbol(id, | ||
+ | |||
+ | :} | ||
+ | //Matrix element assignment | ||
+ | | ID:id RO arit_op:i CM arit_op:j RC EQ arit_op:x {: | ||
+ | InfoVar idVar = parser.symbolTable.get(id); | ||
+ | stamentsBuff.append(" | ||
+ | stamentsBuff.append(" | ||
+ | stamentsBuff.append(" | ||
+ | :} | ||
+ | </ | ||
+ | |||
+ | Here is an example: | ||
+ | |||
+ | <code java> | ||
+ | d = [1 2 4 ; 5 6 7] | ||
+ | </ | ||
+ | |||
+ | And here is the LLVM transformation: | ||
+ | <code java> | ||
+ | %7 = alloca [2 x [3 x i32]], align 4 | ||
+ | %8 = getelementptr inbounds [2 x [3 x i32]], [2 x [3 x i32]]* %7, i32 0, i32 0 | ||
+ | %9 = getelementptr inbounds [3 x i32], [3 x i32]* %8, i32 0, i32 0 | ||
+ | store i32 1, i32* %9, align 4 | ||
+ | %10 = getelementptr inbounds [2 x [3 x i32]], [2 x [3 x i32]]* %7, i32 0, i32 0 | ||
+ | %11 = getelementptr inbounds [3 x i32], [3 x i32]* %10, i32 0, i32 1 | ||
+ | store i32 2, i32* %11, align 4 | ||
+ | %12 = getelementptr inbounds [2 x [3 x i32]], [2 x [3 x i32]]* %7, i32 0, i32 0 | ||
+ | %13 = getelementptr inbounds [3 x i32], [3 x i32]* %12, i32 0, i32 2 | ||
+ | store i32 4, i32* %13, align 4 | ||
+ | %14 = getelementptr inbounds [2 x [3 x i32]], [2 x [3 x i32]]* %7, i32 0, i32 1 | ||
+ | %15 = getelementptr inbounds [3 x i32], [3 x i32]* %14, i32 0, i32 0 | ||
+ | store i32 5, i32* %15, align 4 | ||
+ | %16 = getelementptr inbounds [2 x [3 x i32]], [2 x [3 x i32]]* %7, i32 0, i32 1 | ||
+ | %17 = getelementptr inbounds [3 x i32], [3 x i32]* %16, i32 0, i32 1 | ||
+ | store i32 6, i32* %17, align 4 | ||
+ | %18 = getelementptr inbounds [2 x [3 x i32]], [2 x [3 x i32]]* %7, i32 0, i32 1 | ||
+ | %19 = getelementptr inbounds [3 x i32], [3 x i32]* %18, i32 0, i32 2 | ||
+ | store i32 7, i32* %19, align 4 | ||
+ | </ | ||
+ | |||
+ | ==== Function implementation ==== | ||
+ | |||
+ | The following piece of code represents the LLVM IR code of the functions, this only accepts integers parameters and integer returns | ||
+ | |||
+ | <code java> | ||
+ | function_def ::= FUNCT ID:r EQ ID:f RO parameters: | ||
+ | |||
+ | stamentsBuff.append(" | ||
+ | for(int i = 0; i< | ||
+ | { | ||
+ | genVarCount(); | ||
+ | stamentsBuff.append(" | ||
+ | if(i != (par.size()-1)) | ||
+ | stamentsBuff.append(", | ||
+ | else | ||
+ | stamentsBuff.append(" | ||
+ | } | ||
+ | Integer currentReg; | ||
+ | for(int i = 0; i< | ||
+ | { | ||
+ | currentReg = genVarCount() ; | ||
+ | stamentsBuff.append(" | ||
+ | stamentsBuff.append(" | ||
+ | InfoVar newParam = new InfoVar(); | ||
+ | var_count--; | ||
+ | newParam.reg_id = Integer.toString(currentReg); | ||
+ | newParam.type = " | ||
+ | newParam.align = 4; | ||
+ | addSymbol(par.get(i), | ||
+ | } | ||
+ | ArrayList< | ||
+ | for(int i = 0; i< | ||
+ | { | ||
+ | parametersType.add(" | ||
+ | } | ||
+ | InfoFun funct = new InfoFun(parametersType); | ||
+ | functionTable.put(f, | ||
+ | |||
+ | ret_id = r; | ||
+ | |||
+ | :} RC statements END{: | ||
+ | stamentsBuff.append(" | ||
+ | var_count = 0; | ||
+ | symbolTable.clear(); | ||
+ | :}; | ||
+ | |||
+ | param ::= ID:x {:RESULT = x;:} | ; | ||
+ | |||
+ | parameters ::= parameters: | ||
+ | l.add(x); | ||
+ | RESULT = l; | ||
+ | :} | ||
+ | | param:x{: | ||
+ | RESULT = new ArrayList< | ||
+ | RESULT.add(x); | ||
+ | |||
+ | :} | ||
+ | ; | ||
+ | </ | ||
+ | |||
+ | ==== Print instruction ==== | ||
+ | |||
+ | There are two print instructions implemented, | ||
+ | either string words with the function ManageString or variables (IDs for simple variables, arrays or matrices) with the function ManageStringID; | ||
+ | The Matlab instruction " | ||
+ | the reference of the variables (only single variables). | ||
+ | |||
+ | <code java> | ||
+ | //Print instruction | ||
+ | print_instr ::= DISP RO STRING:x RC{: | ||
+ | ManageString(x); | ||
+ | :} | ||
+ | |DISP RO ID:x RC{: | ||
+ | ManageStringID(x); | ||
+ | :} | ||
+ | | PRINT RO STRING:s CM id_list:x RC{: | ||
+ | ManageString(s, | ||
+ | :} | ||
+ | | print_keyw error {: | ||
+ | ; | ||
+ | |||
+ | id_list ::= id_list:x CM ID:i{: | ||
+ | x.add(i); | ||
+ | RESULT = x; | ||
+ | :} | ||
+ | |ID:x{: | ||
+ | RESULT = new ArrayList< | ||
+ | RESULT.add(x); | ||
+ | :} | ||
+ | ; | ||
+ | |||
+ | </ | ||
+ | |||
+ | Here are the three ManageString functions | ||
+ | <code java> | ||
+ | public void ManageString(String x){ | ||
+ | int label = genStrCount(); | ||
+ | String s = x; | ||
+ | s = s.replace(" | ||
+ | s = s + " | ||
+ | Integer length = s.length()-4; | ||
+ | parser.stringStatements.add(" | ||
+ | stamentsBuff.append((" | ||
+ | } | ||
+ | |||
+ | public void ManageStringID(String x){ | ||
+ | |||
+ | InfoVar infoVar = parser.symbolTable.get(x); | ||
+ | if(!parser.symbolTable.containsKey(x)) | ||
+ | { | ||
+ | pSemError(" | ||
+ | }else{ | ||
+ | if(infoVar.size1==-1){ | ||
+ | int label = genStrCount(); | ||
+ | String s = " | ||
+ | Integer length = s.length()-4; | ||
+ | stamentsBuff.append(" | ||
+ | infoVar.load_to = var_count+""; | ||
+ | parser.stringStatements.add(" | ||
+ | stamentsBuff.append((" | ||
+ | }else if(infoVar.size1!=1 && infoVar.size2==-1){ | ||
+ | int label = genStrCount(); | ||
+ | String s = ""; | ||
+ | ArrayList< | ||
+ | for(int i = 0;i < infoVar.size1-1; | ||
+ | s = s+" %" | ||
+ | stamentsBuff.append(" | ||
+ | stamentsBuff.append(" | ||
+ | loads_reg.add(var_count); | ||
+ | } | ||
+ | s = s+" %" | ||
+ | stamentsBuff.append(" | ||
+ | stamentsBuff.append(" | ||
+ | loads_reg.add(var_count); | ||
+ | Integer length = s.length()-4; | ||
+ | parser.stringStatements.add(" | ||
+ | stamentsBuff.append((" | ||
+ | stamentsBuff.append(", | ||
+ | for (int i = 0; i < loads_reg.size(); | ||
+ | { | ||
+ | if(i==0) | ||
+ | stamentsBuff.append(infoVar.type+" | ||
+ | else | ||
+ | stamentsBuff.append(", | ||
+ | } | ||
+ | stamentsBuff.append(" | ||
+ | }else{ | ||
+ | for(int i = 0;i < infoVar.size1; | ||
+ | int label = genStrCount(); | ||
+ | String s = ""; | ||
+ | ArrayList< | ||
+ | for(int j = 0;j < infoVar.size2; | ||
+ | s = s+" %" | ||
+ | if(j== infoVar.size2-1) | ||
+ | s = s+" | ||
+ | stamentsBuff.append(" | ||
+ | stamentsBuff.append(" | ||
+ | stamentsBuff.append(" | ||
+ | loads_reg.add(var_count); | ||
+ | } | ||
+ | Integer length = s.length()-4; | ||
+ | parser.stringStatements.add(" | ||
+ | stamentsBuff.append((" | ||
+ | stamentsBuff.append(", | ||
+ | for (int j = 0; j < loads_reg.size(); | ||
+ | { | ||
+ | if(j==0) | ||
+ | stamentsBuff.append(infoVar.type+" | ||
+ | else | ||
+ | stamentsBuff.append(", | ||
+ | } | ||
+ | stamentsBuff.append(" | ||
+ | } | ||
+ | } | ||
+ | } | ||
+ | } | ||
+ | |||
+ | public void ManageString(String x, ArrayList< | ||
+ | { | ||
+ | ArrayList < | ||
+ | int label = genStrCount(); | ||
+ | InfoVar t = null; | ||
+ | String s = x; | ||
+ | s = s.replace(" | ||
+ | s = s.replace(" | ||
+ | |||
+ | for(String var : variables) | ||
+ | { | ||
+ | t = parser.symbolTable.get(var); | ||
+ | if(!parser.symbolTable.containsKey(var)) | ||
+ | { | ||
+ | pSemError(" | ||
+ | }else if(parser.symbolTable.get(var).size1==-1){ | ||
+ | stamentsBuff.append(" | ||
+ | t.load_to = var_count+""; | ||
+ | regList.add(t); | ||
+ | } | ||
+ | } | ||
+ | s = s + " | ||
+ | Integer length = s.length()-4; | ||
+ | |||
+ | parser.stringStatements.add(" | ||
+ | stamentsBuff.append((" | ||
+ | stamentsBuff.append(", | ||
+ | for (int i = 0; i < regList.size(); | ||
+ | { | ||
+ | InfoVar infoVar = regList.get(i); | ||
+ | if(i==0) | ||
+ | stamentsBuff.append(infoVar.type+" | ||
+ | else | ||
+ | stamentsBuff.append(", | ||
+ | } | ||
+ | stamentsBuff.append(" | ||
+ | } | ||
+ | </ | ||
+ | |||
+ | ==== Error handling ==== | ||
+ | The compiler is able to recognize the following kind of errors: | ||
+ | |||
+ | |||
+ | * Variable not declared | ||
+ | * Variable is not an array | ||
+ | * Function not defined | ||
+ | * Generic error in assignment | ||
+ | * Missing ] in array definition | ||
+ | * General error in while condition | ||
+ | * Missing ) in while condition | ||
+ | * General error in if condition | ||
+ | |||
+ | ==== Missing functionalities, | ||
+ | |||
+ | * the '' | ||
+ | * '' | ||
+ | * functions only return and accept parameters with type i32 (integers) | ||
+ | * if and while condition only allows AND conditions, OR conditions are not generated properly | ||
+ | * No support for global variables | ||
+ | * Strings cannot be assigned to a variable | ||
+ | * Due to a reduce/ | ||
+ | |||
+ | ===== Download and Parser ===== | ||
+ | |||
+ | **Compiler** {{https:// | ||
+ | |||
+ | **Examples** | ||
+ | * Function example and arithmetic operations: {{https:// | ||
+ | * Array and matrix operations: {{https:// | ||
+ | * Bubble sort: {{https:// | ||
+ | |||
+ | ==== How to run it ==== | ||
+ | - Install the llvm package '' | ||
+ | |||
+ | - Download the matlab_compiler and unzip it | ||
+ | - Start a new terminal inside the source folder and run the following commands: | ||
+ | * '' | ||
+ | * '' | ||
+ | * '' | ||
+ | * '' | ||
+ | - This will produce an '' | ||
+ | - Run output.ll file with: '' | ||
+ | |||
+ | ==== References ==== | ||
+ | |||
+ | * Templates and code structure were taken from [[https:// | ||
+ | * [[https:// | ||
If you found any error, or if you want to partecipate to the editing of this wiki, please contact: admin [at] skenz.it
You can reuse, distribute or modify the content of this page, but you must cite in any document (or webpage) this url: https://www.skenz.it/compilers/matlab_to_llvm?do=diff&rev2%5B0%5D=1664053240&rev2%5B1%5D=1664053528&difftype=sidebyside
/web/htdocs/www.skenz.it/home/data/pages/compilers/matlab_to_llvm.txt · Last modified: 2024/04/08 22:34 by 127.0.0.1