{"id":20989397,"url":"https://github.com/haoheliu/courseproject_compiler","last_synced_at":"2025-07-14T18:39:48.676Z","repository":{"id":113629239,"uuid":"181437424","full_name":"haoheliu/courseProject_Compiler","owner":"haoheliu","description":"java implementation of NWPU Compiler course project-西工大编译原理-试点班","archived":false,"fork":false,"pushed_at":"2024-05-07T14:20:25.000Z","size":145,"stargazers_count":14,"open_issues_count":0,"forks_count":2,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-04-02T21:51:27.799Z","etag":null,"topics":["compiler-design","coursework","mips","recursive-descent"],"latest_commit_sha":null,"homepage":"","language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/haoheliu.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2019-04-15T07:44:26.000Z","updated_at":"2024-10-23T10:01:52.000Z","dependencies_parsed_at":null,"dependency_job_id":"e4b815d4-e827-4c08-ba0a-ee1de1226199","html_url":"https://github.com/haoheliu/courseProject_Compiler","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/haoheliu/courseProject_Compiler","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/haoheliu%2FcourseProject_Compiler","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/haoheliu%2FcourseProject_Compiler/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/haoheliu%2FcourseProject_Compiler/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/haoheliu%2FcourseProject_Compiler/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/haoheliu","download_url":"https://codeload.github.com/haoheliu/courseProject_Compiler/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/haoheliu%2FcourseProject_Compiler/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":265333890,"owners_count":23748895,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["compiler-design","coursework","mips","recursive-descent"],"created_at":"2024-11-19T06:24:43.494Z","updated_at":"2025-07-14T18:39:48.647Z","avatar_url":"https://github.com/haoheliu.png","language":"Java","funding_links":[],"categories":[],"sub_categories":[],"readme":"**西北工业大学《编译原理》试点班作品\n\n# 1. Overview 概述\n\n## 1.1 整体思路\n\n词法分析器-\u003e语法分析器（递归下降，语法制导翻译）-\u003e寄存器分配和代码优化-\u003eMIPS汇编指令集\n\n## 1.2 特色\n\n- 按照软件工程和设计模式规范开发，文档完备\n- 使用github进行项目管理，各个版本清晰可见：\u003chttps://github.com/Ranchofromxgd/courseProject_Compiler\u003e\n- 文法由自己设计，实现了所有C0的语法，并有适当拓展\n- 代码使用工业级编码规范进行书写，符合java设计模式要求\n- 代码内文档详尽，注释清晰，可读性和可维护性强\n- 注重细节，对源代码格式鲁棒性高（例如循环递归调用的寄存器保存）\n- 生成的汇编代码自带注释，可读性强（见文档最后附录编译结果）\n- 使用自己编写的assert函数进行集成测试，不通过时会使用exit系统调用退出\n- 寄存器分配和符号表结构设计高效合理，算法设计效率高\n\n## 1.3 总体设计\n\n![ZCyn4s.png](https://s2.ax1x.com/2019/06/23/ZCyn4s.png)\n\n## 1.4 开发环境\n\n**IntelliJ IDEA 2019.1**\n\n**JRE:1.8.0_202-RELEASE-1483-B39 AMD64**\n\n**JVM: OpenJDK 64-Bits Server VM by JetBrains**\n\n# 2. Syntax support 支持的语法\n\n## 2.1. alrithmetic 算术语法\n\n### 2.1.1. calculations(- +,-,*,/)\n\n- 遵循四则运算的算术优先级，也可以使用括号来改变算术优先级\n\n### 2.1.2. boolean expressions (and,or)\n\n- and相当于C语言中的:\u0026\u0026\n- or相当于C语言中的:||\n- 支持短路\n\n### 2.1.3. comparision (\u003e,\u003c,\u003c=,\u003e=,==)\n\n- 与正常C语言含义相同\n- 可以将多个比较运算符使用and和or进行连接\n\n### 2.1.4. 赋值语句\n\n语法：\n\n```c\nARRAY[n]|INTEGER = EXPRESSION\n```\n\n- 将每一次赋值语句作为寄存器的一次使用周期，在每一次赋值语句结束之后就可以将他们复位一下，重新从$t0,$s0...开始分配\n- 赋值之前将左值分配寄存器，从内存中取出，存入寄存器，经过计算之后再存入内存\n- 赋值语句的寄存器使用效率可能较低，而且每一次使用变量都要访存，可能会影响程序的运行速度\n\n## 2.2. 选择和分支\n\n### 2.2.1. if-else\n\n语法：\n\n```c\n   if(BOOLEANEXPRESSION)\n   {\n         [statementList]...\n   }else\n   {\n         [statementList]...\n   }\n```\n\n### 2.2.2. while\n\n语法\n\n```c\n   ...\n   while(BOOLEANEXPRESSION)\n   {\n      [StatementList]...\n   }\n   ...\n```\n\n- break:正常的跳出语句\n- continue：接着进行循环\n\n### 2.2.3. 全局变量\n\n语法：\n\n```c\n//只能在函数定义之前进行声明\nint global_var1,...;\nint global_var2,...;\n...\narray global_arr1[LENGTH1];\narray global_arr2[LENGTH2];\n...\n```\n\n- 全局int变量\n- 全局array变量 \n- 全局变量存储在内存的堆区，使用$gp指针进行检索  \n\n### 2.2.4. function Defination\n\n语法：\n\n```c\ndef void/int \u003cFUNCTIONNAME\u003e(int PARAM1,int PARAM2,...)  \n{\n   int var1,var2,...;  \n   array arr1[LENGTH1];\n   array arr2[LENGTH2];\n   ...\n   const int c1 = 123;\n   ...\n   [StatementList]...\n   [returnStatement]...\n}\n```\n\n- 局部变量声明：可以声明局部int变量和array变量\n- 支持入口参数，在调用时使用$a0~$a3存放\n- 支持返回值，返回值存放在$v0寄存器中\n- 支持递归调用过程中寄存器保存，如：\n\n```c\ndef void factor( int N ){\n    global1 = global1 + 1;\n    println(\"\\nThe global value: \");\n    println(global1);\n\tif( N \u003e 1 ){\n\t\treturn N * cal factor( N - 1 );\n\t}\n\telse{\n\t\treturn 1;\n\t}\n}\n```\n\n- 函数内部可以使用全局int 和 array变量\n\n### 2.2.5. const常量\n\n语法：\n\n```c\nconst int \u003cID\u003e = EXPR;\n```\n\n- CONST声明过的变量在试图修改值(saveVariable())的时候会报错\n\n### 2.2.6. functioncall \n\n语法：\n\n```c\ncal \u003cFUNCTIONNAME\u003e(PARAM1,PARAM2,PARAM3...)  \n```\n\n- 支持立即数，int和array变量作为实参\n- 支持将函数调用作为算术表达式的一个项（必须带返回参数）\n\n### 2.2.7. goto \u0026 dest\n\n语法：\n\n```c\ndest LABEL\n...\ngoto LABEL\n...\n```\n\n- 遇到dest语句就在mips中加入一个标签，执行到goto的话就用无条件跳转\"j\"来跳到标签处\n\n```c\ndef void main()\n{\n    int a,b;\n    a = 10;\n    b = 6;\n    while(a \u003e= 3)\n    {\n        println(b);\n        println(\"\\n\");\n        if(a == 5)\n        {\n            println(\"Use goto to jump to the label\\n\");\n            goto First;\n        }\n        a = a-1;\n    }\n    dest First;\n    println(\"Finish!\");\n    return 0;\n}\n```\n\n## 2.3. 强制退出语句\n\n语法：\n\n```c\nexit;       //force quit\n```\n\n## 2.4. Built-in functions 内建函数\n\n### 2.4.1. 标准输出\n\n语法：\n\n```c\nprintln(\u003cSTRING\u003e|VARIABLE|CONSTANT);\n```\n\n- 可以用来打印字符串，指向字符串的变量(打印出来的也是字符串)，变量和立即数\n- 默认在字符串末尾加上一个换行符，这个通过修改StringMgr中的Enter函数实现\n  例子：\n\n```c\ndef void main()\n{\n   int test_var;\n   array test[10];\n   //字符串输出\n   println(\"This is \\t standard \\\\\\\"output\\\"!\\n\");\n   test_var = 66;\n   test[4]=  88;\n   // Output of variables\n   println(test_var);\n   println(test[4]);\n   //Output of constants\n   println(65535);\n}\n```\n\n### 2.4.2. 标准输入\n\n语法：\n\n```java\nint readint()\n```\n\n- 调用这个函数的返回值为int型\n\n## 2.5. 字符串与转义字符\n\n- 字符串中如果识别到连续的偶数个反斜线(\\)加上一个双引号(\")，则这里的双引号代表字符串的结束\n- 字符串中如果识别到连续的奇数个反斜线(\\)加上一个双引号，则最后一个双引号为转义字符，不作为字符串的结束标志\n- 字符串变量都作为\".asciiz\"类型存储在MIPS程序的.data段\n\n## 2.6. assert 语句\n\n语法：\n\n```java\nassert(EXPR1 == EXPR2);\n```\n\n如果两个expr的值不相等，程序会调用exit自动退出\n\n## 2.7. Comment\n\n语法：\n\n```c\n//这里是注释\n```\n\n## 2.8. Error report\n\n### 2.8.1. 一个通用的报错函数\n\n- 这个报错的函数定义在parser类中，由这个类使用\n- TOKEN类中存有行列信息，支持报告出错的行和列，对于当前正在parse的token，如果出现错误可以取出currentToken然后在Exception中进行报告，具体函数设计如下：\n\n```java\n    private RuntimeException genEx(String errorMessage)\n    {\n       //errorMessage可以在不同的场景下进行不同定义\n        return new RuntimeException(\"Encountered \\\"\" +\n                currentToken.image + \"\\\" on line \" +\n                currentToken.beginLine + \", column \" +\n                currentToken.beginColumn + \".\" +\n                errorMessage);\n    }\n```\n\n### 2.8.2. 局部符号表FuncSymTab的报错\n\n- 主要包括变量未定义和数组未定义的错误\n\n```java\npublic void arrEnter(String name,int space)\n    {\n       ...\n        if(index\u003c0)\n        {\n            ...\n        }else genDf(name);\n    }\n\n    public int arrLocate(String name)\n    {\n        int index = arr_names.indexOf(name);\n        if(index \u003e= 0)\n        {\n           ...\n        }else\n            throw new RuntimeException(\"Error: This array have not been defined!\");\n    }\n\n    //on parsing: enter the args\n    public void argEnter(String arg)\n    {\n        int index = args.indexOf(arg);\n        if(index\u003c0)\n        {\n           ...\n        }\n        else genDf(arg);\n    }\n\n    public void varEnter(String var)\n    {\n        if(args.indexOf(var)\u003e=0)genDf(var);\n        int index = vars.indexOf(var);\n        if(index\u003c0)\n        {\n           ...\n        }\n        else genDf(var);\n    }\n   //Exceptions\n    private void genDf(String item)\n    {\n        throw new RuntimeException(\"\\nError: \"+item+\" is already defined\");\n    }\n```\n\n### 2.8.3. 全局符号表的报错\n\n```java\n   //Global array have already been defined\n   public void addGlobalArr(String name,int space)\n    {\n        ...\n        if(index\u003c0)\n        {\n            ...\n        }else throw new RuntimeException(\"Error: global variable\"+name+\" have already been defined\");\n    }\n\n   // Global variable have already been defined\n    public void addGlobal(String s)\n    {\n        if(global_var.contains(s))\n            throw new RuntimeException(\"Error: \"+s+\" has already been defined!\");\n        global_var.add(s);\n    }\n\n   // Function have already been defined\n    public void enterFunc(String func_name,FuncSymTab func)\n    {\n        if (!func_tabs.containsKey(func_name))\n            ...\n        else throw new RuntimeException(\"Error: Function \\\"\"+func_name+\"\\\" has already defined\");\n    }\n```\n\n### 2.8.4. 寄存器分配溢出错误\n\n```java\npublic String registerAvailable()\n    {\n        String temp = \"$t\"+this.registerT_count++;\n        //Totally we have $t0~$t9, so if we don't have enough register, we will throw an exception\n        if(this.registerT_count == 11)\n        {\n           //register $tx not enough\n            throw new RuntimeException(\"Temporary registor overflow\");\n        }\n        return temp;\n    }\n\n    public String registerS_Available(){\n        String temp = \"$s\"+this.registerS_count++;\n        if(this.registerS_count == 9)\n        {\n           //register $sx not enough\n            throw new RuntimeException(\"s registor overflow\");\n        }\n        return temp;\n    }\n\n    public String registerA_Available(){\n        String temp = \"$a\"+this.registerA_count++;\n        if(this.registerA_count == 5)\n        {\n           //register $ax not enough\n            throw new RuntimeException(\"Registor a overflow\");\n        }\n        return temp;\n    }\n```\n\n# 3. Details 一些实现细节 (详见代码注释)\n\n## 3.1. 函数内部定义的变量在load和save的时候如何在内存中定位 \n\n详见Parser.java中loadVariable函数，注释非常详尽：\n\n```java\n/**\n     * This function is defined in order to unify the \"load\" operation from local variables and global varibales\n     * */\n    private void loadVariable(String reg,String var)\n    {\n        int index;\n        /***************\n         * First consider whether this variable is an array\n         * Then we need some code to loadvariable into register\n         * ********/\n        if(var.indexOf('[') \u003e 0 \u0026\u0026 var.indexOf(']') \u003e 0)\n        {\n            String name = var.substring(0, var.indexOf('['));\n            int arr_index = Integer.parseInt(var.substring(var.indexOf('[')+1, var.indexOf(']')));\n            /**\n             * First consider if it's a global array\n             * */\n            int offset = st.locateGlobalArr(name);\n            if(offset \u003c 0)\n            {\n                /**\n                 * If not global array, see if it's an array defined within function\n                 * */\n                offset = ft.getOffset(name, ARRAY);\n                emitInstruction(\"lw\", reg,offset+arr_index*4+\"($sp)\");\n            }else\n            {\n                int base = st.getGlobalVarSize(); //Start from the last item of global variables\n                emitInstruction(\"lw\",reg,base+offset+arr_index*4+\"($gp)\");\n            }\n//            System.out.println(\"String name:\"+name);\n//            System.out.println(\"String name:\"+offset);\n        }else {\n            /**\n             * If not array, first consider if it's global variable\n             * */\n            index = st.locateGlobal(var);\n            System.out.println(\"index of the globle variable: \"+index);\n            if(index \u003e= 0) // If this variable is found in global variable list\n            {\n                emitInstruction(\"lw\",reg,(index*4)+\"($gp)\");\n                return;\n            }\n            /**\n             * If not global variables, consider if it's local variable\n             * */\n            index = ft.getOffset(var, ARGS);\n            if(index \u003e= 0)\n            {\n                //If this variable is defined in args list\n                /**@marked\n                 * The push sequence and index sequence are inverse\n                 * So we need some tricks\n                 * */\n                emitInstruction(\"lw\",reg, index+\"($fp)\");\n            }\n            else if(index \u003c 0)\n            {\n                //If this variable is defined in local variables list\n                index = ft.getOffset(var,INT);\n                if(index \u003e= 0)emitInstruction(\"lw\",reg, index+\"($sp)\");\n            }\n            /**\n             * If not local variables, consider if it's const variable\n             * */\n            if(index \u003c0)\n            {\n                index = ft.getOffset(var, CONST);\n                if(index \u003e= 0)emitInstruction(\"lw\", reg,index+\"($sp)\");\n            }\n\n            if(index \u003c 0) throw genEx(var+\" not defined\");\n        }\n    }\n```\n\n\n\n## 3.2. 被调用者保存寄存器的实现\n\n在Parser.java的functionCall()函数中有这么一段代码用来识别需要保存的寄存器，并在函数退出之后恢复这些寄存器，并且将这些寄存器按照压栈顺序反向依次弹栈：\n\n```java\n//argumentList will also consume registers\n        int reg_t = rm.registerT_count;\n        int reg_s = rm.registerS_count;\n        int save_reg = (-4)*(reg_s+reg_t);\n\n        System.out.println(\"reg\"+rm.registerT_count);\n        System.out.println(\"reg\"+rm.registerS_count);\n\n        emitInstruction(\"addi\", \"$sp\",\"$sp\",\"\"+save_reg,\"# \"+(reg_t+reg_s)+\" registers need to be saved\");\n\n        int pointer = -save_reg-4;\n        for(int i=reg_s-1;i\u003e=0;i--)\n        {\n            emitInstruction(\"sw\", \"$s\"+i,pointer+\"($sp)\");\n            pointer-=4;\n        }\n        for(int i=reg_t-1;i\u003e=0;i--)\n        {\n            emitInstruction(\"sw\", \"$t\"+i,pointer+\"($sp)\");\n            pointer-=4;\n        }\n\n        //ft.base_offset += (reg_s+reg_t)*4;\n\n        rm.resetRegister();\n\n        outFile.println(\"# Execute function: \"+func_name);\n        emitInstruction(\"jal\",func_name);\n\n        pointer = 0;\n\n        //Reload the saved registers' value into the previous registers\n        for(int i=0;i\u003creg_t;i++)\n        {\n            emitInstruction(\"lw\", \"$t\"+i,pointer+\"($sp)\");\n            pointer+=4;\n        }\n\n        for(int i=0;i\u003creg_s;i++)\n        {\n            emitInstruction(\"lw\", \"$s\"+i,pointer+\"($sp)\");\n            pointer+=4;\n        }\n\n        //ft.base_offset = 0;\n\n        emitInstruction(\"addi\", \"$sp\",\"$sp\",\"\"+(-1)*save_reg,\"#Saved \"+(reg_s+reg_t)+\" registers pop stack\");\n    \n```\n\n\n\n## 3.3. 函数调用直接用于算术表达式\n\n详见文法设计部分，将函数调用语句当做一个变量处理\n\n## 3.4. 符号表设计（全局符号表和局部符号表）\n\n详见5.2节符号表设计\n\n## 3.5. 局部变量与局部数组同时存在时如何正确定位数组基址\n\n在函数定义中遇到一个变量或者数组的时候，将其类型和占用空间（size）先存入局部符号表中，在整个函数parse完毕之后利用各个变量的size信息计算出各个变量以及数组基址相对于$sp指针的偏移量，并更新vars类对象的offset属性，在访问局部变量的时候利用这些信息进行定位\n\n详见5.2节局部符号表设计\n\n## 3.6. 寄存器分配复位的时机\n\n- 使用的寄存器有$t0~$t9,$s0~$s7,$a0~$a3\n\n- 每个寄存器都是从0号开始分配，如果没有足够的寄存器则报错，分配代码如下：\n\n  ```java\n      public String registerAvailable()\n      {\n          String temp = \"$t\"+this.registerT_count++;\n          //Totally we have $t0~$t9, so if we don't have enough register, we will throw an exception\n          if(this.registerT_count == 11)\n          {\n              throw new RuntimeException(\"Temporary registor overflow\");\n          }\n          return temp;\n      }\n  \n      public String registerS_Available(){\n          String temp = \"$s\"+this.registerS_count++;\n          if(this.registerS_count == 9)\n          {\n              throw new RuntimeException(\"s registor overflow\");\n          }\n          return temp;\n      }\n  \n      public String registerA_Available(){\n          String temp = \"$a\"+this.registerA_count++;\n          if(this.registerA_count == 5)\n          {\n              throw new RuntimeException(\"Registor a overflow\");\n          }\n          return temp;\n      }\n  ```\n\n- 在合适的时机可以reset所有寄存器的分配\n\n  ```java\n  public void resetRegister()\n  {\n      this.registerS_count = 0;\n      this.registerT_count = 0;\n      this.registerA_count = 0;\n  }\n  ```\n\n- 具体的复位时机：\n  - 在functioncall的jal之前（由于输入参数可能是一个复杂的表达式，占用了相当一部分寄存器）\n  - 在赋值语句结束之后（赋值语句中使用到的寄存器和下一条语句没有关系）\n  - 在println语句结束之后（println里边可能有复杂的表达式计算）\n  - 在布尔表达式运算完毕之后（多个布尔表达式用\u0026\u0026或者||连接时，如果计算完一部分不reset一下，很有可能会溢出。采取的对策是，每计算完一个单独的表达式，就释放所有使用的寄存器，而且将结果存入复位后新分配的寄存器）\n\n## 3.7. 各种变量和数组的load、save逻辑\n\n这里以局部符号表里的变量相对于$sp寄存器作为指针的offset为例来说明变量如何在函数调用栈中进行定位，全局符号表类似，只不过使用的是$gp寄存器作为指针\n\n分这三步：\n\n1. 见到变量：使用Enter()收入局部符号表，存入type，size信息\n\n2. 整个函数的变量扫描完后调用initCalBasementValue()函数来计算出各个变量相对于$sp的offset\n\n3. 使用变量时调用getOffset()来获取offset\n\n   代码如下：\n\n   对于Enter，需要分为const，int和array分别来考虑\n\n   ```java\n       /**\n        * Enter for ARRAY\n        * */\n       public void Enter(String name,int type,int size)\n       {\n           if(type == ARRAY)\n           {\n               Var temp = new Var(name,type,size);\n               temp.name = temp.name.substring(0, temp.name.indexOf('['));\n               if(vars.indexOf(temp) \u003c 0){\n                   this.vars.add(temp);\n               }else{\n                   throw new RuntimeException(\"Error: [\"+name+\"] Array has already been defined\");\n               }\n           }else throw new RuntimeException(\"Error: The function \\\"Enter\\\" used is not compatible\");\n       }\n       /**\n        * Enter for INT and CONST\n        * */\n       public void Enter(String name,int type)\n       {\n           if(type == INT || type == CONST || type == ARGS)\n           {\n               Var temp = new Var(name,type);\n               if(vars.indexOf(temp) \u003c 0)\n               {\n                   this.vars.add(temp);\n                   //Update the number of localVariables as well as args\n                   if(type == INT) this.local_var_num ++;\n                   if(type == ARGS)this.local_args_num++;\n                   if(type == CONST)this.local_const_num++;\n               }else{\n                   throw new RuntimeException(\"Error: [\"+name+\"] Variable has already been defined\");\n               }\n           }else throw new RuntimeException(\"Error: The function \\\"Enter\\\" used is not compatible\");\n       }\n   ```\n\n   利用变量的size信息反向计算出各个变量的offset\n\n```java\n    /**\n     * @LastStepOfFuncSymTab\n     * The initial value in \"Var\" is their size\n     * After this function we will have it's offset from base_pointer\n     * */\n    public void initCalBasementValue()\n    {\n        if(vars.size() == 0)\n        {\n            return;\n        }\n        int offset = 0;\n        Var temp = new Var();\n        for(int i=vars.size();i\u003e0;i--)\n        {\n            temp = vars.get(i-1); //Get the i-th element\n            temp.offset = offset; //update it's offset\n            offset += temp.size;\n            vars.set(i-1, temp);  //Update this element to : vars\n        }\n\n        int j=1;\n        temp = vars.get(0);\n\n        while(temp.type == ARGS){\n            try {\n                temp = vars.get(j);\n            }catch (Exception e){\n                break;\n            }\n            j++;\n        }\n        /**\n         * This value is extremely important to the pop of function stack\n         * */\n        if(temp.type == ARGS)\n            this.space = this.local_args_num*4+8; //The space used by array,const and int\n        else\n            this.space = temp.size+temp.offset+this.local_args_num*4+8;\n\n        int start_offset_fp = 8;\n        for(int i=0;i\u003cvars.size();i++)\n        {\n            temp = vars.get(i); //Get the i-th element\n            if(temp.type == ARGS){\n                temp.offset = start_offset_fp; //update it's offset\n                start_offset_fp += 4;\n            }\n            else break;\n            vars.set(i, temp);  //Update this element to : vars\n        }\n    }\n```\n\n获取某个变量的offset\n\n```java\n    /**\n     * Return offset value for array,int and const\n     * */\n    public int getOffset(String name, int type)\n    {\n        int offset = 0;\n        Var temp = new Var();\n        temp.name = name;\n        temp.type = type;\n        int index = this.vars.indexOf(temp);\n        if(index \u003e= 0)\n        {\n            temp = vars.get(index);\n            offset = temp.offset;\n            return offset+this.base_offset;\n        }\n        else return -1;\n    }\n```\n\n\n\n------\n\n# 4. Grammars 文法设计\n\n- 词法分析器(TokenMgr.java)因为比较简单，这里先省略\n\n## 4.1. 上层文法：程序，函数定义，全局声明\n\n**program** \t\t\t\t\t-\u0026gt;**programUnitList**  \u0026lt;EOF\u0026gt;  \n|\u0026lt;EOF\u0026gt;\n\n**programUnitList**  \t\t\t-\u0026gt;**programUnit**  **programUnitList**  {“def”}  \n|ε\n\n**programUnit**  \t\t\t\t-\u003e**functionDefinition** {“def”}  \n|**globalDeclarations** {\"int\"}  \n|ε\n\n**globalDeclarations**\t\t\t-\u003e\t”int” \u0026lt;ID\u0026gt; **globalTail** “;”  **globalDeclarations**  \n|\"array\" \u0026lt;ID\u003e \"[\" \u0026lt;UNSIGNED\u003e \"]\" \";\" **globalDeclarations**    \n|const \u0026lt;ID\u003e \"=\" \u0026LT;UNSIGNED\u003e \";\" **globalDeclarations**   \n|ε{\u0026lt;ID\u0026gt;,”println”,”{”,”while”,”if”,”return”,”cal”}\n\n**globalTail** \t\t\t\t\t-\u0026gt;\t”,” \u0026lt;ID\u0026gt; **globalTail**  \n|ε {”;”}\n\n**functionDefinition**-\u0026gt;”def” ”void” \u0026lt;ID\u0026gt; “(” **parameterList** “)”\n“{” **localDeclarations** **statementList** “}”\n\n**parameterList**\t\t\t\t-\u0026gt;\t**parameter** **parameterTail**\n\n**parameter**\t\t\t\t\t-\u0026gt;\t”int” \u0026lt;ID\u0026gt;\n\n**parameterTail** \t\t\t\t-\u0026gt;\t”,” **parameter** **parameterTail**  \n|ε{“)”}\n\n**localDeclarations**\t\t\t-\u003e  \n|\"array\" \"[\" \u0026lt;UNSIGNED\u0026gt; \"]\" \";\"  **localDeclarations**   \n|”int” \u0026lt;ID\u0026gt; **localTail** “;” **localDeclarations**     \n|\"const\" \"int\" \u0026lt;ID\u003e \"=\" expr \";\"  **localDeclarations*\n|ε{\u0026lt;ID\u0026gt;,”println”,”{”,”while”,”if”,”return”,”cal”}\n\n**localTail** \t\t\t\t\t-\u0026gt;\t”,” \u0026lt;ID\u0026gt; **localTail**  \n|ε {”;”}\n\n------\n\n## 4.2. 中层文法：不同种类的statements\n\n**statementList** \t\t\t\t-\u0026gt; \t**statement**  **statementList**  \n|ε{\u0026lt;EOF\u0026gt;,”}”,”return”}\n\n**statement** \t\t\t\t\t-\u0026gt; \t**assignmentAndBoolen**{\u0026lt;ID\u0026gt;}\n\n**statement**\t\t\t\t\t-\u0026gt;\t**printlnStatement**{”println”}\n\n**statement** \t\t\t\t\t-\u0026gt;\t**compoundStatement**{“{”}\n\n**statement**\t\t\t\t\t-\u0026gt;\t**whileStatement**{“while”}\n\n**statement**\t\t\t\t\t-\u0026gt;\t**ifStatement**{“if”}\n\n**statement**\t\t\t\t\t-\u0026gt;\t**switchStatement** {“switch”}\n\n**statement** \t\t\t\t\t-\u0026gt;\t**returnStatement**{“return”}\n\n**statement**              -\u003e **jumpStatement** {\"break\",\"goto\",\"continue\",\"dest\"}\n\n**statement**              -\u003e **arrayStatement** {\"array\"}\n\n**statement**               -\u003e**exitStatement** {\"exit\"} \n\n**statement** \t\t\t\t\t-\u0026gt; \t**functionCall** {“cal ”}\n\n**statement**               -\u003e **assertStatement** {\"assert\"}\n\n------\n\n## 4.3. 中层文法细化-\u003e非终结符的产生式\n\n**assignmentAndBoolen**\t\t-\u0026gt;\t\u0026lt;ID\u0026gt;  **assignmentStatement**\n\n**assignmentStatement**\t\t-\u0026gt;\t”=”  **expr**  ”;”\n\n**argumentList**\t\t\t\t-\u0026gt;\t**expr**  **argtail**  \n|ε{“)”} {\u0026lt;UNSIGNED\u0026gt;,”+”,”-”,\u0026lt;ID\u0026gt;,”(”,\u0026lt;STRING\u0026gt;}\n\n**argtail**\t\t\t\t\t\t-\u0026gt;\t“,” **expr** **argtail**  \n|ε {“)”}\n\n**compoundStatement**\t\t-\u0026gt;\t”{” **statementList** “}”\n\n**printlnStatement**\t\t\t-\u0026gt;\t”println”  ”(”  **expr** ”)”  “;” {”println”}\n\n**whileStatement**\t\t\t\t-\u0026gt;\t”while”  “(”  **expr**  “)”  **statement**\n\n**ifStatement** \t\t\t    \t-\u0026gt;\t”if”  “(”  **expr**  “)”  **statement**  **elsePart**\n\n**elseStatement**(代码上实现) \t-\u0026gt;\t”else” **statement**\n\n**switchStatement** \t\t\t-\u0026gt;”switch”  “(” **expr** “)” “{”\n**caseStatementList** **defaultStatement** “}”\n\n**caseStatementList**\t\t\t-\u0026gt;**caseStatement** **caseStatementList**{”case”}  \n|ε\n\n**caseStatement**\t\t\t\t-\u0026gt;case numbers”:” **StatementList**\n\n**defaultStatement**\t\t\t-\u0026gt;”default” “:” **StatementList**  \n|ε\n\n**numbers**\t\t\t\t\t-\u0026gt;\t\u0026lt;UNSIGNED\u0026gt;\n\n**compoundStatement**\t\t-\u0026gt;\t”{” **statementList** “}”\n\n**returnStatement**\t\t\t-\u0026gt;\t”return“ **expr** “;”  \n|ε {\u0026lt;UNSIGNED\u0026gt;,”+”,”-”,\u0026lt;ID\u0026gt;,”(”,\u0026lt;STRING\u0026gt;}\n\n**jumpStatement**-\u003e\"goto\"  \n|\"break\"  \n|\"continue\"  \n|\"dest\"\n\n**assertStatement**     -\u003e \"assert\" \"(\" **expr** \",\" **expr** \")\" \";\"\n\n------\n\n## 4.4. 低层文法：布尔表达式，算术表达式\n\n**expr**\t\t\t\t\t\t\t-\u0026gt;\tterm termList\n{\u0026lt;UNSIGNED\u0026gt;,”+”,”-”,\u0026lt;ID\u0026gt;,”(”,\u0026lt;STRING\u0026gt;}\n\n**termList**\t\t\t\t\t\t-\u0026gt;\t”+”  term termList  \n|”-” **term** **termlist**  \n|”==”  **expr**    **boolenExpression**  {“and”,”or”,“)”,”;”,”,”}  \n|”\u0026gt;=”  **expr**    **boolenExpression**  \n|”\u0026lt;=”  **expr**  **boolenExpression**  \n|”\u0026gt;”  **expr**  **boolenExpression**  \n|”\u0026lt;”  **expr**  **boolenExpression**  \n|ε{“)”,”;”,”,”}\n\n**functionCall**\t\t\t\t\t-\u0026gt;\t“cal” \u0026lt;ID\u0026gt; “(” argumentList “)” “;”\n\n**boolenExpression**\t\t\t-\u0026gt;\t“and” **expr** **boolenExpression**  \n|“or” **expr** **boolenExpression**  \n|ε{“)”,”;”,”,”}\n\n**term**\t\t\t\t\t\t-\u0026gt;\t**factor**  **factorList**{\u0026lt;UNSIGNED\u0026gt;,”+”,”-”,\u0026lt;ID\u0026gt;,”(”,\u0026lt;STRING\u0026gt;}  \n|**functionCall**{“cal ”}\n\n**factor**\t\t\t\t\t\t-\u0026gt;\t\u0026lt;UNSIGNED\u0026gt;     {\u0026lt;UNSIGNED\u0026gt;}  \n| ”+”  \u0026lt;UNSIGNED\u0026gt; {“+”}  \n| ”-”\t  \u0026lt;UNSIGNED\u0026gt; {“-”}  \n| \u0026lt;ID\u0026gt; {\u0026lt;ID\u0026gt;}  \n| ”(”  **expr**  “)” {“(”}  \n|**functionCall**  \n|\u0026lt;STRING\u0026gt;\n\n**factorList**\t\t\t\t\t-\u0026gt;\t”*” **factor** **factorList**   {“*”}  \n|”/” **factor** **factorList**\t{“/”}  \n|ε {“)”,”;”,”+”}\n\n# 5. Key problems 重点问题\n\n## 5.1. Design of function calling stack 函数调用栈设计\n\n函数调用栈压栈顺序可以用下边表格表示：\n\n| 函数调用栈            | 备注                                                         | 指针   |\n| --------------------- | ------------------------------------------------------------ | ------ |\n| $a0                   |                                                              |        |\n| ...                   | 从$a0~$a3，在函数调用之前先将实参压栈                        |        |\n| $ra                   | 存储函数返回地址                                             |        |\n| $fp                   | 存储旧的$fp指针值                                            | \u003c- $fp |\n| int变量1              |                                                              |        |\n| int变量2              |                                                              |        |\n| ...                   | int变量声明                                                  |        |\n| array_1分配的空间     |                                                              |        |\n| ...                   |                                                              |        |\n| array_2分配的空间     |                                                              |        |\n| ...                   |                                                              |        |\n| array_n分配的空间     |                                                              |        |\n| ...                   |                                                              |        |\n| 调用者保存的$sx寄存器 |                                                              |        |\n| ...                   |                                                              |        |\n| 调用者保存的$tx寄存器 |                                                              |        |\n| ...                   | 在函数递归调用时需要由被调用者保存这些寄存器到栈，返回时将这些变量返回到寄存器中 |        |\n| 栈顶                  |                                                              | \u003c- $sp |\n\n## 5.2 符号表设计\n\n- 全局符号表用来储存全局int变量以及全局数组，存储在静态数据区，使用$gp指针进行访问\n- 全局符号表中用一个哈希表来对函数名和局部符号表进行一一映射\n- 其他设计设计细节如图所示：\n\n[![ZS7RWF.png](https://s2.ax1x.com/2019/06/21/ZS7RWF.png)](https://imgchr.com/i/ZS7RWF)\n\n## 5.3. Strategy for register management 寄存器分配设计\n\n- 寄存器分配管理由类**RegMgr**进行\n- 使用的寄存器组：$t0~$t9,$s0~$s7,$a0~$a3，每次请求寄存器成功后就将寄存器号+1，如果超出了现有的寄存器数量，则报错寄存器分配溢出\n- 注意到一条赋值语句结束之后，使用过的寄存器就可以全部清空了，在本文档中定义这种现象为**前向无依赖性**，具有这种性质的语句结束后都可以调用rm.reset()方法来复位寄存器；对于形如expr1 \u0026\u0026 expr2 || expr3... 这样的布尔表达式，如果表达式比较长而且参与计算的变量或者常量比较多，非常容易产生寄存器的分配溢出，为了防止这种现象的出现， 每计算完一个expr的布尔值，就释放掉所有expr使用过的寄存器，并将计算结果放入一个重新分配的寄存器中。使用这种方法平均下来每个布尔表达式只需要1个寄存器，大大消除了寄存器分配溢出的风险。\n- 清空的方法：下次分配寄存器的时候从$t0，$s0开始分配\n\n# 6. Test cases一部分测例:\n\n## 6.1. Recursive function calling \u0026 breakStatement \u0026continue Statement \u0026 globalStatement\n\n```c\nint global1,global2;\n\ndef void factor( int N ){\n    global1 = global1 + 1;\n    println(\"\\nThe global value: \");\n    println(global1);\n\tif( N \u003e 1 ){\n\t\treturn N * cal factor( N - 1 );\n\t}\n\telse{\n\t\treturn 1;\n\t}\n}\n\ndef void main()\n{\n    int n,times;\n    global1 = 1;\n    times = 6;\n    while(times \u003e= 0)\n    {\n        n = cal factor(times);\n        println(\"\\nResult of factor:\");\n        println(times);\n        println(\" - \");\n        println(n);\n        println(\" - \");\n        if(times == 4)\n        {\n            println(\"Break!\");\n            break;\n        }else{\n            times = times-1;\n            println(\"Continue!\");\n            continue;\n        }\n    }\n    return 0;\n}\n\n```\n\n## 6.2. 数组测试\n\narr的基址是根据在它之前声明的arr2的大小决定的，在访问和更改arr的元素的时候也是如此\n\n```c\ndef void main()\n{\n    int n,times;\n    array arr2[100];\n    array arr[255];\n    arr[66] = 65535;\n    println(arr[66]);\n    \n    return 0;\n}\n```\n\n输出结果为65535，正确！\n\n## 6.3. 递归调用寄存器保存测试:\n\n```c\nint global1,global2;\n\ndef void factor( int N ){\n    global1 = global1 + 1;\n    println(\"\\nThe global value: \");\n    println(global1);\n\tif( N \u003e 1 ){\n\t\treturn N * cal factor( N - 1 );\n\t}\n\telse{\n\t\treturn 1;\n\t}\n}\n\ndef void main()\n{\n    int n,times;\n    array arr[255];\n    global1 = 1;\n    times = 6;\n    while(times \u003e= 0)\n    {\n        n = cal factor(times);\n        println(\"\\nResult of factor:\");\n        println(times);\n        println(\" - \");\n        println(n);\n        println(\" - \");\n        if(times == 4)\n        {\n            println(\"Break!\");\n            break;\n        }else{\n            times = times-1;\n            println(\"Continue!\");\n            continue;\n        }\n    }\n    return 0;\n}\n```\n\n## 6.4. 全局数组测试\n\n```c\narray arr1[80];\n\ndef void test()\n{\n    println(arr1[66]);\n}\n\ndef void main()\n{\n    arr1[66] = 65535;\n    cal test()\n    return 0;\n}\n```\n\n其他：\n\n- 见到一个变量以后的策略：先看在全局符号阵列中寻找，看是否为全局变量，然后再在此函数的实参表中寻找，如果还是没有找到就在函数的局部声明中寻找，如果还找不到的话就报错\n- 最初对数组的空间考虑分配的是：在C语言中对函数调用栈的大小有限制，所以在函数内部不能定义特别大的数组，为了解决这个缺陷，我将函数中的数组定义放在了静态变量区，当函数调用退出时释放数组的空间；实现上使用一个globalpointer，当在程序最初有int或者数组声明的时候，这个pointer就会向上拓展。当进入一个函数时将当前的globalpointer地址当做分配数组的开始地址，在使用的时候也是以这个指针为导向进行索引，在退出函数之前，不需要做任何操作，因为globalpointer的值没有改变，下一个函数中声明的数组将会保存...然而递归调用会出现数组的保存问题  \n  所以我决定还是将函数中的数组放到函数调用栈中，在读取localvariable的值的时候要在$sp的基础上加上数组的空间，在给变量赋值的时候也要在$sp的基础上加上数组的偏移量\n- 为了将数组内元素的使用和变量ID的使用统一起来，我修改了词法分析器，使得其将数组元素的使用也看作ID的使用，而后修改loadVriable中的代码使得其可以辨识出是要加载的是普通的变量还是数组中的参数  \n- 将数组定义时连同中括号以及内部的数字一同作为ID还可以使得变量和数组具有相同的名字而不会冲突\n\n- 测试函数内部数组：\n\n```c\n//Function call need not ';'\ndef void main(int argtest)\n{\n    array s[100];\n    int a;              //test whether the offset is set correctly\n    array s2[4];\n    s2[1] = 100;\n    //LOCAL TEST\n    //a = 456;    \n    //s[3] = 655*a + s2[1] ;  //test the load and save of array element\n    //ARGS TEST\n    argtest = 456;    \n    s[3] = 655*argtest + s2[1] ;  //test the load and save of array element\n    println(s[3]);     \n}\n```\n\n## 6.5  集成测试\n\n通过这个测例可以测试几乎所有的实现的语法，使用assert语句进行判断程序运行的对错，如果assert失败，则会结束程序的运行，使用系统调用exit方法强制结束程序运行\n\n```c\n//SOME GLOBAL VARIABLES\nint test1,test2;\narray arr1[4];\narray arr2[8];\n\ndef void modifyGlobal()\n{\n    test1 = 111;\n    test2 = 222;\n    arr1[3] = 65535;\n    arr2[1] = 100;\n}\n\ndef int Fabio(int n)    //recursive\n{\n    array retval[2];\n\tif(n == 1 or n ==2)\n\t{\n\t\treturn 1;\n\t}\n\telse\n\t{\n\t    retval[0] = cal Fabio(n-1);\n\t    retval[1] = cal Fabio(n-2);\n\n\t\treturn retval[0]+retval[1];\n\t}\n}\n\ndef int factor( int N ){\n\tif( N \u003e 1 ){\n\t\treturn N * cal factor( N - 1 );\n\t}\n\telse{\n\t\treturn 1;\n\t}\n}\n\ndef void main(int argtest,int argtest2)\n{\n                                                //ARRAY TEST\n    array s[100];\n    int a,times;              //test whether the offset is set correctly\n    int result,start,end;           //For the test of Fibonacci sequence\n    int short1,short2,short3;\n    array s2[4];\n    const int test = 50+8*(66+3);\n    //START TEST!!!\n    println(\"******************Compiler naive****************\");\n    println(\"*****************author:Haohe Liu***************\");\n    println(\"*******************START TEST*******************\");\n    println(\"----------------1.Array test----------------\");\n\n    s2[1] = 456;\n    assert(s2[1], 456);\n    a = 543;\n    assert(a, 543);\n    s[3] = 655*a + s2[1];    //test the load and save of array element\n    assert(s[3], 356121);\n    argtest = 100;\n    assert(argtest, 100);\n    a = 1+(2+4)*100;\n    assert(a,601);\n    println(\"PASS\");\n                                                //RECURSIVE TEST\n    println(\"----------------2.recursive test------------\");\n\n    println(\"=========factorial test=========\");\n    times = 6;\n    a = cal factor(times);\n    println(\"\\tResult of recursive test:\\n\\t\");\n    println(a);\n    println(\"PASS\");\n\n    println(\"=========Fibonacci sequence test=========\");\n    start = 1;\n    end = 10;\n    println(\"\\tFibonacci sequence calculated by recursion from 1 to 10\");\n    while(start \u003c= end)\n    {\n        result = cal Fabio(start);\n        println(result);\n        start = start + 1;\n    }\n    println(\"PASS\");\n                                                //WHILE TEST\n    println(\"----------------3.while test----------------\");\n    println(\"\\tCount down from 10 to 5:\");\n    times = 10;\n    while(times \u003e= 0)\n    {\n        println(times);\n        if(times == 4){\n            break;\n        }\n        times  = times -1;\n    }\n    println(\"PASS\");\n                                                //IF TEST\n    println(\"----------------4.if test----------------\");\n    println(\"\\tValue of start: \\n\\t\");\n    println(start);\n    println(\"\\tValue of end \\n\\t\");\n    println(end);\n    if(start == 1 or end == 10){\n        println(\"\\tstart == 1 or end == 10\");\n    }\n    if(start \u003c 1 or end \u003e 10)\n    {\n        println(\"\\tstart \u003c 1 or end \u003e 10\");\n    }else\n    {\n        println(\"\\tstart \u003e= 1 or end \u003c= 10\");\n    }\n\n    println(\"PASS\");\n                                                //GOTO TEST\n    println(\"----------------5.goto test----------------\");\n    println(\"\\tStart of goto test, you will see nothing if it works\");\n    goto end;\n    println(\"\\tIf you see this, it means you are wrong!\");\n    dest end;\n    println(\"PASS\");\n                                                //SHORT CIRCUIT TEST\n    println(\"----------------6.short circuit test----------------\");\n    short1 = 10;\n    short2 = 100;\n    short3 = 1000;\n    assert(short3,1000);\n    while(short1 == 10 and short2 \u003c= 99 and short3 \u003e 900)\n    {\n        println(\"\\tShort circuit!\");\n        break;\n    }\n    println(\"PASS\");\n                                                //CONST TEST\n\n    println(\"----------------7.constant modification test----------------\");\n    println(\"!attension: in order to perform this test, please modify the original code\");\n    //test = 100;  //Const variable cannot be modified\n    println(\"PASS\");\n\n    println(\"----------------8.global modification test----------------\");\n    println(\"\\tBefore modification:\");\n    println(test1);\n    println(test2);\n    println(arr1[3]);\n    println(arr2[1]);\n    cal modifyGlobal()   //Call this function to modify the global variable\n    println(\"\\tAfter modification:\");\n    println(test1);\n    println(test2);\n    println(arr1[3]);\n    println(arr2[1]);\n    println(\"PASS\");\n\n    println(\"----------------9.String test----------------\");\n    println(\"\\tThis string has a \\\"double quotation\\\" in it\");\n    println(\"PASS\");\n\n\n    println(\"----------------10.exit test----------------\");\n    println(\"If you see nothing, then exit is success\");\n    println(\"PASS\");\n    exit;\n    println(\"Wrong man!\");\n\n\n}\n```\n\n# 7. Result 运行结果\n\n## 7.1 集成测试运行结果\n\n[![ZSqqYV.png](https://s2.ax1x.com/2019/06/21/ZSqqYV.png)](https://imgchr.com/i/ZSqqYV)\n\n```java\n-- program is finished running (dropped off bottom) --\n\n******************Compiler naive****************\n*****************author:Haohe Liu***************\n*******************START TEST*******************\n----------------1.Array test----------------\nPASS\n----------------2.recursive test------------\n=========factorial test=========\n\tResult of recursive test:\n\t\n720\nPASS\n=========Fibonacci sequence test=========\n\tFibonacci sequence calculated by recursion from 1 to 10\n1\n1\n2\n3\n5\n8\n13\n21\n34\n55\nPASS\n----------------3.while test----------------\n\tCount down from 10 to 5:\n10\n9\n8\n7\n6\n5\n4\nPASS\n----------------4.if test----------------\n\tValue of start: \n\t\n11\n\tValue of end \n\t\n10\n\tstart == 1 or end == 10\n\tstart \u003e= 1 or end \u003c= 10\nPASS\n----------------5.goto test----------------\n\tStart of goto test, you will see nothing if it works\nPASS\n----------------6.short circuit test----------------\nPASS\n----------------7.constant modification test----------------\n!attension: in order to perform this test, please modify the original code\nPASS\n----------------8.global modification test----------------\n\tBefore modification:\n0\n0\n0\n0\n\tAfter modification:\n111\n222\n65535\n100\nPASS\n----------------9.String test----------------\n\tThis string has a \"double quotation\" in it\nPASS\n----------------10.exit test----------------\nIf you see nothing, then exit is success\nPASS\n\n-- program is finished running --\n```\n\n\n\n## 7.2 集成测试汇编代码\n\n```java\n\t.text\nmove\t$fp,\t$sp\njal\tmain\nj\texit\naddi\t$gp,\t$gp,\t4\t\t\t#Space for variable: test1\naddi\t$gp,\t$gp,\t4\t\t\t#Space for variable: test2\n\nmodifyGlobal:\naddi\t$sp,\t$sp,\t-8\t\t\t#Create space for $ra and $fp\nsw\t$ra,\t4($sp)\nsw\t$fp,\t0($sp)\nmove\t$fp,\t$sp\n#Assignment statement for varaible: test1\nlw\t$t0,\t0($gp)\nli\t$t1,\t111\nmove\t$t0,\t$t1\nsw\t$t0,\t0($gp)\n#The end of assignment\n#Assignment statement for varaible: test2\nlw\t$t0,\t4($gp)\nli\t$t1,\t222\nmove\t$t0,\t$t1\nsw\t$t0,\t4($gp)\n#The end of assignment\n#Assignment statement for varaible: arr1[3]\nlw\t$t0,\t20($gp)\nli\t$t1,\t65535\nmove\t$t0,\t$t1\nsw\t$t0,\t20($gp)\n#The end of assignment\n#Assignment statement for varaible: arr2[1]\nlw\t$t0,\t28($gp)\nli\t$t1,\t100\nmove\t$t0,\t$t1\nsw\t$t0,\t28($gp)\n#The end of assignment\n#Restore register $ra and $fp\nlw\t$ra,\t4($fp)\nlw\t$fp,\t0($fp)\naddi\t$sp,\t$sp,\t0\t\t\t#pop stack all at once\njr\t$ra\n\nFabio:\naddi\t$sp,\t$sp,\t-12\t\t\t#Create space for args ,$ra and $fp\nsw\t$a0,\t8($sp)\nsw\t$ra,\t4($sp)\nsw\t$fp,\t0($sp)\nmove\t$fp,\t$sp\naddi\t$sp,\t$sp,\t-8\t\t\t#Create space for :  retval[2]\nlw\t$t0,\t8($fp)\nli\t$t1,\t1\nseq\t$s0,\t$t0,\t$t1\nlw\t$t2,\t8($fp)\nli\t$t3,\t2\nseq\t$s2,\t$t2,\t$t3\nor\t$s0,\t$s0,\t$s2\nbeq\t$zero,\t$s0,\tL0\nli\t$t0,\t1\n#return value of Fabio\nmove\t$v0,\t$t0\nj\tL1\nL0:\n#Assignment statement for varaible: retval[0]\nlw\t$t1,\t0($sp)\nlw\t$t2,\t8($fp)\nli\t$t3,\t1\nsub\t$t4,\t$t2,\t$t3\nmove\t$a0,\t$t4\naddi\t$sp,\t$sp,\t-20\t\t\t# 5 registers need to be saved\nsw\t$t4,\t16($sp)\nsw\t$t3,\t12($sp)\nsw\t$t2,\t8($sp)\nsw\t$t1,\t4($sp)\nsw\t$t0,\t0($sp)\n# Execute function: Fabio\njal\tFabio\nlw\t$t0,\t0($sp)\nlw\t$t1,\t4($sp)\nlw\t$t2,\t8($sp)\nlw\t$t3,\t12($sp)\nlw\t$t4,\t16($sp)\naddi\t$sp,\t$sp,\t20\t\t\t#Saved 5 registers pop stack\nmove\t$t1,\t$v0\nsw\t$t1,\t0($sp)\n#The end of assignment\n#Assignment statement for varaible: retval[1]\nlw\t$t0,\t4($sp)\nlw\t$t1,\t8($fp)\nli\t$t2,\t2\nsub\t$t3,\t$t1,\t$t2\nmove\t$a0,\t$t3\naddi\t$sp,\t$sp,\t-16\t\t\t# 4 registers need to be saved\nsw\t$t3,\t12($sp)\nsw\t$t2,\t8($sp)\nsw\t$t1,\t4($sp)\nsw\t$t0,\t0($sp)\n# Execute function: Fabio\njal\tFabio\nlw\t$t0,\t0($sp)\nlw\t$t1,\t4($sp)\nlw\t$t2,\t8($sp)\nlw\t$t3,\t12($sp)\naddi\t$sp,\t$sp,\t16\t\t\t#Saved 4 registers pop stack\nmove\t$t0,\t$v0\nsw\t$t0,\t4($sp)\n#The end of assignment\nlw\t$t0,\t0($sp)\nlw\t$t1,\t4($sp)\nadd\t$t2,\t$t1,\t$t0\n#return value of Fabio\nmove\t$v0,\t$t2\nL1:\n#Restore register $ra and $fp\nlw\t$ra,\t4($fp)\nlw\t$fp,\t0($fp)\naddi\t$sp,\t$sp,\t20\t\t\t#pop stack all at once\njr\t$ra\n\nfactor:\naddi\t$sp,\t$sp,\t-12\t\t\t#Create space for args ,$ra and $fp\nsw\t$a0,\t8($sp)\nsw\t$ra,\t4($sp)\nsw\t$fp,\t0($sp)\nmove\t$fp,\t$sp\nlw\t$t3,\t8($fp)\nli\t$t4,\t1\nsgt\t$s0,\t$t3,\t$t4\nbeq\t$zero,\t$s0,\tL2\nlw\t$t0,\t8($fp)\nlw\t$t1,\t8($fp)\nli\t$t2,\t1\nsub\t$t3,\t$t1,\t$t2\nmove\t$a0,\t$t3\naddi\t$sp,\t$sp,\t-16\t\t\t# 4 registers need to be saved\nsw\t$t3,\t12($sp)\nsw\t$t2,\t8($sp)\nsw\t$t1,\t4($sp)\nsw\t$t0,\t0($sp)\n# Execute function: factor\njal\tfactor\nlw\t$t0,\t0($sp)\nlw\t$t1,\t4($sp)\nlw\t$t2,\t8($sp)\nlw\t$t3,\t12($sp)\naddi\t$sp,\t$sp,\t16\t\t\t#Saved 4 registers pop stack\nmult\t$t0,\t$v0\nmflo\t$t0\n#return value of factor\nmove\t$v0,\t$t0\nj\tL3\nL2:\nli\t$t1,\t1\n#return value of factor\nmove\t$v0,\t$t1\nL3:\n#Restore register $ra and $fp\nlw\t$ra,\t4($fp)\nlw\t$fp,\t0($fp)\naddi\t$sp,\t$sp,\t12\t\t\t#pop stack all at once\njr\t$ra\n\nmain:\naddi\t$sp,\t$sp,\t-16\t\t\t#Create space for args ,$ra and $fp\nsw\t$a0,\t12($sp)\nsw\t$a1,\t8($sp)\nsw\t$ra,\t4($sp)\nsw\t$fp,\t0($sp)\nmove\t$fp,\t$sp\naddi\t$sp,\t$sp,\t-400\t\t\t#Create space for :  s[100]\naddi\t$sp,\t$sp,\t-8\t\t\t#Create space for local variables\naddi\t$sp,\t$sp,\t-20\t\t\t#Create space for local variables\naddi\t$sp,\t$sp,\t-32\t\t\t#Create space for local variables\naddi\t$sp,\t$sp,\t-16\t\t\t#Create space for :  s2[4]\naddi\t$sp,\t$sp,\t-4\t\t\t#Create space for const variable: test\nli\t$t2,\t66\nli\t$t3,\t3\nadd\t$t4,\t$t3,\t$t2\nli\t$t5,\t8\nmult\t$t5,\t$t4\nmflo\t$t6\nli\t$t7,\t50\nadd\t$t8,\t$t6,\t$t7\nsw\t$t8,\t0($sp)\n#println Statement\nla\t$t0,\tStr1\nli\t$v0,\t4\nmove\t$a0,\t$t0\nsyscall\n#println Statement\nla\t$t0,\tStr2\nli\t$v0,\t4\nmove\t$a0,\t$t0\nsyscall\n#println Statement\nla\t$t0,\tStr3\nli\t$v0,\t4\nmove\t$a0,\t$t0\nsyscall\n#println Statement\nla\t$t0,\tStr4\nli\t$v0,\t4\nmove\t$a0,\t$t0\nsyscall\n#Assignment statement for varaible: s2[1]\nlw\t$t0,\t8($sp)\nli\t$t1,\t456\nmove\t$t0,\t$t1\nsw\t$t0,\t8($sp)\n#The end of assignment\n# Assert statement\nlw\t$t0,\t8($sp)\nli\t$t1,\t456\nseq\t$s0,\t$t0,\t$t1\nbeq\t$zero,\t$s0,\tL5\t\t\t#If not equal, exit the hole program\nj\tL4\nL5:\nli\t$v0,\t10\nsyscall\nL4:\n#Assignment statement for varaible: a\nlw\t$t0,\t48($sp)\nli\t$t1,\t543\nmove\t$t0,\t$t1\nsw\t$t0,\t48($sp)\n#The end of assignment\n# Assert statement\nlw\t$t0,\t48($sp)\nli\t$t1,\t543\nseq\t$s0,\t$t0,\t$t1\nbeq\t$zero,\t$s0,\tL7\t\t\t#If not equal, exit the hole program\nj\tL6\nL7:\nli\t$v0,\t10\nsyscall\nL6:\n#Assignment statement for varaible: s[3]\nlw\t$t0,\t64($sp)\nlw\t$t1,\t48($sp)\nli\t$t2,\t655\nmult\t$t2,\t$t1\nmflo\t$t3\nlw\t$t4,\t8($sp)\nadd\t$t5,\t$t4,\t$t3\nmove\t$t0,\t$t5\nsw\t$t0,\t64($sp)\n#The end of assignment\n# Assert statement\nlw\t$t0,\t64($sp)\nli\t$t1,\t356121\nseq\t$s0,\t$t0,\t$t1\nbeq\t$zero,\t$s0,\tL9\t\t\t#If not equal, exit the hole program\nj\tL8\nL9:\nli\t$v0,\t10\nsyscall\nL8:\n#Assignment statement for varaible: argtest\nlw\t$t0,\t8($fp)\nli\t$t1,\t100\nmove\t$t0,\t$t1\nsw\t$t0,\t8($fp)\n#The end of assignment\n# Assert statement\nlw\t$t0,\t8($fp)\nli\t$t1,\t100\nseq\t$s0,\t$t0,\t$t1\nbeq\t$zero,\t$s0,\tL11\t\t\t#If not equal, exit the hole program\nj\tL10\nL11:\nli\t$v0,\t10\nsyscall\nL10:\n#Assignment statement for varaible: a\nlw\t$t0,\t48($sp)\nli\t$t1,\t2\nli\t$t2,\t4\nadd\t$t3,\t$t2,\t$t1\nli\t$t4,\t100\nmult\t$t3,\t$t4\nmflo\t$t5\nli\t$t6,\t1\nadd\t$t7,\t$t5,\t$t6\nmove\t$t0,\t$t7\nsw\t$t0,\t48($sp)\n#The end of assignment\n# Assert statement\nlw\t$t0,\t48($sp)\nli\t$t1,\t601\nseq\t$s0,\t$t0,\t$t1\nbeq\t$zero,\t$s0,\tL13\t\t\t#If not equal, exit the hole program\nj\tL12\nL13:\nli\t$v0,\t10\nsyscall\nL12:\n#println Statement\nla\t$t0,\tStr5\nli\t$v0,\t4\nmove\t$a0,\t$t0\nsyscall\n#println Statement\nla\t$t0,\tStr6\nli\t$v0,\t4\nmove\t$a0,\t$t0\nsyscall\n#println Statement\nla\t$t0,\tStr7\nli\t$v0,\t4\nmove\t$a0,\t$t0\nsyscall\n#Assignment statement for varaible: times\nlw\t$t0,\t44($sp)\nli\t$t1,\t6\nmove\t$t0,\t$t1\nsw\t$t0,\t44($sp)\n#The end of assignment\n#Assignment statement for varaible: a\nlw\t$t0,\t48($sp)\nlw\t$t1,\t44($sp)\nmove\t$a0,\t$t1\naddi\t$sp,\t$sp,\t-8\t\t\t# 2 registers need to be saved\nsw\t$t1,\t4($sp)\nsw\t$t0,\t0($sp)\n# Execute function: factor\njal\tfactor\nlw\t$t0,\t0($sp)\nlw\t$t1,\t4($sp)\naddi\t$sp,\t$sp,\t8\t\t\t#Saved 2 registers pop stack\nmove\t$t0,\t$v0\nsw\t$t0,\t48($sp)\n#The end of assignment\n#println Statement\nla\t$t0,\tStr8\nli\t$v0,\t4\nmove\t$a0,\t$t0\nsyscall\n#println Statement\nlw\t$t0,\t48($sp)\nli\t$v0,\t1\nmove\t$a0,\t$t0\nsyscall\nla\t$t0,\tStr0\nli\t$v0,\t4\nmove\t$a0,\t$t0\nsyscall\n#println Statement\nla\t$t0,\tStr9\nli\t$v0,\t4\nmove\t$a0,\t$t0\nsyscall\n#println Statement\nla\t$t0,\tStr10\nli\t$v0,\t4\nmove\t$a0,\t$t0\nsyscall\n#Assignment statement for varaible: start\nlw\t$t0,\t36($sp)\nli\t$t1,\t1\nmove\t$t0,\t$t1\nsw\t$t0,\t36($sp)\n#The end of assignment\n#Assignment statement for varaible: end\nlw\t$t0,\t32($sp)\nli\t$t1,\t10\nmove\t$t0,\t$t1\nsw\t$t0,\t32($sp)\n#The end of assignment\n#println Statement\nla\t$t0,\tStr11\nli\t$v0,\t4\nmove\t$a0,\t$t0\nsyscall\n# WhileStatement\nL14:\nlw\t$t0,\t36($sp)\nlw\t$t1,\t32($sp)\nsle\t$s0,\t$t0,\t$t1\nbeq\t$zero,\t$s0,\tL15\n#Assignment statement for varaible: result\nlw\t$t0,\t40($sp)\nlw\t$t1,\t36($sp)\nmove\t$a0,\t$t1\naddi\t$sp,\t$sp,\t-8\t\t\t# 2 registers need to be saved\nsw\t$t1,\t4($sp)\nsw\t$t0,\t0($sp)\n# Execute function: Fabio\njal\tFabio\nlw\t$t0,\t0($sp)\nlw\t$t1,\t4($sp)\naddi\t$sp,\t$sp,\t8\t\t\t#Saved 2 registers pop stack\nmove\t$t0,\t$v0\nsw\t$t0,\t40($sp)\n#The end of assignment\n#println Statement\nlw\t$t0,\t40($sp)\nli\t$v0,\t1\nmove\t$a0,\t$t0\nsyscall\nla\t$t0,\tStr0\nli\t$v0,\t4\nmove\t$a0,\t$t0\nsyscall\n#Assignment statement for varaible: start\nlw\t$t0,\t36($sp)\nlw\t$t1,\t36($sp)\nli\t$t2,\t1\nadd\t$t3,\t$t2,\t$t1\nmove\t$t0,\t$t3\nsw\t$t0,\t36($sp)\n#The end of assignment\nj\tL14\nL15:\n#println Statement\nla\t$t0,\tStr12\nli\t$v0,\t4\nmove\t$a0,\t$t0\nsyscall\n#println Statement\nla\t$t0,\tStr13\nli\t$v0,\t4\nmove\t$a0,\t$t0\nsyscall\n#println Statement\nla\t$t0,\tStr14\nli\t$v0,\t4\nmove\t$a0,\t$t0\nsyscall\n#Assignment statement for varaible: times\nlw\t$t0,\t44($sp)\nli\t$t1,\t10\nmove\t$t0,\t$t1\nsw\t$t0,\t44($sp)\n#The end of assignment\n# WhileStatement\nL16:\nlw\t$t0,\t44($sp)\nli\t$t1,\t0\nsge\t$s0,\t$t0,\t$t1\nbeq\t$zero,\t$s0,\tL17\n#println Statement\nlw\t$t0,\t44($sp)\nli\t$v0,\t1\nmove\t$a0,\t$t0\nsyscall\nla\t$t0,\tStr0\nli\t$v0,\t4\nmove\t$a0,\t$t0\nsyscall\nlw\t$t0,\t44($sp)\nli\t$t1,\t4\nseq\t$s0,\t$t0,\t$t1\nbeq\t$zero,\t$s0,\tL18\nj\tL17\nj\tL19\nL18:\nL19:\n#Assignment statement for varaible: times\nlw\t$t0,\t44($sp)\nlw\t$t1,\t44($sp)\nli\t$t2,\t1\nsub\t$t3,\t$t1,\t$t2\nmove\t$t0,\t$t3\nsw\t$t0,\t44($sp)\n#The end of assignment\nj\tL16\nL17:\n#println Statement\nla\t$t0,\tStr15\nli\t$v0,\t4\nmove\t$a0,\t$t0\nsyscall\n#println Statement\nla\t$t0,\tStr16\nli\t$v0,\t4\nmove\t$a0,\t$t0\nsyscall\n#println Statement\nla\t$t0,\tStr17\nli\t$v0,\t4\nmove\t$a0,\t$t0\nsyscall\n#println Statement\nlw\t$t0,\t36($sp)\nli\t$v0,\t1\nmove\t$a0,\t$t0\nsyscall\nla\t$t0,\tStr0\nli\t$v0,\t4\nmove\t$a0,\t$t0\nsyscall\n#println Statement\nla\t$t0,\tStr18\nli\t$v0,\t4\nmove\t$a0,\t$t0\nsyscall\n#println Statement\nlw\t$t0,\t32($sp)\nli\t$v0,\t1\nmove\t$a0,\t$t0\nsyscall\nla\t$t0,\tStr0\nli\t$v0,\t4\nmove\t$a0,\t$t0\nsyscall\nlw\t$t0,\t36($sp)\nli\t$t1,\t1\nseq\t$s0,\t$t0,\t$t1\nlw\t$t2,\t32($sp)\nli\t$t3,\t10\nseq\t$s2,\t$t2,\t$t3\nor\t$s0,\t$s0,\t$s2\nbeq\t$zero,\t$s0,\tL20\n#println Statement\nla\t$t0,\tStr19\nli\t$v0,\t4\nmove\t$a0,\t$t0\nsyscall\nj\tL21\nL20:\nL21:\nlw\t$t0,\t36($sp)\nli\t$t1,\t1\nslt\t$s0,\t$t0,\t$t1\nlw\t$t2,\t32($sp)\nli\t$t3,\t10\nsgt\t$s1,\t$t2,\t$t3\nor\t$s0,\t$s0,\t$s1\nbeq\t$zero,\t$s0,\tL22\n#println Statement\nla\t$t0,\tStr20\nli\t$v0,\t4\nmove\t$a0,\t$t0\nsyscall\nj\tL23\nL22:\n#println Statement\nla\t$t0,\tStr21\nli\t$v0,\t4\nmove\t$a0,\t$t0\nsyscall\nL23:\n#println Statement\nla\t$t0,\tStr22\nli\t$v0,\t4\nmove\t$a0,\t$t0\nsyscall\n#println Statement\nla\t$t0,\tStr23\nli\t$v0,\t4\nmove\t$a0,\t$t0\nsyscall\n#println Statement\nla\t$t0,\tStr24\nli\t$v0,\t4\nmove\t$a0,\t$t0\nsyscall\nj\tend\n#println Statement\nla\t$t0,\tStr25\nli\t$v0,\t4\nmove\t$a0,\t$t0\nsyscall\nend:\n#println Statement\nla\t$t0,\tStr26\nli\t$v0,\t4\nmove\t$a0,\t$t0\nsyscall\n#println Statement\nla\t$t0,\tStr27\nli\t$v0,\t4\nmove\t$a0,\t$t0\nsyscall\n#Assignment statement for varaible: short1\nlw\t$t0,\t28($sp)\nli\t$t1,\t10\nmove\t$t0,\t$t1\nsw\t$t0,\t28($sp)\n#The end of assignment\n#Assignment statement for varaible: short2\nlw\t$t0,\t24($sp)\nli\t$t1,\t100\nmove\t$t0,\t$t1\nsw\t$t0,\t24($sp)\n#The end of assignment\n#Assignment statement for varaible: short3\nlw\t$t0,\t20($sp)\nli\t$t1,\t1000\nmove\t$t0,\t$t1\nsw\t$t0,\t20($sp)\n#The end of assignment\n# Assert statement\nlw\t$t0,\t20($sp)\nli\t$t1,\t1000\nseq\t$s0,\t$t0,\t$t1\nbeq\t$zero,\t$s0,\tL25\t\t\t#If not equal, exit the hole program\nj\tL24\nL25:\nli\t$v0,\t10\nsyscall\nL24:\n# WhileStatement\nL26:\nlw\t$t0,\t28($sp)\nli\t$t1,\t10\nseq\t$s0,\t$t0,\t$t1\nlw\t$t2,\t24($sp)\nli\t$t3,\t99\nsle\t$s2,\t$t2,\t$t3\nlw\t$t4,\t20($sp)\nli\t$t5,\t900\nsgt\t$s4,\t$t4,\t$t5\nbeq\t$zero,\t$s2,\tL27\t\t\t#Short circuit supported\nand\t$s0,\t$s2,\t$s4\nbeq\t$zero,\t$s0,\tL27\t\t\t#Short circuit supported\nand\t$s0,\t$s0,\t$s2\nbeq\t$zero,\t$s0,\tL27\n#println Statement\nla\t$t0,\tStr28\nli\t$v0,\t4\nmove\t$a0,\t$t0\nsyscall\nj\tL27\nj\tL26\nL27:\n#println Statement\nla\t$t0,\tStr29\nli\t$v0,\t4\nmove\t$a0,\t$t0\nsyscall\n#println Statement\nla\t$t0,\tStr30\nli\t$v0,\t4\nmove\t$a0,\t$t0\nsyscall\n#println Statement\nla\t$t0,\tStr31\nli\t$v0,\t4\nmove\t$a0,\t$t0\nsyscall\n#println Statement\nla\t$t0,\tStr32\nli\t$v0,\t4\nmove\t$a0,\t$t0\nsyscall\n#println Statement\nla\t$t0,\tStr33\nli\t$v0,\t4\nmove\t$a0,\t$t0\nsyscall\n#println Statement\nla\t$t0,\tStr34\nli\t$v0,\t4\nmove\t$a0,\t$t0\nsyscall\n#println Statement\nlw\t$t0,\t0($gp)\nli\t$v0,\t1\nmove\t$a0,\t$t0\nsyscall\nla\t$t0,\tStr0\nli\t$v0,\t4\nmove\t$a0,\t$t0\nsyscall\n#println Statement\nlw\t$t0,\t4($gp)\nli\t$v0,\t1\nmove\t$a0,\t$t0\nsyscall\nla\t$t0,\tStr0\nli\t$v0,\t4\nmove\t$a0,\t$t0\nsyscall\n#println Statement\nlw\t$t0,\t20($gp)\nli\t$v0,\t1\nmove\t$a0,\t$t0\nsyscall\nla\t$t0,\tStr0\nli\t$v0,\t4\nmove\t$a0,\t$t0\nsyscall\n#println Statement\nlw\t$t0,\t28($gp)\nli\t$v0,\t1\nmove\t$a0,\t$t0\nsyscall\nla\t$t0,\tStr0\nli\t$v0,\t4\nmove\t$a0,\t$t0\nsyscall\naddi\t$sp,\t$sp,\t0\t\t\t# 0 registers need to be saved\n# Execute function: modifyGlobal\njal\tmodifyGlobal\naddi\t$sp,\t$sp,\t0\t\t\t#Saved 0 registers pop stack\n#println Statement\nla\t$t0,\tStr35\nli\t$v0,\t4\nmove\t$a0,\t$t0\nsyscall\n#println Statement\nlw\t$t0,\t0($gp)\nli\t$v0,\t1\nmove\t$a0,\t$t0\nsyscall\nla\t$t0,\tStr0\nli\t$v0,\t4\nmove\t$a0,\t$t0\nsyscall\n#println Statement\nlw\t$t0,\t4($gp)\nli\t$v0,\t1\nmove\t$a0,\t$t0\nsyscall\nla\t$t0,\tStr0\nli\t$v0,\t4\nmove\t$a0,\t$t0\nsyscall\n#println Statement\nlw\t$t0,\t20($gp)\nli\t$v0,\t1\nmove\t$a0,\t$t0\nsyscall\nla\t$t0,\tStr0\nli\t$v0,\t4\nmove\t$a0,\t$t0\nsyscall\n#println Statement\nlw\t$t0,\t28($gp)\nli\t$v0,\t1\nmove\t$a0,\t$t0\nsyscall\nla\t$t0,\tStr0\nli\t$v0,\t4\nmove\t$a0,\t$t0\nsyscall\n#println Statement\nla\t$t0,\tStr36\nli\t$v0,\t4\nmove\t$a0,\t$t0\nsyscall\n#println Statement\nla\t$t0,\tStr37\nli\t$v0,\t4\nmove\t$a0,\t$t0\nsyscall\n#println Statement\nla\t$t0,\tStr38\nli\t$v0,\t4\nmove\t$a0,\t$t0\nsyscall\n#println Statement\nla\t$t0,\tStr39\nli\t$v0,\t4\nmove\t$a0,\t$t0\nsyscall\n#println Statement\nla\t$t0,\tStr40\nli\t$v0,\t4\nmove\t$a0,\t$t0\nsyscall\n#println Statement\nla\t$t0,\tStr41\nli\t$v0,\t4\nmove\t$a0,\t$t0\nsyscall\n#println Statement\nla\t$t0,\tStr42\nli\t$v0,\t4\nmove\t$a0,\t$t0\nsyscall\nli\t$v0,\t10\nsyscall\n#println Statement\nla\t$t0,\tStr43\nli\t$v0,\t4\nmove\t$a0,\t$t0\nsyscall\n#Restore register $ra and $fp\nlw\t$ra,\t4($fp)\nlw\t$fp,\t0($fp)\naddi\t$sp,\t$sp,\t468\t\t\t#pop stack all at once\njr\t$ra\nexit:\n\t.data\nStr0:\t.asciiz\t\"\\n\"\nStr1:\t.asciiz\t\"******************Compiler naive****************\\n\"\nStr2:\t.asciiz\t\"*****************author:Haohe Liu***************\\n\"\nStr3:\t.asciiz\t\"*******************START TEST*******************\\n\"\nStr4:\t.asciiz\t\"----------------1.Array test----------------\\n\"\nStr5:\t.asciiz\t\"PASS\\n\"\nStr6:\t.asciiz\t\"----------------2.recursive test------------\\n\"\nStr7:\t.asciiz\t\"=========factorial test=========\\n\"\nStr8:\t.asciiz\t\"\\tResult of recursive test:\\n\\t\\n\"\nStr9:\t.asciiz\t\"PASS\\n\"\nStr10:\t.asciiz\t\"=========Fibonacci sequence test=========\\n\"\nStr11:\t.asciiz\t\"\\tFibonacci sequence calculated by recursion from 1 to 10\\n\"\nStr12:\t.asciiz\t\"PASS\\n\"\nStr13:\t.asciiz\t\"----------------3.while test----------------\\n\"\nStr14:\t.asciiz\t\"\\tCount down from 10 to 5:\\n\"\nStr15:\t.asciiz\t\"PASS\\n\"\nStr16:\t.asciiz\t\"----------------4.if test----------------\\n\"\nStr17:\t.asciiz\t\"\\tValue of start: \\n\\t\\n\"\nStr18:\t.asciiz\t\"\\tValue of end \\n\\t\\n\"\nStr19:\t.asciiz\t\"\\tstart == 1 or end == 10\\n\"\nStr20:\t.asciiz\t\"\\tstart \u003c 1 or end \u003e 10\\n\"\nStr21:\t.asciiz\t\"\\tstart \u003e= 1 or end \u003c= 10\\n\"\nStr22:\t.asciiz\t\"PASS\\n\"\nStr23:\t.asciiz\t\"----------------5.goto test----------------\\n\"\nStr24:\t.asciiz\t\"\\tStart of goto test, you will see nothing if it works\\n\"\nStr25:\t.asciiz\t\"\\tIf you see this, it means you are wrong!\\n\"\nStr26:\t.asciiz\t\"PASS\\n\"\nStr27:\t.asciiz\t\"----------------6.short circuit test----------------\\n\"\nStr28:\t.asciiz\t\"\\tShort circuit!\\n\"\nStr29:\t.asciiz\t\"PASS\\n\"\nStr30:\t.asciiz\t\"----------------7.constant modification test----------------\\n\"\nStr31:\t.asciiz\t\"!attension: in order to perform this test, please modify the original code\\n\"\nStr32:\t.asciiz\t\"PASS\\n\"\nStr33:\t.asciiz\t\"----------------8.global modification test----------------\\n\"\nStr34:\t.asciiz\t\"\\tBefore modification:\\n\"\nStr35:\t.asciiz\t\"\\tAfter modification:\\n\"\nStr36:\t.asciiz\t\"PASS\\n\"\nStr37:\t.asciiz\t\"----------------9.String test----------------\\n\"\nStr38:\t.asciiz\t\"\\tThis string has a \\\"double quotation\\\" in it\\n\"\nStr39:\t.asciiz\t\"PASS\\n\"\nStr40:\t.asciiz\t\"----------------10.exit test----------------\\n\"\nStr41:\t.asciiz\t\"If you see nothing, then exit is success\\n\"\nStr42:\t.asciiz\t\"PASS\\n\"\nStr43:\t.asciiz\t\"Wrong man!\\n\"\n\n```\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhaoheliu%2Fcourseproject_compiler","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fhaoheliu%2Fcourseproject_compiler","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhaoheliu%2Fcourseproject_compiler/lists"}