diff --git a/.vscode/settings.json b/.vscode/settings.json index 1728226..6cad6e4 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,5 +1,6 @@ { "files.associations": { - "random": "c" + "random": "c", + "iostream": "cpp" } } \ No newline at end of file diff --git a/.vscode/tasks.json b/.vscode/tasks.json new file mode 100644 index 0000000..05054c5 --- /dev/null +++ b/.vscode/tasks.json @@ -0,0 +1,28 @@ +{ + "tasks": [ + { + "type": "cppbuild", + "label": "C/C++: g++ build active file", + "command": "/usr/bin/g++", + "args": [ + "-fdiagnostics-color=always", + "-g", + "${file}", + "-o", + "${fileDirname}/${fileBasenameNoExtension}" + ], + "options": { + "cwd": "${fileDirname}" + }, + "problemMatcher": [ + "$gcc" + ], + "group": { + "kind": "build", + "isDefault": true + }, + "detail": "Task generated by Debugger." + } + ], + "version": "2.0.0" +} \ No newline at end of file diff --git a/Assignment3/include/functions.h b/Assignment3/include/functions.h index 2a8d370..c027070 100644 --- a/Assignment3/include/functions.h +++ b/Assignment3/include/functions.h @@ -134,23 +134,67 @@ bool startsWithPointerOrAddress(const string& line) { } // Function to clean Three-Address Code from input file and write to output file +// void cleanTAC(string input) { +// int lineno=1; +// string line=""; +// int index=0; +// while(index= 2 && line.front() == '\"' && line.back() == '\"'; +} + void cleanTAC(string input) { - int lineno=1; - string line=""; - int index=0; - while(indexptr, (yyvsp[0].symbol_info)->symbol_size); (yyval.symbol_info)->place=qid(std::to_string(*(int*)((yyvsp[0].symbol_info)->ptr)),nullptr); (yyval.symbol_info)->code=std::to_string(*(int*)((yyvsp[0].symbol_info)->ptr)); } -#line 1916 "parser.tab.c" +#line 1928 "parser.tab.c" break; case 3: /* constant: FLOAT_LITERAL */ -#line 82 "src/parser.y" +#line 83 "src/parser.y" { (yyval.symbol_info)= new symbol_info("", "float", (yyvsp[0].symbol_info)->ptr, (yyvsp[0].symbol_info)->symbol_size); (yyval.symbol_info)->place=qid(std::to_string(*(float*)((yyvsp[0].symbol_info)->ptr)),nullptr); (yyval.symbol_info)->code=std::to_string(*(float*)((yyvsp[0].symbol_info)->ptr)); } -#line 1926 "parser.tab.c" +#line 1938 "parser.tab.c" break; case 4: /* constant: EXP_LITERAL */ -#line 87 "src/parser.y" +#line 88 "src/parser.y" {(yyval.symbol_info) = new symbol_info("", "exp", (yyvsp[0].symbol_info)->ptr, (yyvsp[0].symbol_info)->symbol_size);} -#line 1932 "parser.tab.c" +#line 1944 "parser.tab.c" break; case 5: /* constant: HEXA_LITERAL */ -#line 88 "src/parser.y" +#line 89 "src/parser.y" {(yyval.symbol_info) = new symbol_info("", "hexa", (yyvsp[0].symbol_info)->ptr, (yyvsp[0].symbol_info)->symbol_size);} -#line 1938 "parser.tab.c" +#line 1950 "parser.tab.c" break; case 6: /* constant: REAL_LITERAL */ -#line 89 "src/parser.y" +#line 90 "src/parser.y" {(yyval.symbol_info) = new symbol_info("", "real", (yyvsp[0].symbol_info)->ptr, (yyvsp[0].symbol_info)->symbol_size);} -#line 1944 "parser.tab.c" +#line 1956 "parser.tab.c" break; case 7: /* constant: STRING_LITERAL */ -#line 91 "src/parser.y" +#line 92 "src/parser.y" { (yyval.symbol_info) = new symbol_info("", "char*", (yyvsp[0].symbol_info)->ptr, (yyvsp[0].symbol_info)->symbol_size); (yyval.symbol_info)->str_val=(yyvsp[0].symbol_info)->str_val; (yyval.symbol_info)->place=qid((yyvsp[0].symbol_info)->str_val,nullptr); (yyval.symbol_info)->code=(yyvsp[0].symbol_info)->str_val; } -#line 1955 "parser.tab.c" +#line 1967 "parser.tab.c" break; case 8: /* constant: OCTAL_LITERAL */ -#line 97 "src/parser.y" +#line 98 "src/parser.y" {(yyval.symbol_info) = new symbol_info("", "octal", (yyvsp[0].symbol_info)->ptr, (yyvsp[0].symbol_info)->symbol_size);} -#line 1961 "parser.tab.c" +#line 1973 "parser.tab.c" break; case 9: /* constant: CHARACTER_LITERAL */ -#line 99 "src/parser.y" +#line 100 "src/parser.y" { (yyval.symbol_info) = new symbol_info("", "char", (yyvsp[0].symbol_info)->ptr, (yyvsp[0].symbol_info)->symbol_size); string tempp = "'"; @@ -1970,11 +1982,11 @@ yyparse (void) (yyval.symbol_info)->place=qid(tempp,nullptr); (yyval.symbol_info)->code=tempp; } -#line 1974 "parser.tab.c" +#line 1986 "parser.tab.c" break; case 10: /* primary_expression: ID */ -#line 111 "src/parser.y" +#line 112 "src/parser.y" { symbol_info* new_symbol = new symbol_info((yyvsp[0].str)); (yyval.symbol_info) = new_symbol; @@ -1991,19 +2003,19 @@ yyparse (void) (yyval.symbol_info)->is_array=find_symbol->is_array; } } -#line 1995 "parser.tab.c" +#line 2007 "parser.tab.c" break; case 11: /* primary_expression: constant */ -#line 128 "src/parser.y" +#line 129 "src/parser.y" { (yyval.symbol_info) = (yyvsp[0].symbol_info); } -#line 2003 "parser.tab.c" +#line 2015 "parser.tab.c" break; case 13: /* primary_expression: LPARENTHESES expression RPARENTHESES */ -#line 133 "src/parser.y" +#line 134 "src/parser.y" { symbol_info* new_symbol = new symbol_info(); new_symbol->place=newtemp((yyvsp[-1].symbol_info)->type,curr_scope); @@ -2012,19 +2024,19 @@ yyparse (void) new_symbol->code=(yyvsp[-1].symbol_info)->code+"\n"+new_symbol->place.first+":= ("+(yyvsp[-1].symbol_info)->place.first+")"; (yyval.symbol_info)=new_symbol; } -#line 2016 "parser.tab.c" +#line 2028 "parser.tab.c" break; case 14: /* postfix_expression: primary_expression */ -#line 145 "src/parser.y" +#line 146 "src/parser.y" { (yyval.symbol_info)=(yyvsp[0].symbol_info); } -#line 2024 "parser.tab.c" +#line 2036 "parser.tab.c" break; case 15: /* postfix_expression: postfix_expression LBRACKET expression RBRACKET */ -#line 149 "src/parser.y" +#line 150 "src/parser.y" { string array_name=(yyvsp[-3].symbol_info)->name; symbol_info* find_symbol = lookup_symbol_global(array_name, curr_scope); @@ -2056,11 +2068,11 @@ yyparse (void) } } -#line 2060 "parser.tab.c" +#line 2072 "parser.tab.c" break; case 16: /* postfix_expression: postfix_expression LPARENTHESES RPARENTHESES */ -#line 181 "src/parser.y" +#line 182 "src/parser.y" { symbol_info* find_symbol = lookup_symbol_global((yyvsp[-2].symbol_info)->name, curr_scope); if(find_symbol == nullptr) { @@ -2090,11 +2102,11 @@ yyparse (void) } } -#line 2094 "parser.tab.c" +#line 2106 "parser.tab.c" break; case 17: /* postfix_expression: postfix_expression LPARENTHESES argument_expression_list RPARENTHESES */ -#line 211 "src/parser.y" +#line 212 "src/parser.y" { (yyval.symbol_info) = new symbol_info(); symbol_info* find_symbol = lookup_symbol_global((yyvsp[-3].symbol_info)->name, curr_scope); @@ -2133,11 +2145,11 @@ yyparse (void) (yyval.symbol_info)->type=find_symbol->type; } } -#line 2137 "parser.tab.c" +#line 2149 "parser.tab.c" break; case 18: /* postfix_expression: postfix_expression DOT ID */ -#line 250 "src/parser.y" +#line 251 "src/parser.y" { symbol_info* find_symbol = lookup_symbol_global((yyvsp[-2].symbol_info)->name, curr_scope); if(find_symbol == nullptr) { @@ -2208,11 +2220,11 @@ yyparse (void) } } -#line 2212 "parser.tab.c" +#line 2224 "parser.tab.c" break; case 20: /* postfix_expression: postfix_expression INCREMENT */ -#line 322 "src/parser.y" +#line 323 "src/parser.y" { if((yyvsp[-1].symbol_info)->is_array==true){ string code = get_last_line((yyvsp[-1].symbol_info)->code); @@ -2221,11 +2233,11 @@ yyparse (void) else (yyval.symbol_info)->code=(yyvsp[-1].symbol_info)->code + "\n" + (yyvsp[-1].symbol_info)->place.first+":= "+(yyvsp[-1].symbol_info)->place.first+"+1"; } -#line 2225 "parser.tab.c" +#line 2237 "parser.tab.c" break; case 21: /* postfix_expression: postfix_expression DECREMENT */ -#line 331 "src/parser.y" +#line 332 "src/parser.y" { if((yyvsp[-1].symbol_info)->is_array==true){ string code = get_last_line((yyvsp[-1].symbol_info)->code); @@ -2233,19 +2245,20 @@ yyparse (void) } else (yyval.symbol_info)->code=(yyvsp[-1].symbol_info)->code + "\n" + (yyvsp[-1].symbol_info)->place.first+":= "+(yyvsp[-1].symbol_info)->place.first+"-1"; } -#line 2237 "parser.tab.c" +#line 2249 "parser.tab.c" break; case 22: /* argument_expression_list: assignment_expression */ -#line 342 "src/parser.y" +#line 343 "src/parser.y" { if((yyvsp[0].symbol_info)->place.first!=""){ - // debug("herrrr ", $1->code); + (yyval.symbol_info)->code=(yyvsp[0].symbol_info)->code; (yyval.symbol_info)->param_types.push_back((yyvsp[0].symbol_info)->type); (yyval.symbol_info)->param_list.push_back((yyvsp[0].symbol_info)->place.first); } else{ + // debug("gggggggggggggg ", $1->code); if((yyvsp[0].symbol_info)->name==""){ (yyval.symbol_info)=new symbol_info((yyvsp[0].symbol_info)); (yyval.symbol_info)->param_types.push_back((yyvsp[0].symbol_info)->type); @@ -2268,11 +2281,11 @@ yyparse (void) } } -#line 2272 "parser.tab.c" +#line 2285 "parser.tab.c" break; case 23: /* argument_expression_list: argument_expression_list COMMA assignment_expression */ -#line 374 "src/parser.y" +#line 376 "src/parser.y" { if((yyvsp[0].symbol_info)->place.first!=""){ (yyval.symbol_info)->code=(yyvsp[-2].symbol_info)->code + "\n" + (yyvsp[0].symbol_info)->code; @@ -2304,19 +2317,45 @@ yyparse (void) } } -#line 2308 "parser.tab.c" +#line 2321 "parser.tab.c" break; case 24: /* unary_expression: postfix_expression */ -#line 409 "src/parser.y" +#line 411 "src/parser.y" { (yyval.symbol_info)=(yyvsp[0].symbol_info); } -#line 2316 "parser.tab.c" +#line 2329 "parser.tab.c" break; - case 27: /* unary_expression: unary_operator cast_expression */ + case 25: /* unary_expression: INCREMENT unary_expression */ #line 415 "src/parser.y" + { + symbol_info* new_symbol=new symbol_info(); + (yyval.symbol_info)=new_symbol; + (yyval.symbol_info)->name=(yyvsp[0].symbol_info)->name; + (yyval.symbol_info)->place=(yyvsp[0].symbol_info)->place; + (yyval.symbol_info)->code=(yyvsp[0].symbol_info)->code + "\n" + (yyvsp[0].symbol_info)->place.first+":= "+(yyvsp[0].symbol_info)->place.first+"+1"; + + } +#line 2342 "parser.tab.c" + break; + + case 26: /* unary_expression: DECREMENT unary_expression */ +#line 424 "src/parser.y" + { + symbol_info* new_symbol=new symbol_info(); + (yyval.symbol_info)=new_symbol; + (yyval.symbol_info)->name=(yyvsp[0].symbol_info)->name; + (yyval.symbol_info)->place=(yyvsp[0].symbol_info)->place; + (yyval.symbol_info)->code=(yyvsp[0].symbol_info)->code + "\n" + (yyvsp[0].symbol_info)->place.first+":= "+(yyvsp[0].symbol_info)->place.first+"-1"; + + } +#line 2355 "parser.tab.c" + break; + + case 27: /* unary_expression: unary_operator cast_expression */ +#line 433 "src/parser.y" { symbol_info* new_symbol=new symbol_info(); string original_type=(yyvsp[0].symbol_info)->type; @@ -2332,16 +2371,24 @@ yyparse (void) (yyval.symbol_info)->type.pop_back(); } } + // if($1->code=="-"){ + // debug("ddddd",$2->name); + // qid var=newtemp($2->type,curr_scope); + + // if($2->name!="") $$->code=$2->code+"\n"+var.first+":= -"+$2->name; + // else if($2->place.first!="") $$->code=$2->code+"\n"+var.first+":= -"+$2->place.first; + // $$->place=var; + // } (yyval.symbol_info)->name=(yyvsp[0].symbol_info)->name; (yyval.symbol_info)->code=(yyvsp[0].symbol_info)->code+"\n"+(yyvsp[-1].symbol_info)->code+(yyvsp[0].symbol_info)->place.first; (yyval.symbol_info)->place.first=(yyvsp[-1].symbol_info)->code+(yyvsp[0].symbol_info)->place.first; } -#line 2341 "parser.tab.c" +#line 2388 "parser.tab.c" break; case 30: /* unary_operator: AMPERSAND */ -#line 440 "src/parser.y" +#line 466 "src/parser.y" { symbol_info* new_symbol=new symbol_info(); (yyval.symbol_info)=new_symbol; @@ -2349,89 +2396,90 @@ yyparse (void) (yyval.symbol_info)->code="&"; (yyval.symbol_info)->pointer_depth++; } -#line 2353 "parser.tab.c" +#line 2400 "parser.tab.c" break; case 31: /* unary_operator: STAR */ -#line 448 "src/parser.y" +#line 474 "src/parser.y" { symbol_info* new_symbol=new symbol_info(); (yyval.symbol_info)=new_symbol; (yyval.symbol_info)->name="star"; (yyval.symbol_info)->code="*"; } -#line 2364 "parser.tab.c" +#line 2411 "parser.tab.c" break; case 32: /* unary_operator: PLUS */ -#line 455 "src/parser.y" +#line 481 "src/parser.y" { symbol_info* new_symbol=new symbol_info(); (yyval.symbol_info)=new_symbol; (yyval.symbol_info)->name="plus"; (yyval.symbol_info)->code="+"; } -#line 2375 "parser.tab.c" +#line 2422 "parser.tab.c" break; case 33: /* unary_operator: MINUS */ -#line 462 "src/parser.y" +#line 488 "src/parser.y" { symbol_info* new_symbol=new symbol_info(); (yyval.symbol_info)=new_symbol; (yyval.symbol_info)->name="minus"; (yyval.symbol_info)->code="-"; } -#line 2386 "parser.tab.c" +#line 2433 "parser.tab.c" break; case 34: /* unary_operator: TILDE */ -#line 469 "src/parser.y" +#line 495 "src/parser.y" { symbol_info* new_symbol=new symbol_info(); (yyval.symbol_info)=new_symbol; (yyval.symbol_info)->name="tilde"; (yyval.symbol_info)->code="~"; } -#line 2397 "parser.tab.c" +#line 2444 "parser.tab.c" break; case 35: /* unary_operator: EXCLAMATION */ -#line 476 "src/parser.y" +#line 502 "src/parser.y" { symbol_info* new_symbol=new symbol_info(); (yyval.symbol_info)=new_symbol; (yyval.symbol_info)->name="exclamation"; (yyval.symbol_info)->code="!"; } -#line 2408 "parser.tab.c" +#line 2455 "parser.tab.c" break; case 36: /* cast_expression: unary_expression */ -#line 486 "src/parser.y" +#line 512 "src/parser.y" { + (yyval.symbol_info)=(yyvsp[0].symbol_info); } -#line 2416 "parser.tab.c" +#line 2464 "parser.tab.c" break; case 37: /* cast_expression: LPARENTHESES type_name RPARENTHESES cast_expression */ -#line 490 "src/parser.y" +#line 517 "src/parser.y" { (yyval.symbol_info) = (yyvsp[0].symbol_info); (yyval.symbol_info)->type = (yyvsp[-2].symbol_info)->type; } -#line 2425 "parser.tab.c" +#line 2473 "parser.tab.c" break; case 38: /* multiplicative_expression: cast_expression */ -#line 497 "src/parser.y" +#line 524 "src/parser.y" {(yyval.symbol_info)=(yyvsp[0].symbol_info);} -#line 2431 "parser.tab.c" +#line 2479 "parser.tab.c" break; case 39: /* multiplicative_expression: multiplicative_expression STAR cast_expression */ -#line 499 "src/parser.y" +#line 526 "src/parser.y" { (yyval.symbol_info) = (yyvsp[-2].symbol_info); (yyval.symbol_info)->type = priority_to_type[max(type_priority[(yyvsp[-2].symbol_info)->type],type_priority[(yyvsp[0].symbol_info)->type])]; @@ -2439,11 +2487,11 @@ yyparse (void) (yyval.symbol_info)->code=(yyvsp[-2].symbol_info)->code + "\n" + (yyvsp[0].symbol_info)->code +"\n" + var.first+":= "+(yyvsp[-2].symbol_info)->place.first+"*"+(yyvsp[0].symbol_info)->place.first; (yyval.symbol_info)->place=var; } -#line 2443 "parser.tab.c" +#line 2491 "parser.tab.c" break; case 40: /* multiplicative_expression: multiplicative_expression DIVIDE cast_expression */ -#line 507 "src/parser.y" +#line 534 "src/parser.y" { (yyval.symbol_info) = (yyvsp[-2].symbol_info); (yyval.symbol_info)->type = priority_to_type[max(type_priority[(yyvsp[-2].symbol_info)->type],type_priority[(yyvsp[0].symbol_info)->type])]; @@ -2451,11 +2499,11 @@ yyparse (void) (yyval.symbol_info)->code=(yyvsp[-2].symbol_info)->code + "\n" + (yyvsp[0].symbol_info)->code +"\n" + var.first+":= "+(yyvsp[-2].symbol_info)->place.first+"/"+(yyvsp[0].symbol_info)->place.first; (yyval.symbol_info)->place=var; } -#line 2455 "parser.tab.c" +#line 2503 "parser.tab.c" break; case 41: /* multiplicative_expression: multiplicative_expression MODULO cast_expression */ -#line 515 "src/parser.y" +#line 542 "src/parser.y" { (yyval.symbol_info) = (yyvsp[-2].symbol_info); (yyval.symbol_info)->type = priority_to_type[max(type_priority[(yyvsp[-2].symbol_info)->type],type_priority[(yyvsp[0].symbol_info)->type])]; @@ -2466,29 +2514,34 @@ yyparse (void) (yyval.symbol_info)->code=(yyvsp[-2].symbol_info)->code + "\n" + (yyvsp[0].symbol_info)->code +"\n" + var.first+":= "+(yyvsp[-2].symbol_info)->place.first+"%"+(yyvsp[0].symbol_info)->place.first; (yyval.symbol_info)->place=var; } -#line 2470 "parser.tab.c" +#line 2518 "parser.tab.c" break; case 42: /* additive_expression: multiplicative_expression */ -#line 528 "src/parser.y" +#line 555 "src/parser.y" {(yyval.symbol_info)=(yyvsp[0].symbol_info);} -#line 2476 "parser.tab.c" +#line 2524 "parser.tab.c" break; case 43: /* additive_expression: additive_expression PLUS multiplicative_expression */ -#line 530 "src/parser.y" +#line 557 "src/parser.y" { + // cerr<<$1->type<type<type = priority_to_type[max(type_priority[(yyvsp[-2].symbol_info)->type],type_priority[(yyvsp[0].symbol_info)->type])]; + if(count_star((yyvsp[-2].symbol_info)->type)>count_star((yyvsp[0].symbol_info)->type)) (yyval.symbol_info)->type=(yyvsp[-2].symbol_info)->type; + else if(count_star((yyvsp[-2].symbol_info)->type)type)) (yyval.symbol_info)->type=(yyvsp[0].symbol_info)->type; + else (yyval.symbol_info)->type = priority_to_type[max(type_priority[(yyvsp[-2].symbol_info)->type],type_priority[(yyvsp[0].symbol_info)->type])]; + // cerr<<$$->type<type,curr_scope); (yyval.symbol_info)->code=(yyvsp[-2].symbol_info)->code + "\n" + (yyvsp[0].symbol_info)->code +"\n" + var.first+":= "+(yyvsp[-2].symbol_info)->place.first+"+"+(yyvsp[0].symbol_info)->place.first; (yyval.symbol_info)->place=var; } -#line 2488 "parser.tab.c" +#line 2541 "parser.tab.c" break; case 44: /* additive_expression: additive_expression MINUS multiplicative_expression */ -#line 538 "src/parser.y" +#line 570 "src/parser.y" { (yyval.symbol_info) = (yyvsp[-2].symbol_info); (yyval.symbol_info)->type = priority_to_type[max(type_priority[(yyvsp[-2].symbol_info)->type],type_priority[(yyvsp[0].symbol_info)->type])]; @@ -2496,17 +2549,17 @@ yyparse (void) (yyval.symbol_info)->code=(yyvsp[-2].symbol_info)->code + "\n" + (yyvsp[0].symbol_info)->code +"\n" + var.first+":= "+(yyvsp[-2].symbol_info)->place.first+"-"+(yyvsp[0].symbol_info)->place.first; (yyval.symbol_info)->place=var; } -#line 2500 "parser.tab.c" +#line 2553 "parser.tab.c" break; case 45: /* shift_expression: additive_expression */ -#line 548 "src/parser.y" +#line 580 "src/parser.y" {(yyval.symbol_info)=(yyvsp[0].symbol_info);} -#line 2506 "parser.tab.c" +#line 2559 "parser.tab.c" break; case 46: /* shift_expression: shift_expression LEFT_SHIFT additive_expression */ -#line 550 "src/parser.y" +#line 582 "src/parser.y" { (yyval.symbol_info) = (yyvsp[-2].symbol_info); (yyval.symbol_info)->type = priority_to_type[max(type_priority[(yyvsp[-2].symbol_info)->type],type_priority[(yyvsp[0].symbol_info)->type])]; @@ -2517,11 +2570,11 @@ yyparse (void) (yyval.symbol_info)->code=(yyvsp[-2].symbol_info)->code + "\n" + (yyvsp[0].symbol_info)->code +"\n" + var.first+":= "+(yyvsp[-2].symbol_info)->place.first+"<<"+(yyvsp[0].symbol_info)->place.first; (yyval.symbol_info)->place=var; } -#line 2521 "parser.tab.c" +#line 2574 "parser.tab.c" break; case 47: /* shift_expression: shift_expression RIGHT_SHIFT additive_expression */ -#line 561 "src/parser.y" +#line 593 "src/parser.y" { (yyval.symbol_info) = (yyvsp[-2].symbol_info); (yyval.symbol_info)->type = priority_to_type[max(type_priority[(yyvsp[-2].symbol_info)->type],type_priority[(yyvsp[0].symbol_info)->type])]; @@ -2532,17 +2585,17 @@ yyparse (void) (yyval.symbol_info)->code=(yyvsp[-2].symbol_info)->code + "\n" + (yyvsp[0].symbol_info)->code +"\n" + var.first+":= "+(yyvsp[-2].symbol_info)->place.first+">>"+(yyvsp[0].symbol_info)->place.first; (yyval.symbol_info)->place=var; } -#line 2536 "parser.tab.c" +#line 2589 "parser.tab.c" break; case 48: /* relational_expression: shift_expression */ -#line 574 "src/parser.y" +#line 606 "src/parser.y" {(yyval.symbol_info)=(yyvsp[0].symbol_info);} -#line 2542 "parser.tab.c" +#line 2595 "parser.tab.c" break; case 49: /* relational_expression: relational_expression LESS_THAN shift_expression */ -#line 576 "src/parser.y" +#line 608 "src/parser.y" { (yyval.symbol_info) = (yyvsp[-2].symbol_info); (yyval.symbol_info)->type = priority_to_type[max(type_priority[(yyvsp[-2].symbol_info)->type],type_priority[(yyvsp[0].symbol_info)->type])]; @@ -2550,11 +2603,11 @@ yyparse (void) (yyval.symbol_info)->code=(yyvsp[-2].symbol_info)->code + "\n" + (yyvsp[0].symbol_info)->code +"\n" + var.first+":= "+(yyvsp[-2].symbol_info)->place.first+"<"+(yyvsp[0].symbol_info)->place.first; (yyval.symbol_info)->place=var; } -#line 2554 "parser.tab.c" +#line 2607 "parser.tab.c" break; case 50: /* relational_expression: relational_expression GREATER_THAN shift_expression */ -#line 584 "src/parser.y" +#line 616 "src/parser.y" { (yyval.symbol_info) = (yyvsp[-2].symbol_info); (yyval.symbol_info)->type = priority_to_type[max(type_priority[(yyvsp[-2].symbol_info)->type],type_priority[(yyvsp[0].symbol_info)->type])]; @@ -2562,11 +2615,11 @@ yyparse (void) (yyval.symbol_info)->code=(yyvsp[-2].symbol_info)->code + "\n" + (yyvsp[0].symbol_info)->code +"\n" + var.first+":= "+(yyvsp[-2].symbol_info)->place.first+">"+(yyvsp[0].symbol_info)->place.first; (yyval.symbol_info)->place=var; } -#line 2566 "parser.tab.c" +#line 2619 "parser.tab.c" break; case 51: /* relational_expression: relational_expression LESS_EQUALS shift_expression */ -#line 592 "src/parser.y" +#line 624 "src/parser.y" { (yyval.symbol_info) = (yyvsp[-2].symbol_info); (yyval.symbol_info)->type = priority_to_type[max(type_priority[(yyvsp[-2].symbol_info)->type],type_priority[(yyvsp[0].symbol_info)->type])]; @@ -2575,11 +2628,11 @@ yyparse (void) (yyval.symbol_info)->place=var; } -#line 2579 "parser.tab.c" +#line 2632 "parser.tab.c" break; case 52: /* relational_expression: relational_expression GREATER_EQUALS shift_expression */ -#line 601 "src/parser.y" +#line 633 "src/parser.y" { (yyval.symbol_info) = (yyvsp[-2].symbol_info); (yyval.symbol_info)->type = priority_to_type[max(type_priority[(yyvsp[-2].symbol_info)->type],type_priority[(yyvsp[0].symbol_info)->type])]; @@ -2587,17 +2640,17 @@ yyparse (void) (yyval.symbol_info)->code=(yyvsp[-2].symbol_info)->code + "\n" + (yyvsp[0].symbol_info)->code +"\n" + var.first+":= "+(yyvsp[-2].symbol_info)->place.first+">="+(yyvsp[0].symbol_info)->place.first; (yyval.symbol_info)->place=var; } -#line 2591 "parser.tab.c" +#line 2644 "parser.tab.c" break; case 53: /* equality_expression: relational_expression */ -#line 611 "src/parser.y" +#line 643 "src/parser.y" {(yyval.symbol_info)=(yyvsp[0].symbol_info);} -#line 2597 "parser.tab.c" +#line 2650 "parser.tab.c" break; case 54: /* equality_expression: equality_expression REL_EQUALS relational_expression */ -#line 613 "src/parser.y" +#line 645 "src/parser.y" { (yyval.symbol_info) = (yyvsp[-2].symbol_info); (yyval.symbol_info)->type = priority_to_type[max(type_priority[(yyvsp[-2].symbol_info)->type],type_priority[(yyvsp[0].symbol_info)->type])]; @@ -2605,11 +2658,11 @@ yyparse (void) (yyval.symbol_info)->code=(yyvsp[-2].symbol_info)->code + "\n" + (yyvsp[0].symbol_info)->code +"\n" + var.first+":= "+(yyvsp[-2].symbol_info)->place.first+"=="+(yyvsp[0].symbol_info)->place.first; (yyval.symbol_info)->place=var; } -#line 2609 "parser.tab.c" +#line 2662 "parser.tab.c" break; case 55: /* equality_expression: equality_expression REL_NOT_EQ relational_expression */ -#line 621 "src/parser.y" +#line 653 "src/parser.y" { (yyval.symbol_info) = (yyvsp[-2].symbol_info); (yyval.symbol_info)->type = priority_to_type[max(type_priority[(yyvsp[-2].symbol_info)->type],type_priority[(yyvsp[0].symbol_info)->type])]; @@ -2617,17 +2670,17 @@ yyparse (void) (yyval.symbol_info)->code=(yyvsp[-2].symbol_info)->code + "\n" + (yyvsp[0].symbol_info)->code +"\n" + var.first+":= "+(yyvsp[-2].symbol_info)->place.first+"!="+(yyvsp[0].symbol_info)->place.first; (yyval.symbol_info)->place=var; } -#line 2621 "parser.tab.c" +#line 2674 "parser.tab.c" break; case 56: /* and_expression: equality_expression */ -#line 631 "src/parser.y" +#line 663 "src/parser.y" {(yyval.symbol_info)=(yyvsp[0].symbol_info);} -#line 2627 "parser.tab.c" +#line 2680 "parser.tab.c" break; case 57: /* and_expression: and_expression AMPERSAND equality_expression */ -#line 633 "src/parser.y" +#line 665 "src/parser.y" { (yyval.symbol_info) = (yyvsp[-2].symbol_info); (yyval.symbol_info)->type = priority_to_type[max(type_priority[(yyvsp[-2].symbol_info)->type],type_priority[(yyvsp[0].symbol_info)->type])]; @@ -2635,17 +2688,17 @@ yyparse (void) error_list.push_back("Line "+to_string(yylineno)+" : And operator can only be used with int type"); } } -#line 2639 "parser.tab.c" +#line 2692 "parser.tab.c" break; case 58: /* exclusive_or_expression: and_expression */ -#line 643 "src/parser.y" +#line 675 "src/parser.y" {(yyval.symbol_info)=(yyvsp[0].symbol_info);} -#line 2645 "parser.tab.c" +#line 2698 "parser.tab.c" break; case 59: /* exclusive_or_expression: exclusive_or_expression XOR and_expression */ -#line 645 "src/parser.y" +#line 677 "src/parser.y" { (yyval.symbol_info) = (yyvsp[-2].symbol_info); (yyval.symbol_info)->type = priority_to_type[max(type_priority[(yyvsp[-2].symbol_info)->type],type_priority[(yyvsp[0].symbol_info)->type])]; @@ -2656,17 +2709,17 @@ yyparse (void) (yyval.symbol_info)->code=(yyvsp[-2].symbol_info)->code + "\n" + (yyvsp[0].symbol_info)->code +"\n" + var.first+":= "+(yyvsp[-2].symbol_info)->place.first+"^"+(yyvsp[0].symbol_info)->place.first; (yyval.symbol_info)->place=var; } -#line 2660 "parser.tab.c" +#line 2713 "parser.tab.c" break; case 60: /* inclusive_or_expression: exclusive_or_expression */ -#line 658 "src/parser.y" +#line 690 "src/parser.y" {(yyval.symbol_info)=(yyvsp[0].symbol_info);} -#line 2666 "parser.tab.c" +#line 2719 "parser.tab.c" break; case 61: /* inclusive_or_expression: inclusive_or_expression OR exclusive_or_expression */ -#line 660 "src/parser.y" +#line 692 "src/parser.y" { (yyval.symbol_info) = (yyvsp[-2].symbol_info); (yyval.symbol_info)->type = priority_to_type[max(type_priority[(yyvsp[-2].symbol_info)->type],type_priority[(yyvsp[0].symbol_info)->type])]; @@ -2677,17 +2730,17 @@ yyparse (void) (yyval.symbol_info)->code=(yyvsp[-2].symbol_info)->code + "\n" + (yyvsp[0].symbol_info)->code +"\n" + var.first+":= "+(yyvsp[-2].symbol_info)->place.first+"|"+(yyvsp[0].symbol_info)->place.first; (yyval.symbol_info)->place=var; } -#line 2681 "parser.tab.c" +#line 2734 "parser.tab.c" break; case 62: /* logical_and_expression: inclusive_or_expression */ -#line 673 "src/parser.y" +#line 705 "src/parser.y" {(yyval.symbol_info)=(yyvsp[0].symbol_info);} -#line 2687 "parser.tab.c" +#line 2740 "parser.tab.c" break; case 63: /* logical_and_expression: logical_and_expression REL_AND inclusive_or_expression */ -#line 675 "src/parser.y" +#line 707 "src/parser.y" { (yyval.symbol_info) = (yyvsp[-2].symbol_info); (yyval.symbol_info)->type = priority_to_type[max(type_priority[(yyvsp[-2].symbol_info)->type],type_priority[(yyvsp[0].symbol_info)->type])]; @@ -2696,17 +2749,17 @@ yyparse (void) } } -#line 2700 "parser.tab.c" +#line 2753 "parser.tab.c" break; case 64: /* logical_or_expression: logical_and_expression */ -#line 686 "src/parser.y" +#line 718 "src/parser.y" {(yyval.symbol_info)=(yyvsp[0].symbol_info);} -#line 2706 "parser.tab.c" +#line 2759 "parser.tab.c" break; case 65: /* logical_or_expression: logical_or_expression REL_OR logical_and_expression */ -#line 688 "src/parser.y" +#line 720 "src/parser.y" { (yyval.symbol_info) = (yyvsp[-2].symbol_info); (yyval.symbol_info)->type = priority_to_type[max(type_priority[(yyvsp[-2].symbol_info)->type],type_priority[(yyvsp[0].symbol_info)->type])]; @@ -2714,23 +2767,28 @@ yyparse (void) error_list.push_back("Line "+to_string(yylineno)+" : OR operator can only be used with int type"); } } -#line 2718 "parser.tab.c" +#line 2771 "parser.tab.c" break; case 66: /* conditional_expression: logical_or_expression */ -#line 698 "src/parser.y" +#line 730 "src/parser.y" {(yyval.symbol_info)=(yyvsp[0].symbol_info);} -#line 2724 "parser.tab.c" +#line 2777 "parser.tab.c" break; case 68: /* assignment_expression: conditional_expression */ -#line 703 "src/parser.y" - {(yyval.symbol_info)=(yyvsp[0].symbol_info);} -#line 2730 "parser.tab.c" +#line 736 "src/parser.y" + { + + (yyval.symbol_info)=(yyvsp[0].symbol_info); + // cerr<<"hereeeeee "<<$$->name<type<name, curr_scope); @@ -2768,19 +2826,23 @@ yyparse (void) error_list.push_back("Line "+to_string(yylineno)+" : char* is not modifiable"); } if(min(type_priority[(yyvsp[-2].symbol_info)->type],type_priority[(yyvsp[0].symbol_info)->type])==0 && (yyvsp[-2].symbol_info)->type!=(yyvsp[0].symbol_info)->type){ - error_list.push_back("Line "+to_string(yylineno)+" : Type mismatch in assignment"); + if((yyvsp[0].symbol_info)->type!="int" && (yyvsp[-2].symbol_info)->type!="int") error_list.push_back("Line "+to_string(yylineno)+" : Type mismatch in assignment"); } - if(type_priority[(yyvsp[-2].symbol_info)->type]type]){ - error_list.push_back("Line "+to_string(yylineno)+" : Type mismatch in assignment"); + else if(type_priority[(yyvsp[-2].symbol_info)->type]type]){ + error_list.push_back("Line "+to_string(yylineno)+" : Type mismatch in assignment3"); } string third_code=(yyvsp[0].symbol_info)->code; string first_code=(yyvsp[-2].symbol_info)->code; if(min(type_priority[(yyvsp[-2].symbol_info)->type],type_priority[find_symbol->type])>0) find_symbol->type=priority_to_type[max(type_priority[find_symbol->type],type_priority[(yyvsp[0].symbol_info)->type])]; - + find_symbol->name=(yyvsp[-2].symbol_info)->name; find_symbol->place=(yyvsp[-2].symbol_info)->place; find_symbol->code=(yyvsp[-2].symbol_info)->code + "\n" + (yyvsp[0].symbol_info)->code + "\n" + (yyvsp[-2].symbol_info)->place.first + ":= " + (yyvsp[0].symbol_info)->place.first; - + find_symbol->pointer_depth=max((yyvsp[-2].symbol_info)->pointer_depth, (yyvsp[0].symbol_info)->pointer_depth); + // cerr<<$1->name<<" |||| "<<$1->pointer_depth<name<<" |||| "<<$3->pointer_depth<name<pointer_depth<place.first[0]!='t' && (yyvsp[0].symbol_info)->place.first[0]!='&' && (yyvsp[0].symbol_info)->place.first[0]!='*' && (yyvsp[0].symbol_info)->place.first[0]!='+' && (yyvsp[0].symbol_info)->place.first[0]!='-' && (yyvsp[0].symbol_info)->place.first[0]!='~' && (yyvsp[0].symbol_info)->place.first[0]!='!') { @@ -2844,99 +2906,99 @@ yyparse (void) error_list.push_back("Line "+to_string(yylineno)+" : Undeclared symbol "+(yyvsp[-2].symbol_info)->name); } } -#line 2848 "parser.tab.c" +#line 2910 "parser.tab.c" break; case 70: /* assignment_operator: EQUALS */ -#line 821 "src/parser.y" +#line 863 "src/parser.y" {(yyval.symbol_info)=new symbol_info("","equals",nullptr,0); (yyval.symbol_info)->code="=";} -#line 2854 "parser.tab.c" +#line 2916 "parser.tab.c" break; case 71: /* assignment_operator: ASSIGN_STAR */ -#line 822 "src/parser.y" +#line 864 "src/parser.y" {(yyval.symbol_info)=new symbol_info("","assign_star",nullptr,0); (yyval.symbol_info)->code="*=";} -#line 2860 "parser.tab.c" +#line 2922 "parser.tab.c" break; case 72: /* assignment_operator: ASSIGN_DIV */ -#line 823 "src/parser.y" +#line 865 "src/parser.y" {(yyval.symbol_info)=new symbol_info("","assign_div",nullptr,0); (yyval.symbol_info)->code="/=";} -#line 2866 "parser.tab.c" +#line 2928 "parser.tab.c" break; case 73: /* assignment_operator: ASSIGN_MOD */ -#line 824 "src/parser.y" +#line 866 "src/parser.y" {(yyval.symbol_info)=new symbol_info("","assign_mod",nullptr,0); (yyval.symbol_info)->code="%=";} -#line 2872 "parser.tab.c" +#line 2934 "parser.tab.c" break; case 74: /* assignment_operator: ASSIGN_PLUS */ -#line 825 "src/parser.y" +#line 867 "src/parser.y" {(yyval.symbol_info)=new symbol_info("","assign_plus",nullptr,0); (yyval.symbol_info)->code="+=";} -#line 2878 "parser.tab.c" +#line 2940 "parser.tab.c" break; case 75: /* assignment_operator: ASSIGN_MINUS */ -#line 826 "src/parser.y" +#line 868 "src/parser.y" {(yyval.symbol_info)=new symbol_info("","assign_minus",nullptr,0); (yyval.symbol_info)->code="-=";} -#line 2884 "parser.tab.c" +#line 2946 "parser.tab.c" break; case 76: /* assignment_operator: LEFT_SHIFT_EQ */ -#line 827 "src/parser.y" +#line 869 "src/parser.y" {(yyval.symbol_info)=new symbol_info("","left_shift_eq",nullptr,0); (yyval.symbol_info)->code="<<=";} -#line 2890 "parser.tab.c" +#line 2952 "parser.tab.c" break; case 77: /* assignment_operator: RIGHT_SHIFT_EQ */ -#line 828 "src/parser.y" +#line 870 "src/parser.y" {(yyval.symbol_info)=new symbol_info("","right_shift_eq",nullptr,0); (yyval.symbol_info)->code=">>=";} -#line 2896 "parser.tab.c" +#line 2958 "parser.tab.c" break; case 78: /* assignment_operator: ASSIGN_AND */ -#line 829 "src/parser.y" +#line 871 "src/parser.y" {(yyval.symbol_info)=new symbol_info("","assign_and",nullptr,0); (yyval.symbol_info)->code="&=";} -#line 2902 "parser.tab.c" +#line 2964 "parser.tab.c" break; case 79: /* assignment_operator: ASSIGN_XOR */ -#line 830 "src/parser.y" +#line 872 "src/parser.y" {(yyval.symbol_info)=new symbol_info("","assign_xor",nullptr,0); (yyval.symbol_info)->code="^=";} -#line 2908 "parser.tab.c" +#line 2970 "parser.tab.c" break; case 80: /* assignment_operator: ASSIGN_OR */ -#line 831 "src/parser.y" +#line 873 "src/parser.y" {(yyval.symbol_info)=new symbol_info("","assign_or",nullptr,0); (yyval.symbol_info)->code="|=";} -#line 2914 "parser.tab.c" +#line 2976 "parser.tab.c" break; case 81: /* expression: assignment_expression */ -#line 836 "src/parser.y" +#line 878 "src/parser.y" { (yyval.symbol_info)=(yyvsp[0].symbol_info); } -#line 2922 "parser.tab.c" +#line 2984 "parser.tab.c" break; case 82: /* expression: expression COMMA assignment_expression */ -#line 840 "src/parser.y" +#line 882 "src/parser.y" { (yyval.symbol_info)->code=(yyvsp[-2].symbol_info)->code + "\n" + (yyvsp[0].symbol_info)->code; } -#line 2930 "parser.tab.c" +#line 2992 "parser.tab.c" break; case 83: /* constant_expression: conditional_expression */ -#line 846 "src/parser.y" +#line 888 "src/parser.y" {(yyval.symbol_info)=(yyvsp[0].symbol_info);} -#line 2936 "parser.tab.c" +#line 2998 "parser.tab.c" break; case 85: /* declaration: declaration_specifiers init_declarator_list SEMICOLON */ -#line 852 "src/parser.y" +#line 894 "src/parser.y" { if(std::string((yyvsp[-2].str)).substr(0, 7) == "typedef"){ string new_type=parsing_stack.top(); @@ -2958,7 +3020,7 @@ yyparse (void) parsing_stack.pop(); pointer_info.pop(); if (curr_scope->symbol_map[top_symbol]->type!= ""){ - if(depth!=count_star(curr_scope->symbol_map[top_symbol]->type)){ + if(depth!=count_star(curr_scope->symbol_map[top_symbol]->type) && !curr_scope->symbol_map[top_symbol]->is_array){ error_list.push_back("Line "+to_string(yylineno)+" : Pointer depth mismatch"); flag = 1; } @@ -2971,31 +3033,38 @@ yyparse (void) curr_scope->symbol_map[top_symbol]->name = top_symbol; if(type_priority[(yyvsp[-2].str)]>0 && type_priority[curr_scope->symbol_map[top_symbol]->type]>0) curr_scope->symbol_map[top_symbol]->type = priority_to_type[max(type_priority[(yyvsp[-2].str)], type_priority[curr_scope->symbol_map[top_symbol]->type])]; - + if(std::string((yyvsp[-2].str)).substr(0,6) == "static"){ + curr_scope->symbol_map[top_symbol]->is_static = true; + } // debug("declaration specifiers121 ", $2->code); - - code=(yyvsp[-1].symbol_info)->code; + code+=(yyvsp[-1].symbol_info)->code; } else { + curr_scope->symbol_map[top_symbol]->type = (yyvsp[-2].str); for(int i=0;isymbol_map[top_symbol]->type+="*"; } + if(curr_scope->symbol_map[top_symbol]->is_array) curr_scope->symbol_map[top_symbol]->type+="*"; curr_scope->symbol_map[top_symbol]->name = top_symbol; curr_scope->symbol_map[top_symbol]->pointer_depth = depth; - if((curr_scope->symbol_map[top_symbol]->type).substr(0,6)=="struct") { + // cerr<<"gggggghjjj "<<$1<symbol_map[top_symbol]->type).substr(7); + if(struct_name.back()=='*') struct_name.pop_back(); symbol_info* find_struct=lookup_symbol_global(struct_name, curr_scope); int size=0; + for(int i=0;iparam_list.size();i++){ size+=get_size(find_struct->param_types[i]); } //debug("Struct size: ",to_string(size)); + code=code+top_symbol+":= alloc " +to_string(size)+"\n"; + } else if((curr_scope->symbol_map[top_symbol]->type).substr(0,5)=="union") @@ -3011,23 +3080,39 @@ yyparse (void) } + if(curr_scope->symbol_map[top_symbol]->is_array){ + // debug("in the arr",curr_scope->symbol_map[top_symbol]->type.substr(0,3)); + if(curr_scope->symbol_map[top_symbol]->type.substr(0,3)=="int"){ + code=code+top_symbol+":= alloc " +to_string(4*curr_scope->symbol_map[top_symbol]->array_length)+"\n"; + } + if(curr_scope->symbol_map[top_symbol]->type.substr(0,5)=="float"){ + code=code+top_symbol+":= alloc " +to_string(4*curr_scope->symbol_map[top_symbol]->array_length)+"\n"; + } + if(curr_scope->symbol_map[top_symbol]->type.substr(0,4)=="char"){ + code=code+top_symbol+":= alloc " +to_string(2*curr_scope->symbol_map[top_symbol]->array_length)+"\n"; + } + // debug("in the arr",code); + + } + symbol_info* new_symbol = new symbol_info(); new_symbol = new symbol_info((yyvsp[-1].symbol_info)); (yyval.symbol_info)=new_symbol; - + } } // debug("declaration specifiers ", to_string(parsing_stack.size())); (yyval.symbol_info)->code=code; + // debug("in the arr11",$$->code); //debug("Declaration: ",curr_scope->symbol_map["p"]->code); } -#line 3027 "parser.tab.c" +#line 3112 "parser.tab.c" break; case 87: /* declaration_specifiers: storage_class_specifier declaration_specifiers */ -#line 944 "src/parser.y" +#line 1009 "src/parser.y" { // debug("storage class specifier ", $1); // debug("storage class specifier ", $2); @@ -3037,36 +3122,36 @@ yyparse (void) // debug("storage class specifier ", $$); } -#line 3041 "parser.tab.c" +#line 3126 "parser.tab.c" break; case 88: /* declaration_specifiers: type_specifier */ -#line 953 "src/parser.y" +#line 1018 "src/parser.y" {(yyval.str)=(yyvsp[0].str);} -#line 3047 "parser.tab.c" +#line 3132 "parser.tab.c" break; case 91: /* init_declarator_list: init_declarator */ -#line 959 "src/parser.y" +#line 1024 "src/parser.y" { (yyval.symbol_info) = (yyvsp[0].symbol_info); } -#line 3055 "parser.tab.c" +#line 3140 "parser.tab.c" break; case 92: /* init_declarator_list: init_declarator_list COMMA init_declarator */ -#line 962 "src/parser.y" +#line 1027 "src/parser.y" { (yyval.symbol_info)=(yyvsp[0].symbol_info); (yyval.symbol_info)->code = (yyvsp[-2].symbol_info)->code + "\n" + (yyvsp[0].symbol_info)->code; } -#line 3064 "parser.tab.c" +#line 3149 "parser.tab.c" break; case 93: /* init_declarator: declarator */ -#line 969 "src/parser.y" +#line 1034 "src/parser.y" { - if(lookup_symbol_global((yyvsp[0].symbol_info)->name, curr_scope)!=nullptr){ + if(lookup_symbol_local((yyvsp[0].symbol_info)->name, curr_scope)!=nullptr){ error_list.push_back("Line "+to_string(yylineno)+" : Redeclaration error "+(yyvsp[0].symbol_info)->name); } symbol_info* new_symbol = new symbol_info(); @@ -3074,14 +3159,15 @@ yyparse (void) curr_scope->symbol_map[(yyvsp[0].symbol_info)->name]=new_symbol; curr_scope->symbol_map[(yyvsp[0].symbol_info)->name]->name=(yyvsp[0].symbol_info)->name; if((yyvsp[0].symbol_info)->is_array==true){ - curr_scope->symbol_map[(yyvsp[0].symbol_info)->name]->is_array=true; + curr_scope->symbol_map[(yyvsp[0].symbol_info)->name]->is_array=true; curr_scope->symbol_map[(yyvsp[0].symbol_info)->name]->array_length=(yyvsp[0].symbol_info)->array_length; if((yyvsp[0].symbol_info)->type=="int" || (yyvsp[0].symbol_info)->type=="float"){ + // cerr<<"gggg"<<$1->type<name+":= alloc " +to_string(4*(yyvsp[0].symbol_info)->array_length); (yyval.symbol_info)->code=code; } else if((yyvsp[0].symbol_info)->type=="char"){ - string code=(yyvsp[0].symbol_info)->name+":= alloc " +to_string(2*(yyvsp[0].symbol_info)->array_length); + string code=(yyvsp[0].symbol_info)->name+":= alloc " +to_string(2*(yyvsp[0].symbol_info)->array_length); (yyval.symbol_info)->code=code; } } @@ -3093,11 +3179,11 @@ yyparse (void) parsing_stack.push((yyvsp[0].symbol_info)->name.c_str()); pointer_info.push((yyvsp[0].symbol_info)->pointer_depth); } -#line 3097 "parser.tab.c" +#line 3183 "parser.tab.c" break; case 94: /* init_declarator: declarator EQUALS initializer */ -#line 997 "src/parser.y" +#line 1063 "src/parser.y" { if(lookup_symbol_local((yyvsp[-2].symbol_info)->name, curr_scope)!=nullptr){ error_list.push_back("Line "+to_string(yylineno)+" : Redeclaration error "+(yyvsp[-2].symbol_info)->name); @@ -3106,7 +3192,6 @@ yyparse (void) curr_scope->symbol_map[(yyvsp[-2].symbol_info)->name]=(yyvsp[0].symbol_info); parsing_stack.push((yyvsp[-2].symbol_info)->name.c_str()); pointer_info.push((yyvsp[-2].symbol_info)->pointer_depth); - if((yyvsp[-2].symbol_info)->is_array){ if((yyvsp[0].symbol_info)->int_array.size() > (yyvsp[-2].symbol_info)->array_length){ error_list.push_back("Line "+to_string(yylineno)+" : Array size mismatch "+(yyvsp[-2].symbol_info)->name); @@ -3114,21 +3199,23 @@ yyparse (void) else{ (yyvsp[-2].symbol_info)->int_array = (yyvsp[0].symbol_info)->int_array; (yyvsp[-2].symbol_info)->type = (yyvsp[0].symbol_info)->type; + (yyvsp[-2].symbol_info)->type=(yyvsp[-2].symbol_info)->type+"*"; curr_scope->symbol_map[(yyvsp[-2].symbol_info)->name]->is_array=true; + curr_scope->symbol_map[(yyvsp[-2].symbol_info)->name]->type=(yyvsp[-2].symbol_info)->type; string code=(yyvsp[-2].symbol_info)->name+":= alloc "; - if((yyvsp[-2].symbol_info)->type=="int" || (yyvsp[-2].symbol_info)->type=="float"){ + if((yyvsp[-2].symbol_info)->type=="int*" || (yyvsp[-2].symbol_info)->type=="float*"){ code=code+to_string(4*(yyvsp[-2].symbol_info)->array_length); } - else if((yyvsp[-2].symbol_info)->type=="char"){ + else if((yyvsp[-2].symbol_info)->type=="char*"){ code=code+to_string(2*(yyvsp[-2].symbol_info)->array_length); } for(int i=0;i<(yyvsp[-2].symbol_info)->array_length;i++){ qid temp=newtemp((yyvsp[-2].symbol_info)->type,curr_scope); code=code+"\n"+temp.first+":= "+to_string(i)+"*"; - if((yyvsp[-2].symbol_info)->type=="int") code=code+"4\n"+"*( "+(yyvsp[-2].symbol_info)->name+" + "+temp.first+" ):= "+to_string(*(int*)((yyvsp[-2].symbol_info)->int_array[i]->ptr)); - else if((yyvsp[-2].symbol_info)->type=="float") code=code+"4\n"+"*( "+(yyvsp[-2].symbol_info)->name+" + "+temp.first+" ):= "+to_string(*(float*)((yyvsp[-2].symbol_info)->int_array[i]->ptr)); - else if((yyvsp[-2].symbol_info)->type=="char") code=code+"2\n"+"*( "+(yyvsp[-2].symbol_info)->name+" + "+temp.first+" ):= "+char(*(char*)((yyvsp[-2].symbol_info)->int_array[i]->ptr)); - else if((yyvsp[-2].symbol_info)->type=="char*") code=code+"2\n"+"*( "+(yyvsp[-2].symbol_info)->name+" + "+temp.first+" ):= "+(yyvsp[-2].symbol_info)->int_array[i]->str_val; + if((yyvsp[-2].symbol_info)->type=="int*") code=code+"4\n"+"*( "+(yyvsp[-2].symbol_info)->name+" + "+temp.first+" ):= "+to_string(*(int*)((yyvsp[-2].symbol_info)->int_array[i]->ptr)); + else if((yyvsp[-2].symbol_info)->type=="float*") code=code+"4\n"+"*( "+(yyvsp[-2].symbol_info)->name+" + "+temp.first+" ):= "+to_string(*(float*)((yyvsp[-2].symbol_info)->int_array[i]->ptr)); + else if((yyvsp[-2].symbol_info)->type=="char*") code=code+"2\n"+"*( "+(yyvsp[-2].symbol_info)->name+" + "+temp.first+" ):= "+char(*(char*)((yyvsp[-2].symbol_info)->int_array[i]->ptr)); + else if((yyvsp[-2].symbol_info)->type=="char**") code=code+"2\n"+"*( "+(yyvsp[-2].symbol_info)->name+" + "+temp.first+" ):= "+(yyvsp[-2].symbol_info)->int_array[i]->str_val; } (yyval.symbol_info)->code=code; } @@ -3143,71 +3230,71 @@ yyparse (void) (yyval.symbol_info)->place=(yyvsp[-2].symbol_info)->place; } } -#line 3147 "parser.tab.c" +#line 3234 "parser.tab.c" break; case 100: /* type_specifier: VOID */ -#line 1053 "src/parser.y" +#line 1120 "src/parser.y" {(yyval.str)=strdup("void");} -#line 3153 "parser.tab.c" +#line 3240 "parser.tab.c" break; case 101: /* type_specifier: CHAR */ -#line 1054 "src/parser.y" +#line 1121 "src/parser.y" {(yyval.str)=strdup("char");} -#line 3159 "parser.tab.c" +#line 3246 "parser.tab.c" break; case 102: /* type_specifier: SHORT */ -#line 1055 "src/parser.y" +#line 1122 "src/parser.y" {(yyval.str)=strdup("short");} -#line 3165 "parser.tab.c" +#line 3252 "parser.tab.c" break; case 103: /* type_specifier: INT */ -#line 1056 "src/parser.y" +#line 1123 "src/parser.y" {(yyval.str)=strdup("int");} -#line 3171 "parser.tab.c" +#line 3258 "parser.tab.c" break; case 104: /* type_specifier: LONG */ -#line 1057 "src/parser.y" +#line 1124 "src/parser.y" {(yyval.str)=strdup("long");} -#line 3177 "parser.tab.c" +#line 3264 "parser.tab.c" break; case 105: /* type_specifier: FLOAT */ -#line 1058 "src/parser.y" +#line 1125 "src/parser.y" {(yyval.str)=strdup("float");} -#line 3183 "parser.tab.c" +#line 3270 "parser.tab.c" break; case 106: /* type_specifier: DOUBLE */ -#line 1059 "src/parser.y" +#line 1126 "src/parser.y" {(yyval.str)=strdup("double");} -#line 3189 "parser.tab.c" +#line 3276 "parser.tab.c" break; case 107: /* type_specifier: SIGNED */ -#line 1060 "src/parser.y" +#line 1127 "src/parser.y" {(yyval.str)=strdup("signed");} -#line 3195 "parser.tab.c" +#line 3282 "parser.tab.c" break; case 108: /* type_specifier: UNSIGNED */ -#line 1061 "src/parser.y" +#line 1128 "src/parser.y" {(yyval.str)=strdup("unsigned");} -#line 3201 "parser.tab.c" +#line 3288 "parser.tab.c" break; case 109: /* type_specifier: struct_or_union_specifier */ -#line 1062 "src/parser.y" +#line 1129 "src/parser.y" {(yyval.str)=(yyvsp[0].str);} -#line 3207 "parser.tab.c" +#line 3294 "parser.tab.c" break; case 111: /* type_specifier: ID */ -#line 1064 "src/parser.y" +#line 1131 "src/parser.y" { if(type_def_mapping.find((yyvsp[0].str)) != type_def_mapping.end()){ (yyval.str)=strdup(type_def_mapping[(yyvsp[0].str)].c_str()); @@ -3216,59 +3303,89 @@ yyparse (void) error_list.push_back("Line "+to_string(yylineno)+" : Typedef error "+(yyvsp[0].str)); } } -#line 3220 "parser.tab.c" +#line 3307 "parser.tab.c" break; - case 112: /* struct_or_union_specifier: struct_or_union ID LBRACE struct_declaration_list RBRACE */ -#line 1076 "src/parser.y" + case 112: /* $@1: %empty */ +#line 1143 "src/parser.y" { - symbol_info* new_symbol=new symbol_info(); - new_symbol->type = (yyvsp[-4].str); - new_symbol->param_list = (yyvsp[-1].symbol_info)->param_list; - new_symbol->param_types = (yyvsp[-1].symbol_info)->param_types; - curr_scope->symbol_map[(yyvsp[-3].str)]=new_symbol; + symbol_info* find_symbol=lookup_symbol_local((yyvsp[0].str),curr_scope); + if(find_symbol==nullptr){ + symbol_info* new_symbol=new symbol_info(); + curr_scope->symbol_map[(yyvsp[0].str)]=new_symbol; + curr_scope->symbol_map[(yyvsp[0].str)]->name = (yyvsp[0].str); + curr_scope->symbol_map[(yyvsp[0].str)]->type = (yyvsp[-1].str); + } + else{ + error_list.push_back("Line "+to_string(yylineno)+" : Struct redeclaration error "+(yyvsp[-1].str)); + } + } +#line 3324 "parser.tab.c" + break; + + case 113: /* $@2: %empty */ +#line 1156 "src/parser.y" + { + curr_scope = new scoped_symtab(curr_scope); + + } +#line 3333 "parser.tab.c" + break; + + case 114: /* struct_or_union_specifier: struct_or_union ID $@1 LBRACE $@2 struct_declaration_list RBRACE */ +#line 1161 "src/parser.y" + { + + + curr_scope->parent->symbol_map[(yyvsp[-5].str)]->param_list = (yyvsp[-1].symbol_info)->param_list; + curr_scope->parent->symbol_map[(yyvsp[-5].str)]->param_types = (yyvsp[-1].symbol_info)->param_types; + all_scopes.push_back(curr_scope); curr_scope = curr_scope->parent; + } -#line 3232 "parser.tab.c" +#line 3346 "parser.tab.c" break; - case 114: /* struct_or_union_specifier: struct_or_union ID */ -#line 1085 "src/parser.y" + case 116: /* struct_or_union_specifier: struct_or_union ID */ +#line 1171 "src/parser.y" { + symbol_info* find_symbol = lookup_symbol_global((yyvsp[0].str), curr_scope); if (find_symbol != nullptr) { if (find_symbol->type == "struct" || find_symbol->type == "union") { std::string temp = std::string((yyvsp[-1].str)) + " " + std::string((yyvsp[0].str)); (yyval.str) = strdup(temp.c_str()); + } else { error_list.push_back("Line "+to_string(yylineno)+" : Variable not of type struct or union"); } } else { error_list.push_back("Line "+to_string(yylineno)+" : Struct or Union not declared "+(yyvsp[0].str)); } + } -#line 3250 "parser.tab.c" +#line 3367 "parser.tab.c" break; - case 115: /* struct_or_union: STRUCT */ -#line 1101 "src/parser.y" + case 117: /* struct_or_union: STRUCT */ +#line 1190 "src/parser.y" {(yyval.str)=strdup("struct");} -#line 3256 "parser.tab.c" +#line 3373 "parser.tab.c" break; - case 116: /* struct_or_union: UNION */ -#line 1102 "src/parser.y" + case 118: /* struct_or_union: UNION */ +#line 1191 "src/parser.y" {(yyval.str)=strdup("union");} -#line 3262 "parser.tab.c" +#line 3379 "parser.tab.c" break; - case 117: /* struct_declaration_list: struct_declaration */ -#line 1106 "src/parser.y" + case 119: /* struct_declaration_list: struct_declaration */ +#line 1195 "src/parser.y" {(yyval.symbol_info)=(yyvsp[0].symbol_info);} -#line 3268 "parser.tab.c" +#line 3385 "parser.tab.c" break; - case 118: /* struct_declaration_list: struct_declaration_list struct_declaration */ -#line 1108 "src/parser.y" + case 120: /* struct_declaration_list: struct_declaration_list struct_declaration */ +#line 1197 "src/parser.y" { (yyval.symbol_info)=(yyvsp[-1].symbol_info); for(int i=0;i<(yyvsp[0].symbol_info)->param_list.size();i++){ @@ -3277,11 +3394,11 @@ yyparse (void) } } -#line 3281 "parser.tab.c" +#line 3398 "parser.tab.c" break; - case 119: /* struct_declaration: specifier_qualifier_list struct_declarator_list SEMICOLON */ -#line 1120 "src/parser.y" + case 121: /* struct_declaration: specifier_qualifier_list struct_declarator_list SEMICOLON */ +#line 1209 "src/parser.y" { (yyval.symbol_info)=(yyvsp[-1].symbol_info); for(auto it: (yyvsp[-1].symbol_info)->param_list) @@ -3297,63 +3414,64 @@ yyparse (void) } -#line 3301 "parser.tab.c" +#line 3418 "parser.tab.c" break; - case 122: /* struct_declarator_list: struct_declarator */ -#line 1144 "src/parser.y" + case 124: /* struct_declarator_list: struct_declarator */ +#line 1233 "src/parser.y" { (yyval.symbol_info)=(yyvsp[0].symbol_info); (yyval.symbol_info)->param_list.push_back((yyvsp[0].symbol_info)->name); } -#line 3310 "parser.tab.c" +#line 3427 "parser.tab.c" break; - case 123: /* struct_declarator_list: struct_declarator_list COMMA struct_declarator */ -#line 1149 "src/parser.y" + case 125: /* struct_declarator_list: struct_declarator_list COMMA struct_declarator */ +#line 1238 "src/parser.y" { (yyval.symbol_info)=(yyvsp[-2].symbol_info); (yyval.symbol_info)->param_list.push_back((yyvsp[0].symbol_info)->name); } -#line 3319 "parser.tab.c" +#line 3436 "parser.tab.c" break; - case 124: /* struct_declarator: declarator */ -#line 1156 "src/parser.y" + case 126: /* struct_declarator: declarator */ +#line 1245 "src/parser.y" {(yyval.symbol_info)=(yyvsp[0].symbol_info);} -#line 3325 "parser.tab.c" +#line 3442 "parser.tab.c" break; - case 136: /* declarator: pointer direct_declarator */ -#line 1183 "src/parser.y" + case 138: /* declarator: pointer direct_declarator */ +#line 1272 "src/parser.y" { (yyval.symbol_info)=(yyvsp[0].symbol_info); (yyval.symbol_info)->pointer_depth=(yyvsp[-1].symbol_info)->pointer_depth; } -#line 3334 "parser.tab.c" +#line 3451 "parser.tab.c" break; - case 137: /* declarator: direct_declarator */ -#line 1187 "src/parser.y" + case 139: /* declarator: direct_declarator */ +#line 1276 "src/parser.y" { (yyval.symbol_info)=(yyvsp[0].symbol_info); } -#line 3342 "parser.tab.c" +#line 3459 "parser.tab.c" break; - case 138: /* direct_declarator: ID */ -#line 1194 "src/parser.y" + case 140: /* direct_declarator: ID */ +#line 1283 "src/parser.y" { symbol_info* x=new symbol_info(); x->name = (yyvsp[0].str); x->place.first=(yyvsp[0].str); (yyval.symbol_info)=x; + } -#line 3353 "parser.tab.c" +#line 3471 "parser.tab.c" break; - case 140: /* direct_declarator: direct_declarator LBRACKET constant_expression RBRACKET */ -#line 1202 "src/parser.y" + case 142: /* direct_declarator: direct_declarator LBRACKET constant_expression RBRACKET */ +#line 1292 "src/parser.y" { (yyval.symbol_info)->is_array = true; if((yyvsp[-1].symbol_info)->type=="int"){ @@ -3364,19 +3482,19 @@ yyparse (void) (yyval.symbol_info)->array_length=100; } } -#line 3368 "parser.tab.c" +#line 3486 "parser.tab.c" break; - case 141: /* direct_declarator: direct_declarator LBRACKET RBRACKET */ -#line 1213 "src/parser.y" + case 143: /* direct_declarator: direct_declarator LBRACKET RBRACKET */ +#line 1303 "src/parser.y" { (yyval.symbol_info)->is_array = true, (yyval.symbol_info)->array_length = 100; } -#line 3376 "parser.tab.c" +#line 3494 "parser.tab.c" break; - case 142: /* direct_declarator: direct_declarator LPARENTHESES parameter_type_list RPARENTHESES */ -#line 1217 "src/parser.y" + case 144: /* direct_declarator: direct_declarator LPARENTHESES parameter_type_list RPARENTHESES */ +#line 1307 "src/parser.y" { symbol_info* new_symbol=new symbol_info(); new_symbol->type=(yyvsp[-3].symbol_info)->type; @@ -3389,11 +3507,11 @@ yyparse (void) (yyval.symbol_info)=new_symbol; } -#line 3393 "parser.tab.c" +#line 3511 "parser.tab.c" break; - case 144: /* direct_declarator: direct_declarator LPARENTHESES RPARENTHESES */ -#line 1231 "src/parser.y" + case 146: /* direct_declarator: direct_declarator LPARENTHESES RPARENTHESES */ +#line 1321 "src/parser.y" { symbol_info* new_symbol=new symbol_info(); new_symbol->type=(yyvsp[-2].symbol_info)->type; @@ -3405,23 +3523,23 @@ yyparse (void) curr_scope->symbol_map[(yyvsp[-2].symbol_info)->name]=new_symbol; (yyval.symbol_info)=new_symbol; } -#line 3409 "parser.tab.c" +#line 3527 "parser.tab.c" break; - case 145: /* pointer: STAR */ -#line 1245 "src/parser.y" + case 147: /* pointer: STAR */ +#line 1335 "src/parser.y" {(yyval.symbol_info)=new symbol_info(); (yyval.symbol_info)->pointer_depth=1;} -#line 3415 "parser.tab.c" +#line 3533 "parser.tab.c" break; - case 147: /* pointer: STAR pointer */ -#line 1247 "src/parser.y" + case 149: /* pointer: STAR pointer */ +#line 1337 "src/parser.y" {(yyval.symbol_info)=(yyvsp[0].symbol_info); (yyval.symbol_info)->pointer_depth++;} -#line 3421 "parser.tab.c" +#line 3539 "parser.tab.c" break; - case 151: /* parameter_type_list: parameter_list */ -#line 1259 "src/parser.y" + case 153: /* parameter_type_list: parameter_list */ +#line 1349 "src/parser.y" { symbol_info* new_symbol=new symbol_info(); (yyval.symbol_info)->parameter_no=(yyvsp[0].symbol_info)->parameter_no; @@ -3431,33 +3549,33 @@ yyparse (void) (yyval.symbol_info)=(yyvsp[0].symbol_info); } -#line 3435 "parser.tab.c" +#line 3553 "parser.tab.c" break; - case 153: /* parameter_list: parameter_declaration */ -#line 1273 "src/parser.y" + case 155: /* parameter_list: parameter_declaration */ +#line 1363 "src/parser.y" { (yyval.symbol_info)->is_param_list=true; (yyval.symbol_info)->parameter_no=1; (yyval.symbol_info)->param_types.push_back((yyvsp[0].symbol_info)->type); (yyval.symbol_info)->param_list.push_back((yyvsp[0].symbol_info)->name); } -#line 3446 "parser.tab.c" +#line 3564 "parser.tab.c" break; - case 154: /* parameter_list: parameter_list COMMA parameter_declaration */ -#line 1280 "src/parser.y" + case 156: /* parameter_list: parameter_list COMMA parameter_declaration */ +#line 1370 "src/parser.y" { (yyval.symbol_info)->is_param_list=true; (yyval.symbol_info)->parameter_no=(yyvsp[-2].symbol_info)->parameter_no+(yyvsp[0].symbol_info)->parameter_no; (yyval.symbol_info)->param_types.push_back((yyvsp[0].symbol_info)->type); (yyval.symbol_info)->param_list.push_back((yyvsp[0].symbol_info)->name); } -#line 3457 "parser.tab.c" +#line 3575 "parser.tab.c" break; - case 155: /* parameter_declaration: declaration_specifiers declarator */ -#line 1291 "src/parser.y" + case 157: /* parameter_declaration: declaration_specifiers declarator */ +#line 1381 "src/parser.y" { symbol_info* new_symbol=new symbol_info(); (yyval.symbol_info)=new_symbol; @@ -3465,60 +3583,61 @@ yyparse (void) (yyval.symbol_info)->name=(yyvsp[0].symbol_info)->name; (yyval.symbol_info)->parameter_no=1; } -#line 3469 "parser.tab.c" +#line 3587 "parser.tab.c" break; - case 156: /* parameter_declaration: declaration_specifiers abstract_declarator */ -#line 1298 "src/parser.y" + case 158: /* parameter_declaration: declaration_specifiers abstract_declarator */ +#line 1388 "src/parser.y" { symbol_info* new_symbol=new symbol_info(); (yyval.symbol_info)=new_symbol; (yyval.symbol_info)->type=(yyvsp[-1].str); (yyval.symbol_info)->name=(yyvsp[0].symbol_info)->name; } -#line 3480 "parser.tab.c" +#line 3598 "parser.tab.c" break; - case 157: /* parameter_declaration: declaration_specifiers */ -#line 1304 "src/parser.y" + case 159: /* parameter_declaration: declaration_specifiers */ +#line 1394 "src/parser.y" { symbol_info* new_symbol=new symbol_info(); (yyval.symbol_info)=new_symbol; (yyval.symbol_info)->type=(yyvsp[0].str); (yyval.symbol_info)->name=""; } -#line 3491 "parser.tab.c" +#line 3609 "parser.tab.c" break; - case 174: /* initializer: assignment_expression */ -#line 1341 "src/parser.y" + case 176: /* initializer: assignment_expression */ +#line 1431 "src/parser.y" { (yyvsp[0].symbol_info)->int_array.push_back((yyvsp[0].symbol_info)); (yyval.symbol_info)=(yyvsp[0].symbol_info); + // cerr<<$1->name<<" "<<$1->pointer_depth<type != (yyvsp[0].symbol_info)->type){ error_list.push_back("Line "+to_string(yylineno)+" : Type mismatch in initializer list"); @@ -3528,54 +3647,54 @@ yyparse (void) } (yyval.symbol_info) = (yyvsp[-2].symbol_info); } -#line 3532 "parser.tab.c" +#line 3651 "parser.tab.c" break; - case 179: /* statement: labeled_statement */ -#line 1364 "src/parser.y" + case 181: /* statement: labeled_statement */ +#line 1455 "src/parser.y" { (yyval.symbol_info)=(yyvsp[0].symbol_info); } -#line 3541 "parser.tab.c" +#line 3660 "parser.tab.c" break; - case 180: /* statement: compound_statement */ -#line 1369 "src/parser.y" + case 182: /* statement: compound_statement */ +#line 1460 "src/parser.y" { (yyval.symbol_info)=(yyvsp[0].symbol_info); } -#line 3549 "parser.tab.c" +#line 3668 "parser.tab.c" break; - case 181: /* statement: expression_statement */ -#line 1373 "src/parser.y" + case 183: /* statement: expression_statement */ +#line 1464 "src/parser.y" { (yyval.symbol_info)=(yyvsp[0].symbol_info); } -#line 3557 "parser.tab.c" +#line 3676 "parser.tab.c" break; - case 182: /* statement: selection_statement */ -#line 1376 "src/parser.y" + case 184: /* statement: selection_statement */ +#line 1467 "src/parser.y" {(yyval.symbol_info)=(yyvsp[0].symbol_info);} -#line 3563 "parser.tab.c" +#line 3682 "parser.tab.c" break; - case 183: /* statement: iteration_statement */ -#line 1377 "src/parser.y" + case 185: /* statement: iteration_statement */ +#line 1468 "src/parser.y" {(yyval.symbol_info)=(yyvsp[0].symbol_info);} -#line 3569 "parser.tab.c" +#line 3688 "parser.tab.c" break; - case 184: /* statement: jump_statement */ -#line 1378 "src/parser.y" + case 186: /* statement: jump_statement */ +#line 1469 "src/parser.y" {(yyval.symbol_info)=(yyvsp[0].symbol_info);} -#line 3575 "parser.tab.c" +#line 3694 "parser.tab.c" break; - case 185: /* labeled_statement: ID COLON statement */ -#line 1384 "src/parser.y" + case 187: /* labeled_statement: ID COLON statement */ +#line 1475 "src/parser.y" { if(lookup_symbol_global((yyvsp[-2].str), curr_scope)!=nullptr){ error_list.push_back("Line "+to_string(yylineno)+" : Label Redeclaration error "+(yyvsp[-2].str)); @@ -3602,11 +3721,11 @@ yyparse (void) curr_scope->symbol_map[(yyvsp[-2].str)]->type="label"; } } -#line 3606 "parser.tab.c" +#line 3725 "parser.tab.c" break; - case 186: /* labeled_statement: ID COLON declaration */ -#line 1411 "src/parser.y" + case 188: /* labeled_statement: ID COLON declaration */ +#line 1502 "src/parser.y" { if(lookup_symbol_global((yyvsp[-2].str), curr_scope)!=nullptr){ @@ -3634,33 +3753,33 @@ yyparse (void) curr_scope->symbol_map[(yyvsp[-2].str)]->type="label"; } } -#line 3638 "parser.tab.c" +#line 3757 "parser.tab.c" break; - case 188: /* labeled_statement: CASE constant_expression COLON statement */ -#line 1440 "src/parser.y" + case 190: /* labeled_statement: CASE constant_expression COLON statement */ +#line 1531 "src/parser.y" { string label=newlabel(); (yyval.symbol_info)->code = label +":\n"+ (yyvsp[0].symbol_info)->code; case_list.top().push({(yyvsp[-2].symbol_info)->code,label}); } -#line 3649 "parser.tab.c" +#line 3768 "parser.tab.c" break; - case 189: /* labeled_statement: DEFAULT COLON statement */ -#line 1447 "src/parser.y" + case 191: /* labeled_statement: DEFAULT COLON statement */ +#line 1538 "src/parser.y" { string label=newlabel(); case_list.top().push({"default",label}); (yyval.symbol_info)->code = label+":\n"+ (yyvsp[0].symbol_info)->code; } -#line 3660 "parser.tab.c" +#line 3779 "parser.tab.c" break; - case 191: /* $@1: %empty */ -#line 1458 "src/parser.y" + case 193: /* $@3: %empty */ +#line 1549 "src/parser.y" { curr_scope = new scoped_symtab(curr_scope); for(int i=0;ireturn_type=(yyvsp[-1].symbol_info)->return_type; all_scopes.push_back(curr_scope);curr_scope = curr_scope->parent; } -#line 3688 "parser.tab.c" +#line 3807 "parser.tab.c" break; - case 193: /* $@2: %empty */ -#line 1478 "src/parser.y" + case 195: /* $@4: %empty */ +#line 1569 "src/parser.y" {curr_scope = new scoped_symtab(curr_scope);} -#line 3694 "parser.tab.c" +#line 3813 "parser.tab.c" break; - case 194: /* compound_statement: LBRACE $@2 statement_list RBRACE */ -#line 1478 "src/parser.y" + case 196: /* compound_statement: LBRACE $@4 statement_list RBRACE */ +#line 1569 "src/parser.y" {symbol_info* new_symbol=new symbol_info(); (yyval.symbol_info)=new_symbol; (yyval.symbol_info)->code=(yyvsp[-1].symbol_info)->code; all_scopes.push_back(curr_scope); curr_scope = curr_scope->parent;} -#line 3703 "parser.tab.c" +#line 3822 "parser.tab.c" break; - case 195: /* $@3: %empty */ -#line 1482 "src/parser.y" + case 197: /* $@5: %empty */ +#line 1573 "src/parser.y" {curr_scope = new scoped_symtab(curr_scope);} -#line 3709 "parser.tab.c" +#line 3828 "parser.tab.c" break; - case 196: /* compound_statement: LBRACE $@3 declaration_list RBRACE */ -#line 1482 "src/parser.y" + case 198: /* compound_statement: LBRACE $@5 declaration_list RBRACE */ +#line 1573 "src/parser.y" {symbol_info* new_symbol=new symbol_info(); (yyval.symbol_info)=new_symbol; (yyval.symbol_info)->code=(yyvsp[-1].symbol_info)->code; all_scopes.push_back(curr_scope); curr_scope = curr_scope->parent;} -#line 3718 "parser.tab.c" +#line 3837 "parser.tab.c" break; - case 197: /* $@4: %empty */ -#line 1486 "src/parser.y" + case 199: /* $@6: %empty */ +#line 1577 "src/parser.y" {curr_scope = new scoped_symtab(curr_scope);} -#line 3724 "parser.tab.c" +#line 3843 "parser.tab.c" break; - case 198: /* compound_statement: LBRACE $@4 declaration_list statement_list RBRACE */ -#line 1486 "src/parser.y" + case 200: /* compound_statement: LBRACE $@6 declaration_list statement_list RBRACE */ +#line 1577 "src/parser.y" {symbol_info* new_symbol=new symbol_info(); (yyval.symbol_info)=new_symbol; (yyval.symbol_info)->code=(yyvsp[-2].symbol_info)->code+"\n"+(yyvsp[-1].symbol_info)->code;all_scopes.push_back(curr_scope); curr_scope = curr_scope->parent;} -#line 3732 "parser.tab.c" +#line 3851 "parser.tab.c" break; - case 199: /* statement_declaration_list: statement_list statement_declaration_list */ -#line 1493 "src/parser.y" + case 201: /* statement_declaration_list: statement_list statement_declaration_list */ +#line 1584 "src/parser.y" { symbol_info* new_symbol=new symbol_info(); (yyval.symbol_info)=new_symbol; @@ -3744,11 +3863,11 @@ yyparse (void) } -#line 3748 "parser.tab.c" +#line 3867 "parser.tab.c" break; - case 200: /* statement_declaration_list: declaration_list statement_declaration_list */ -#line 1505 "src/parser.y" + case 202: /* statement_declaration_list: declaration_list statement_declaration_list */ +#line 1596 "src/parser.y" { symbol_info* new_symbol=new symbol_info(); (yyval.symbol_info)=new_symbol; @@ -3759,11 +3878,11 @@ yyparse (void) } -#line 3763 "parser.tab.c" +#line 3882 "parser.tab.c" break; - case 201: /* statement_declaration_list: statement_list */ -#line 1516 "src/parser.y" + case 203: /* statement_declaration_list: statement_list */ +#line 1607 "src/parser.y" { symbol_info* new_symbol=new symbol_info(); (yyval.symbol_info)=new_symbol; @@ -3772,52 +3891,52 @@ yyparse (void) //dikkat badi hai // $$->return_type=$1->return_type; } -#line 3776 "parser.tab.c" +#line 3895 "parser.tab.c" break; - case 202: /* statement_declaration_list: declaration_list */ -#line 1525 "src/parser.y" + case 204: /* statement_declaration_list: declaration_list */ +#line 1616 "src/parser.y" { (yyval.symbol_info)=(yyvsp[0].symbol_info); } -#line 3784 "parser.tab.c" +#line 3903 "parser.tab.c" break; - case 203: /* declaration_list: declaration */ -#line 1532 "src/parser.y" + case 205: /* declaration_list: declaration */ +#line 1623 "src/parser.y" { symbol_info* new_symbol=new symbol_info(); (yyval.symbol_info)=new_symbol; (yyval.symbol_info)->code=(yyvsp[0].symbol_info)->code; //debug("declaration_list", $$->code); } -#line 3795 "parser.tab.c" +#line 3914 "parser.tab.c" break; - case 204: /* declaration_list: declaration_list declaration */ -#line 1539 "src/parser.y" + case 206: /* declaration_list: declaration_list declaration */ +#line 1630 "src/parser.y" { (yyval.symbol_info)->code=(yyvsp[-1].symbol_info)->code + "\n" + (yyvsp[0].symbol_info)->code; } -#line 3803 "parser.tab.c" +#line 3922 "parser.tab.c" break; - case 205: /* declaration_list: error SEMICOLON */ -#line 1542 "src/parser.y" + case 207: /* declaration_list: error SEMICOLON */ +#line 1633 "src/parser.y" {yyerrok;} -#line 3809 "parser.tab.c" +#line 3928 "parser.tab.c" break; - case 206: /* statement_list: statement */ -#line 1546 "src/parser.y" + case 208: /* statement_list: statement */ +#line 1637 "src/parser.y" { (yyval.symbol_info)=(yyvsp[0].symbol_info); } -#line 3817 "parser.tab.c" +#line 3936 "parser.tab.c" break; - case 207: /* statement_list: statement_list statement */ -#line 1550 "src/parser.y" + case 209: /* statement_list: statement_list statement */ +#line 1641 "src/parser.y" { (yyval.symbol_info)->is_return=((yyvsp[-1].symbol_info)->is_return)|((yyvsp[0].symbol_info)->is_return); // if($1->return_type!="") $$->return_type=$1->return_type; @@ -3825,52 +3944,52 @@ yyparse (void) (yyval.symbol_info)->code=(yyvsp[-1].symbol_info)->code + "\n" + (yyvsp[0].symbol_info)->code; } -#line 3829 "parser.tab.c" +#line 3948 "parser.tab.c" break; - case 208: /* statement_list: error SEMICOLON */ -#line 1557 "src/parser.y" + case 210: /* statement_list: error SEMICOLON */ +#line 1648 "src/parser.y" {yyerrok;} -#line 3835 "parser.tab.c" +#line 3954 "parser.tab.c" break; - case 210: /* expression_statement: expression SEMICOLON */ -#line 1562 "src/parser.y" + case 212: /* expression_statement: expression SEMICOLON */ +#line 1653 "src/parser.y" {(yyval.symbol_info)=(yyvsp[-1].symbol_info);} -#line 3841 "parser.tab.c" +#line 3960 "parser.tab.c" break; - case 211: /* selection_statement: IF LPARENTHESES expression RPARENTHESES statement */ -#line 1567 "src/parser.y" + case 213: /* selection_statement: IF LPARENTHESES expression RPARENTHESES statement */ +#line 1658 "src/parser.y" { string truelabel=newlabel(); string falselabel=newlabel(); (yyval.symbol_info)->code=(yyvsp[-2].symbol_info)->code+"\n"+"if("+ (yyvsp[-2].symbol_info)->place.first +") goto "+truelabel+"\n"+"goto "+falselabel+"\n"+truelabel+":\n"+(yyvsp[0].symbol_info)->code+"\n"+falselabel+":\n"; } -#line 3851 "parser.tab.c" +#line 3970 "parser.tab.c" break; - case 212: /* selection_statement: IF LPARENTHESES expression RPARENTHESES statement ELSE statement */ -#line 1573 "src/parser.y" + case 214: /* selection_statement: IF LPARENTHESES expression RPARENTHESES statement ELSE statement */ +#line 1664 "src/parser.y" { string truelabel=newlabel(); string falselabel=newlabel(); string endlabel=newlabel(); (yyval.symbol_info)->code=(yyvsp[-4].symbol_info)->code+"\n"+"if("+ (yyvsp[-4].symbol_info)->place.first +") goto "+truelabel+"\n"+"goto "+falselabel+"\n"+truelabel+":\n"+(yyvsp[-2].symbol_info)->code+"\n"+"goto "+endlabel+"\n"+falselabel+":\n"+(yyvsp[0].symbol_info)->code+"\n"+endlabel+":\n"; } -#line 3862 "parser.tab.c" +#line 3981 "parser.tab.c" break; - case 213: /* $@5: %empty */ -#line 1579 "src/parser.y" + case 215: /* $@7: %empty */ +#line 1670 "src/parser.y" {queue> q; case_list.push(q); } -#line 3870 "parser.tab.c" +#line 3989 "parser.tab.c" break; - case 214: /* selection_statement: SWITCH $@5 LPARENTHESES expression RPARENTHESES statement */ -#line 1582 "src/parser.y" + case 216: /* selection_statement: SWITCH $@7 LPARENTHESES expression RPARENTHESES statement */ +#line 1673 "src/parser.y" { string str=""; while(!case_list.top().empty()){ @@ -3888,11 +4007,11 @@ yyparse (void) (yyval.symbol_info)->code=replace_break_continue((yyval.symbol_info)->code,endlabel," ",1); case_list.pop(); } -#line 3892 "parser.tab.c" +#line 4011 "parser.tab.c" break; - case 215: /* iteration_statement: WHILE LPARENTHESES expression RPARENTHESES statement */ -#line 1603 "src/parser.y" + case 217: /* iteration_statement: WHILE LPARENTHESES expression RPARENTHESES statement */ +#line 1694 "src/parser.y" { string startlabel=newlabel(); string endlabel=newlabel(); @@ -3902,11 +4021,11 @@ yyparse (void) (yyval.symbol_info)->code=startlabel+":\n"+(yyvsp[-2].symbol_info)->code+"\n"+"if("+(yyvsp[-2].symbol_info)->place.first+") goto "+truelabel+"\n"+"goto "+endlabel+"\n"+truelabel+":\n"+(yyvsp[0].symbol_info)->code+"\n"+"goto "+startlabel+"\n"+endlabel+":\n"; (yyval.symbol_info)->code=replace_break_continue((yyval.symbol_info)->code,endlabel,startlabel,1); } -#line 3906 "parser.tab.c" +#line 4025 "parser.tab.c" break; - case 216: /* iteration_statement: DO statement WHILE LPARENTHESES expression RPARENTHESES SEMICOLON */ -#line 1613 "src/parser.y" + case 218: /* iteration_statement: DO statement WHILE LPARENTHESES expression RPARENTHESES SEMICOLON */ +#line 1704 "src/parser.y" { string startlabel=newlabel(); string endlabel=newlabel(); @@ -3916,11 +4035,11 @@ yyparse (void) (yyval.symbol_info)->code=startlabel+":\n"+(yyvsp[-5].symbol_info)->code+"\n"+truelabel+":\n"+(yyvsp[-2].symbol_info)->code+"\n"+"\n"+"if("+(yyvsp[-2].symbol_info)->place.first+") goto "+startlabel+"\n"+"goto "+endlabel+"\n"+endlabel+":\n"; (yyval.symbol_info)->code=replace_break_continue((yyval.symbol_info)->code,endlabel,startlabel,1); } -#line 3920 "parser.tab.c" +#line 4039 "parser.tab.c" break; - case 217: /* iteration_statement: FOR LPARENTHESES expression_statement expression_statement RPARENTHESES statement */ -#line 1623 "src/parser.y" + case 219: /* iteration_statement: FOR LPARENTHESES expression_statement expression_statement RPARENTHESES statement */ +#line 1714 "src/parser.y" { string startlabel=newlabel(); string endlabel=newlabel(); @@ -3930,11 +4049,11 @@ yyparse (void) (yyval.symbol_info)->code=(yyvsp[-3].symbol_info)->code+"\n"+startlabel+":\n"+(yyvsp[-2].symbol_info)->code+"\n"+"if("+(yyvsp[-2].symbol_info)->place.first+") goto "+truelabel+"\n"+"goto "+endlabel+"\n"+truelabel+":\n"+(yyvsp[0].symbol_info)->code+"\n"+"\n"+"goto "+startlabel+"\n"+endlabel+":\n"; (yyval.symbol_info)->code=replace_break_continue((yyval.symbol_info)->code,endlabel,startlabel,1); } -#line 3934 "parser.tab.c" +#line 4053 "parser.tab.c" break; - case 218: /* iteration_statement: FOR LPARENTHESES expression_statement expression_statement expression RPARENTHESES statement */ -#line 1633 "src/parser.y" + case 220: /* iteration_statement: FOR LPARENTHESES expression_statement expression_statement expression RPARENTHESES statement */ +#line 1724 "src/parser.y" { string startlabel=newlabel(); string endlabel=newlabel(); @@ -3947,11 +4066,11 @@ yyparse (void) (yyval.symbol_info)->code=replace_break_continue((yyval.symbol_info)->code,endlabel,updatelabel,0); } -#line 3951 "parser.tab.c" +#line 4070 "parser.tab.c" break; - case 219: /* jump_statement: GOTO ID SEMICOLON */ -#line 1649 "src/parser.y" + case 221: /* jump_statement: GOTO ID SEMICOLON */ +#line 1740 "src/parser.y" { //idhar ID ko symtab me insert karna he if(goto_list.find((yyvsp[-1].str))==goto_list.end()){ @@ -3974,33 +4093,33 @@ yyparse (void) // cerr << "goto\n"; } -#line 3978 "parser.tab.c" +#line 4097 "parser.tab.c" break; - case 220: /* jump_statement: CONTINUE SEMICOLON */ -#line 1672 "src/parser.y" + case 222: /* jump_statement: CONTINUE SEMICOLON */ +#line 1763 "src/parser.y" { symbol_info* new_symbol=new symbol_info(); (yyval.symbol_info)=new_symbol; (yyval.symbol_info)->is_continue=true; (yyval.symbol_info)->code="\n continue \n"; } -#line 3989 "parser.tab.c" +#line 4108 "parser.tab.c" break; - case 221: /* jump_statement: BREAK SEMICOLON */ -#line 1679 "src/parser.y" + case 223: /* jump_statement: BREAK SEMICOLON */ +#line 1770 "src/parser.y" { symbol_info* new_symbol=new symbol_info(); (yyval.symbol_info)=new_symbol; (yyval.symbol_info)->is_break=true; (yyval.symbol_info)->code="\n break \n"; } -#line 4000 "parser.tab.c" +#line 4119 "parser.tab.c" break; - case 222: /* jump_statement: RETURN SEMICOLON */ -#line 1686 "src/parser.y" + case 224: /* jump_statement: RETURN SEMICOLON */ +#line 1777 "src/parser.y" { symbol_info* new_symbol=new symbol_info(); (yyval.symbol_info)=new_symbol; @@ -4008,11 +4127,11 @@ yyparse (void) (yyval.symbol_info)->return_type="void"; (yyval.symbol_info)->code="\nRETURN\n"; } -#line 4012 "parser.tab.c" +#line 4131 "parser.tab.c" break; - case 223: /* jump_statement: RETURN expression SEMICOLON */ -#line 1694 "src/parser.y" + case 225: /* jump_statement: RETURN expression SEMICOLON */ +#line 1785 "src/parser.y" { symbol_info* new_symbol=new symbol_info(); (yyval.symbol_info)=new_symbol; @@ -4021,56 +4140,56 @@ yyparse (void) (yyval.symbol_info)->code=(yyvsp[-1].symbol_info)->code + "\nRETURN "+(yyvsp[-1].symbol_info)->place.first+"\n"; //debug("return ",$$->code); } -#line 4025 "parser.tab.c" +#line 4144 "parser.tab.c" break; - case 224: /* start_symbol: translation_unit */ -#line 1705 "src/parser.y" + case 226: /* start_symbol: translation_unit */ +#line 1796 "src/parser.y" { //cerr<<"-----------------"<code<<"----------------"<code); } -#line 4036 "parser.tab.c" +#line 4155 "parser.tab.c" break; - case 225: /* translation_unit: external_declaration */ -#line 1714 "src/parser.y" + case 227: /* translation_unit: external_declaration */ +#line 1805 "src/parser.y" { (yyval.symbol_info)->code=(yyvsp[0].symbol_info)->code; } -#line 4044 "parser.tab.c" +#line 4163 "parser.tab.c" break; - case 226: /* translation_unit: translation_unit external_declaration */ -#line 1718 "src/parser.y" + case 228: /* translation_unit: translation_unit external_declaration */ +#line 1809 "src/parser.y" { (yyval.symbol_info)->code=(yyvsp[-1].symbol_info)->code+(yyvsp[0].symbol_info)->code; } -#line 4052 "parser.tab.c" +#line 4171 "parser.tab.c" break; - case 228: /* external_declaration: function_definition */ -#line 1726 "src/parser.y" + case 230: /* external_declaration: function_definition */ +#line 1817 "src/parser.y" { (yyval.symbol_info)=(yyvsp[0].symbol_info); } -#line 4060 "parser.tab.c" +#line 4179 "parser.tab.c" break; - case 231: /* $@6: %empty */ -#line 1735 "src/parser.y" + case 233: /* $@8: %empty */ +#line 1826 "src/parser.y" { var_name=(yyvsp[0].symbol_info)->param_list; type_list=(yyvsp[0].symbol_info)->param_types; curr_scope->symbol_map[(yyvsp[0].symbol_info)->name]->type=(yyvsp[-1].str); } -#line 4070 "parser.tab.c" +#line 4189 "parser.tab.c" break; - case 232: /* function_definition: declaration_specifiers declarator $@6 compound_statement */ -#line 1741 "src/parser.y" + case 234: /* function_definition: declaration_specifiers declarator $@8 compound_statement */ +#line 1832 "src/parser.y" { if(strcmp((yyvsp[-3].str),"void")==0){ @@ -4100,11 +4219,11 @@ yyparse (void) (yyval.symbol_info)->code=(yyval.symbol_info)->code+(yyvsp[0].symbol_info)->code+"\nFUNC_END "+(yyvsp[-2].symbol_info)->name+"\n"; } -#line 4104 "parser.tab.c" +#line 4223 "parser.tab.c" break; -#line 4108 "parser.tab.c" +#line 4227 "parser.tab.c" default: break; } @@ -4297,7 +4416,7 @@ yyparse (void) return yyresult; } -#line 1773 "src/parser.y" +#line 1864 "src/parser.y" void yyerror(const char *s) { @@ -4333,12 +4452,12 @@ void print_scope_table(){ printf("-----------------------------------------------------------------\n"); for (const auto& it : scope->symbol_map) { + if (!it.second) { // Check if symbol_info* is null (shouldn't happen after your fix) printf("| %-15s | %-20s | %-7s | %-10s |\n", it.first.c_str(), "uninitialized", "N/A", "N/A"); continue; } - std::string valueStr = "N/A"; // Default value int size = 0; // Default size @@ -4358,7 +4477,9 @@ void print_scope_table(){ } else { size = 0; // Unknown type } - + if(it.second->is_static){ + it.second->type = "static "+it.second->type; + } printf("| %-15s | %-20s | %-7d | %-10s |\n", it.first.c_str(), // Identifier it.second->type.c_str(), // Type @@ -4394,5 +4515,4 @@ int main() { curr_scope->symbol_map["printf"]=new_symbol; curr_scope->symbol_map["scanf"]=new_symbol; yyparse(); - // print_scope_table(); } diff --git a/Assignment3/parser.tab.h b/Assignment3/parser.tab.h index 7726207..5b9d377 100644 --- a/Assignment3/parser.tab.h +++ b/Assignment3/parser.tab.h @@ -162,7 +162,7 @@ extern int yydebug; #if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED union YYSTYPE { -#line 35 "src/parser.y" +#line 36 "src/parser.y" char* str; // For type_specifier, declarator struct symbol_info* symbol_info; // For expressions and constants diff --git a/Assignment3/src/parser.y b/Assignment3/src/parser.y index 58d60dc..03f3fe3 100644 --- a/Assignment3/src/parser.y +++ b/Assignment3/src/parser.y @@ -6,6 +6,7 @@ void yyerror(const char *s); void print_errors(); + void print_scope_table(); extern int yylex(); extern int yylineno; @@ -341,12 +342,13 @@ argument_expression_list : assignment_expression { if($1->place.first!=""){ - // debug("herrrr ", $1->code); + $$->code=$1->code; $$->param_types.push_back($1->type); $$->param_list.push_back($1->place.first); } else{ + // debug("gggggggggggggg ", $1->code); if($1->name==""){ $$=new symbol_info($1); $$->param_types.push_back($1->type); @@ -410,7 +412,23 @@ unary_expression $$=$1; } | INCREMENT unary_expression + { + symbol_info* new_symbol=new symbol_info(); + $$=new_symbol; + $$->name=$2->name; + $$->place=$2->place; + $$->code=$2->code + "\n" + $2->place.first+":= "+$2->place.first+"+1"; + + } | DECREMENT unary_expression + { + symbol_info* new_symbol=new symbol_info(); + $$=new_symbol; + $$->name=$2->name; + $$->place=$2->place; + $$->code=$2->code + "\n" + $2->place.first+":= "+$2->place.first+"-1"; + + } | unary_operator cast_expression { symbol_info* new_symbol=new symbol_info(); @@ -427,6 +445,14 @@ unary_expression $$->type.pop_back(); } } + // if($1->code=="-"){ + // debug("ddddd",$2->name); + // qid var=newtemp($2->type,curr_scope); + + // if($2->name!="") $$->code=$2->code+"\n"+var.first+":= -"+$2->name; + // else if($2->place.first!="") $$->code=$2->code+"\n"+var.first+":= -"+$2->place.first; + // $$->place=var; + // } $$->name=$2->name; $$->code=$2->code+"\n"+$1->code+$2->place.first; @@ -484,6 +510,7 @@ unary_operator cast_expression : unary_expression { + $$=$1; } | LPARENTHESES type_name RPARENTHESES cast_expression @@ -528,8 +555,13 @@ additive_expression : multiplicative_expression {$$=$1;} | additive_expression PLUS multiplicative_expression { + // cerr<<$1->type<type<type = priority_to_type[max(type_priority[$1->type],type_priority[$3->type])]; + if(count_star($1->type)>count_star($3->type)) $$->type=$1->type; + else if(count_star($1->type)type)) $$->type=$3->type; + else $$->type = priority_to_type[max(type_priority[$1->type],type_priority[$3->type])]; + // cerr<<$$->type<type,curr_scope); $$->code=$1->code + "\n" + $3->code +"\n" + var.first+":= "+$1->place.first+"+"+$3->place.first; $$->place=var; @@ -700,7 +732,13 @@ conditional_expression ; assignment_expression - : conditional_expression {$$=$1;} + : conditional_expression + { + + $$=$1; + // cerr<<"hereeeeee "<<$$->name<type<type],type_priority[$3->type])==0 && $1->type!=$3->type){ - error_list.push_back("Line "+to_string(yylineno)+" : Type mismatch in assignment"); + if($3->type!="int" && $1->type!="int") error_list.push_back("Line "+to_string(yylineno)+" : Type mismatch in assignment"); } - if(type_priority[$1->type]type]){ - error_list.push_back("Line "+to_string(yylineno)+" : Type mismatch in assignment"); + else if(type_priority[$1->type]type]){ + error_list.push_back("Line "+to_string(yylineno)+" : Type mismatch in assignment3"); } string third_code=$3->code; string first_code=$1->code; if(min(type_priority[$1->type],type_priority[find_symbol->type])>0) find_symbol->type=priority_to_type[max(type_priority[find_symbol->type],type_priority[$3->type])]; - + find_symbol->name=$1->name; find_symbol->place=$1->place; find_symbol->code=$1->code + "\n" + $3->code + "\n" + $1->place.first + ":= " + $3->place.first; - + find_symbol->pointer_depth=max($1->pointer_depth, $3->pointer_depth); + // cerr<<$1->name<<" |||| "<<$1->pointer_depth<name<<" |||| "<<$3->pointer_depth<name<pointer_depth<place.first[0]!='t' && $3->place.first[0]!='&' && $3->place.first[0]!='*' && $3->place.first[0]!='+' && $3->place.first[0]!='-' && $3->place.first[0]!='~' && $3->place.first[0]!='!') { @@ -870,7 +912,7 @@ declaration parsing_stack.pop(); pointer_info.pop(); if (curr_scope->symbol_map[top_symbol]->type!= ""){ - if(depth!=count_star(curr_scope->symbol_map[top_symbol]->type)){ + if(depth!=count_star(curr_scope->symbol_map[top_symbol]->type) && !curr_scope->symbol_map[top_symbol]->is_array){ error_list.push_back("Line "+to_string(yylineno)+" : Pointer depth mismatch"); flag = 1; } @@ -883,31 +925,38 @@ declaration curr_scope->symbol_map[top_symbol]->name = top_symbol; if(type_priority[$1]>0 && type_priority[curr_scope->symbol_map[top_symbol]->type]>0) curr_scope->symbol_map[top_symbol]->type = priority_to_type[max(type_priority[$1], type_priority[curr_scope->symbol_map[top_symbol]->type])]; - + if(std::string($1).substr(0,6) == "static"){ + curr_scope->symbol_map[top_symbol]->is_static = true; + } // debug("declaration specifiers121 ", $2->code); - - code=$2->code; + code+=$2->code; } else { + curr_scope->symbol_map[top_symbol]->type = $1; for(int i=0;isymbol_map[top_symbol]->type+="*"; } + if(curr_scope->symbol_map[top_symbol]->is_array) curr_scope->symbol_map[top_symbol]->type+="*"; curr_scope->symbol_map[top_symbol]->name = top_symbol; curr_scope->symbol_map[top_symbol]->pointer_depth = depth; - if((curr_scope->symbol_map[top_symbol]->type).substr(0,6)=="struct") { + // cerr<<"gggggghjjj "<<$1<symbol_map[top_symbol]->type).substr(7); + if(struct_name.back()=='*') struct_name.pop_back(); symbol_info* find_struct=lookup_symbol_global(struct_name, curr_scope); int size=0; + for(int i=0;iparam_list.size();i++){ size+=get_size(find_struct->param_types[i]); } //debug("Struct size: ",to_string(size)); + code=code+top_symbol+":= alloc " +to_string(size)+"\n"; + } else if((curr_scope->symbol_map[top_symbol]->type).substr(0,5)=="union") @@ -923,15 +972,31 @@ declaration } + if(curr_scope->symbol_map[top_symbol]->is_array){ + // debug("in the arr",curr_scope->symbol_map[top_symbol]->type.substr(0,3)); + if(curr_scope->symbol_map[top_symbol]->type.substr(0,3)=="int"){ + code=code+top_symbol+":= alloc " +to_string(4*curr_scope->symbol_map[top_symbol]->array_length)+"\n"; + } + if(curr_scope->symbol_map[top_symbol]->type.substr(0,5)=="float"){ + code=code+top_symbol+":= alloc " +to_string(4*curr_scope->symbol_map[top_symbol]->array_length)+"\n"; + } + if(curr_scope->symbol_map[top_symbol]->type.substr(0,4)=="char"){ + code=code+top_symbol+":= alloc " +to_string(2*curr_scope->symbol_map[top_symbol]->array_length)+"\n"; + } + // debug("in the arr",code); + + } + symbol_info* new_symbol = new symbol_info(); new_symbol = new symbol_info($2); $$=new_symbol; - + } } // debug("declaration specifiers ", to_string(parsing_stack.size())); $$->code=code; + // debug("in the arr11",$$->code); //debug("Declaration: ",curr_scope->symbol_map["p"]->code); } @@ -967,7 +1032,7 @@ init_declarator_list init_declarator : declarator { - if(lookup_symbol_global($1->name, curr_scope)!=nullptr){ + if(lookup_symbol_local($1->name, curr_scope)!=nullptr){ error_list.push_back("Line "+to_string(yylineno)+" : Redeclaration error "+$1->name); } symbol_info* new_symbol = new symbol_info(); @@ -975,14 +1040,15 @@ init_declarator curr_scope->symbol_map[$1->name]=new_symbol; curr_scope->symbol_map[$1->name]->name=$1->name; if($1->is_array==true){ - curr_scope->symbol_map[$1->name]->is_array=true; + curr_scope->symbol_map[$1->name]->is_array=true; curr_scope->symbol_map[$1->name]->array_length=$1->array_length; if($1->type=="int" || $1->type=="float"){ + // cerr<<"gggg"<<$1->type<name+":= alloc " +to_string(4*$1->array_length); $$->code=code; } else if($1->type=="char"){ - string code=$1->name+":= alloc " +to_string(2*$1->array_length); + string code=$1->name+":= alloc " +to_string(2*$1->array_length); $$->code=code; } } @@ -1002,7 +1068,6 @@ init_declarator curr_scope->symbol_map[$1->name]=$3; parsing_stack.push($1->name.c_str()); pointer_info.push($1->pointer_depth); - if($1->is_array){ if($3->int_array.size() > $1->array_length){ error_list.push_back("Line "+to_string(yylineno)+" : Array size mismatch "+$1->name); @@ -1010,21 +1075,23 @@ init_declarator else{ $1->int_array = $3->int_array; $1->type = $3->type; + $1->type=$1->type+"*"; curr_scope->symbol_map[$1->name]->is_array=true; + curr_scope->symbol_map[$1->name]->type=$1->type; string code=$1->name+":= alloc "; - if($1->type=="int" || $1->type=="float"){ + if($1->type=="int*" || $1->type=="float*"){ code=code+to_string(4*$1->array_length); } - else if($1->type=="char"){ + else if($1->type=="char*"){ code=code+to_string(2*$1->array_length); } for(int i=0;i<$1->array_length;i++){ qid temp=newtemp($1->type,curr_scope); code=code+"\n"+temp.first+":= "+to_string(i)+"*"; - if($1->type=="int") code=code+"4\n"+"*( "+$1->name+" + "+temp.first+" ):= "+to_string(*(int*)($1->int_array[i]->ptr)); - else if($1->type=="float") code=code+"4\n"+"*( "+$1->name+" + "+temp.first+" ):= "+to_string(*(float*)($1->int_array[i]->ptr)); - else if($1->type=="char") code=code+"2\n"+"*( "+$1->name+" + "+temp.first+" ):= "+char(*(char*)($1->int_array[i]->ptr)); - else if($1->type=="char*") code=code+"2\n"+"*( "+$1->name+" + "+temp.first+" ):= "+$1->int_array[i]->str_val; + if($1->type=="int*") code=code+"4\n"+"*( "+$1->name+" + "+temp.first+" ):= "+to_string(*(int*)($1->int_array[i]->ptr)); + else if($1->type=="float*") code=code+"4\n"+"*( "+$1->name+" + "+temp.first+" ):= "+to_string(*(float*)($1->int_array[i]->ptr)); + else if($1->type=="char*") code=code+"2\n"+"*( "+$1->name+" + "+temp.first+" ):= "+char(*(char*)($1->int_array[i]->ptr)); + else if($1->type=="char**") code=code+"2\n"+"*( "+$1->name+" + "+temp.first+" ):= "+$1->int_array[i]->str_val; } $$->code=code; } @@ -1072,28 +1139,50 @@ type_specifier ; struct_or_union_specifier - : struct_or_union ID LBRACE struct_declaration_list RBRACE + : struct_or_union ID { - symbol_info* new_symbol=new symbol_info(); - new_symbol->type = $1; - new_symbol->param_list = $4->param_list; - new_symbol->param_types = $4->param_types; - curr_scope->symbol_map[$2]=new_symbol; + symbol_info* find_symbol=lookup_symbol_local($2,curr_scope); + if(find_symbol==nullptr){ + symbol_info* new_symbol=new symbol_info(); + curr_scope->symbol_map[$2]=new_symbol; + curr_scope->symbol_map[$2]->name = $2; + curr_scope->symbol_map[$2]->type = $1; + } + else{ + error_list.push_back("Line "+to_string(yylineno)+" : Struct redeclaration error "+$1); + } + } + LBRACE + { + curr_scope = new scoped_symtab(curr_scope); + + } + struct_declaration_list RBRACE + { + + + curr_scope->parent->symbol_map[$2]->param_list = $6->param_list; + curr_scope->parent->symbol_map[$2]->param_types = $6->param_types; + all_scopes.push_back(curr_scope); curr_scope = curr_scope->parent; + } | struct_or_union LBRACE struct_declaration_list RBRACE | struct_or_union ID { + symbol_info* find_symbol = lookup_symbol_global($2, curr_scope); if (find_symbol != nullptr) { if (find_symbol->type == "struct" || find_symbol->type == "union") { std::string temp = std::string($1) + " " + std::string($2); $$ = strdup(temp.c_str()); + } else { error_list.push_back("Line "+to_string(yylineno)+" : Variable not of type struct or union"); } } else { error_list.push_back("Line "+to_string(yylineno)+" : Struct or Union not declared "+$2); } + } ; @@ -1196,6 +1285,7 @@ direct_declarator x->name = $1; x->place.first=$1; $$=x; + } | LPARENTHESES declarator RPARENTHESES | direct_declarator LBRACKET constant_expression RBRACKET @@ -1341,6 +1431,7 @@ initializer : assignment_expression { $1->int_array.push_back($1); $$=$1; + // cerr<<$1->name<<" "<<$1->pointer_depth<code<<"----------------"<code); } @@ -1805,12 +1896,12 @@ void print_scope_table(){ printf("-----------------------------------------------------------------\n"); for (const auto& it : scope->symbol_map) { + if (!it.second) { // Check if symbol_info* is null (shouldn't happen after your fix) printf("| %-15s | %-20s | %-7s | %-10s |\n", it.first.c_str(), "uninitialized", "N/A", "N/A"); continue; } - std::string valueStr = "N/A"; // Default value int size = 0; // Default size @@ -1830,7 +1921,9 @@ void print_scope_table(){ } else { size = 0; // Unknown type } - + if(it.second->is_static){ + it.second->type = "static "+it.second->type; + } printf("| %-15s | %-20s | %-7d | %-10s |\n", it.first.c_str(), // Identifier it.second->type.c_str(), // Type @@ -1866,5 +1959,4 @@ int main() { curr_scope->symbol_map["printf"]=new_symbol; curr_scope->symbol_map["scanf"]=new_symbol; yyparse(); - // print_scope_table(); } diff --git a/Assignment3/test/input1.c b/Assignment3/test/input1.c index 10f8da0..76aa963 100644 --- a/Assignment3/test/input1.c +++ b/Assignment3/test/input1.c @@ -8,12 +8,6 @@ int main(){ a.x=10; a.y=10; - int c=4; - int* p=&c; - int **q=&p; - int d; - d=**q; - - **q=20; + // int c=a.x; return 0; } \ No newline at end of file diff --git a/Assignment3/test/input2 b/Assignment3/test/input2 new file mode 100755 index 0000000..9fe8868 Binary files /dev/null and b/Assignment3/test/input2 differ diff --git a/Assignment3/test/input2.c b/Assignment3/test/input2.c index b6a72cc..4f84a71 100644 --- a/Assignment3/test/input2.c +++ b/Assignment3/test/input2.c @@ -1,8 +1,6 @@ -typedef float A; - -int main(){ - A b=3; - float c=b; - int d=4; +int main() +{ + int b=3; + int a=-b; return 0; } \ No newline at end of file diff --git a/Assignment3/test/input8.c b/Assignment3/test/input8.c new file mode 100644 index 0000000..6da6365 --- /dev/null +++ b/Assignment3/test/input8.c @@ -0,0 +1,66 @@ +int glb; +int glb1 = 10; + +int glb2; +struct foo +{ + int a; + int b; + struct foo *next; +}; + +int bar(int a, float b) +{ + int lcl = 10; + while (b) + { + b--; + } + if (a == 0){ + return 0; + } + + bar(++a, a + b + lcl); // what if I use a++; +} + +int main() +{ + // int a=4; + int a = 100, b[20], ret,glb; + b[1]=5; + static int hi; + int arr[5] = {1,2,3,4,5}; + int i; + for ( i = 0; i < a; i++) + { + int b = 0; + b += i; + if (b % 2 != b % 3) + printf("%d\n", a + b); + else if (b % 2 == 0) + { + switch (b) + { + case 100: + printf("1\n"); + break; + case 1000: + printf("2\n"); + default: + printf("2\n"); + } + } + // b[19] = i; + ret = i; + } + int *c=b+2; // change to * + c=b; +jump: + struct foo newS[5]; + // printf(newS[3].b); + // if (*(b+2) == 0){ + // goto jump; + // } + // goto jump; + bar(1, *b); +} \ No newline at end of file diff --git a/Assignment4/.gitignore b/Assignment4/.gitignore new file mode 100644 index 0000000..9cd9440 --- /dev/null +++ b/Assignment4/.gitignore @@ -0,0 +1,21 @@ +# Ignore compiled files +**/lex.yy.c +**/lexer +**/parser +**/parser.tab.c +**/parser.tab.h +lex.yy.c +parser.tab.c +parser.tab.h +parser +lexer +# Ignore backup and temporary files +**/*.swp +**/*.swo +**/*.bak +**/*~ + +# Ignore build artifacts +**/*.o +**/*.out +**/*.exe \ No newline at end of file diff --git a/Assignment4/.vscode/settings.json b/Assignment4/.vscode/settings.json new file mode 100644 index 0000000..c5a3fb4 --- /dev/null +++ b/Assignment4/.vscode/settings.json @@ -0,0 +1,97 @@ +{ + "files.associations": { + "any": "cpp", + "array": "cpp", + "atomic": "cpp", + "barrier": "cpp", + "bit": "cpp", + "*.tcc": "cpp", + "bitset": "cpp", + "cctype": "cpp", + "cfenv": "cpp", + "charconv": "cpp", + "chrono": "cpp", + "cinttypes": "cpp", + "clocale": "cpp", + "cmath": "cpp", + "codecvt": "cpp", + "compare": "cpp", + "complex": "cpp", + "concepts": "cpp", + "condition_variable": "cpp", + "coroutine": "cpp", + "csetjmp": "cpp", + "csignal": "cpp", + "cstdarg": "cpp", + "cstddef": "cpp", + "cstdint": "cpp", + "cstdio": "cpp", + "cstdlib": "cpp", + "cstring": "cpp", + "ctime": "cpp", + "cuchar": "cpp", + "cwchar": "cpp", + "cwctype": "cpp", + "deque": "cpp", + "forward_list": "cpp", + "list": "cpp", + "map": "cpp", + "set": "cpp", + "string": "cpp", + "unordered_map": "cpp", + "unordered_set": "cpp", + "vector": "cpp", + "exception": "cpp", + "expected": "cpp", + "algorithm": "cpp", + "functional": "cpp", + "iterator": "cpp", + "memory": "cpp", + "memory_resource": "cpp", + "numeric": "cpp", + "optional": "cpp", + "random": "cpp", + "ratio": "cpp", + "regex": "cpp", + "source_location": "cpp", + "string_view": "cpp", + "system_error": "cpp", + "tuple": "cpp", + "type_traits": "cpp", + "utility": "cpp", + "format": "cpp", + "fstream": "cpp", + "future": "cpp", + "initializer_list": "cpp", + "iomanip": "cpp", + "iosfwd": "cpp", + "iostream": "cpp", + "istream": "cpp", + "latch": "cpp", + "limits": "cpp", + "mutex": "cpp", + "new": "cpp", + "numbers": "cpp", + "ostream": "cpp", + "ranges": "cpp", + "scoped_allocator": "cpp", + "semaphore": "cpp", + "shared_mutex": "cpp", + "span": "cpp", + "spanstream": "cpp", + "sstream": "cpp", + "stacktrace": "cpp", + "stdexcept": "cpp", + "stdfloat": "cpp", + "stop_token": "cpp", + "streambuf": "cpp", + "syncstream": "cpp", + "thread": "cpp", + "typeindex": "cpp", + "typeinfo": "cpp", + "valarray": "cpp", + "variant": "cpp", + "filesystem": "c", + "__nullptr": "cpp" + } +} \ No newline at end of file diff --git a/Assignment4/Makefile b/Assignment4/Makefile new file mode 100644 index 0000000..1fddb31 --- /dev/null +++ b/Assignment4/Makefile @@ -0,0 +1,27 @@ +# Define compiler and tools +LEX = flex +BISON = bison +CC = g++ +CFLAGS = -w + +# Output executable name +EXEC = parser + +# Source files +LEX_FILE = src/scanner.l +YACC_FILE = src/parser.y + +INCLUDE_DIR = include + +# Default target +all: $(EXEC) + +# Rule to compile the parser and scanner +$(EXEC): clean $(YACC_FILE) $(LEX_FILE) + $(BISON) -d -Wno-all $(YACC_FILE) + $(LEX) $(LEX_FILE) + $(CC) $(CFLAGS) -I$(INCLUDE_DIR) parser.tab.c lex.yy.c src/codegen.cpp -o $(EXEC) -ll + +# Clean build files +clean: + rm -f $(EXEC) lex.yy.c parser.tab.c parser.tab.h diff --git a/Assignment4/README.md b/Assignment4/README.md new file mode 100644 index 0000000..774d186 --- /dev/null +++ b/Assignment4/README.md @@ -0,0 +1,67 @@ +# CSN-352-Compiler + +This project implements a **C to MIPS compiler** using **3-address code (3AC)** as an intermediate representation. + +--- + +## 📂 Project Directory Structure +```bash +Assignment4/ +│── src/ # Source code directory +│ ├── scanner.l # Lex file for lexical analysis +| ├── parser.y # File for syntax analysis and generation of 3AC +| ├── codegen.cpp # File for generation of MIPS code from 3AC +│── include/ # Auxillary directory +│ ├── 3AC.h # header file for 3AC code generation +| ├── functions.h # Auxillary functions for 3AC code generation +| ├── utility.h # Data Structures definition for nodes +│── test/ # Test cases for the compiler +│ ├── input1.c # Sample test case 1 +│ ├── input2.c # Sample test case 2 +│ ├── input3.c # Sample test case 3 +│ ├── ... # More test cases +│── output/ # Stores output files (Auto-generated) +│ ├── output1.s # Output of input1.c +│ ├── output2.s # Output of input2.c +│ ├── output3.s # Output of input3.c +│── Makefile # Build automation file +│── run.sh # Script to execute test cases +│── README.md # Project documentation + + +``` +## ⚙️ How to Compile and Run +Follow these steps to build and execute the lexical analyzer: + +### 1️⃣ Compile the files +```bash +make clean +make +``` +### 2️⃣ Run the Test Cases +After that run script using: +```bash +./run.sh +``` +### 3️⃣ Check Output +```bash +ls output/ # Lists all output files +cat output/output1.s # View output for input1.c +cat output/output2.s # View output for input2.c +``` +### 4️⃣ Error Handling +Errors for each code are written within the generated output file corresponding to that code. + +## 🛠️ Implementation Details + + - Lexical Analysis: Uses Flex (Lex) to tokenize C source code. + - Parsing: + Uses Bison (Yacc) to parse the tokenized code according to standard C grammar. + Each of the output files contain symbol table and constant table generated after parsing. + - Intermediate Representation: Uses Three address code. + - Compiler Backend: Generates MIPS Assembly Code to be run on a simulator like Qtspim + +## 📌 Notes + + - Ensure that flex, bison, Qtspim and g++ are installed before running the project. + - The project is structured to automatically generate output files in the output/ directory. \ No newline at end of file diff --git a/Assignment4/advance.cpp b/Assignment4/advance.cpp new file mode 100644 index 0000000..fdc361c --- /dev/null +++ b/Assignment4/advance.cpp @@ -0,0 +1,62 @@ +// #include +// using namespace std; + +// class Animal { +// protected: +// string name; +// public: +// Animal(string n) : name(n) {} +// void display() { +// cout << "Animal Name: " << name << endl; +// } +// }; + +// class Dog : public Animal { +// private: +// int age; +// public: +// Dog(string n, int a) : Animal(n), age(a) {} + +// void bark() { +// cout << name << " barks! Age: " << age << endl; +// } +// }; + +// void greet() { +// cout << "Hello from function pointer!\n"; +// } + +// void callFunction(void (*func)()) { +// func(); +// } + +int main() { + // --- Class, Object, Inheritance --- + // Dog d("Buddy", 5); + // d.display(); + // d.bark(); + + // // --- Function Pointer --- + // void (*fp)() = greet; + // callFunction(fp); + + // // --- References --- + // int x = 10; + // int& ref = x; + // ref = 20; + // cout << "Reference value: " << x << endl; + + // --- Multi-level Pointers --- + int y = 50; + int* p1 = &y; + int** p2 = &p1; + int*** p3 = &p2; + printf("Multi-level pointer value: %d\n", ***p3); + + // --- Multi-level Array --- + // int arr[2][3] = { {1,2,3}, {4,5,6} }; + // cout << "Multi-level array element arr[1][2]: " << arr[1][2] << endl; + + return 0; +} + diff --git a/Assignment4/basic.c b/Assignment4/basic.c new file mode 100644 index 0000000..f525779 --- /dev/null +++ b/Assignment4/basic.c @@ -0,0 +1,71 @@ +#include + +int add(int a, int b) { + return a + b; +} + +int factorial(int n) { + if (n <= 1) return 1; + else return n * factorial(n - 1); +} + +int array_sum(int arr[5], int size) { + int sum = 0; + for (int i = 0; i < size; i++) { + sum = sum + arr[i]; + } + return sum; +} + +struct Point { + int x; + int y; +}; + +// float point_sum(struct Point *p) { +// return p->x / p->y; +// } + +int main() { + int a = 5, b = 10; + + int result = add(a, b); + if (result != 15) { + printf("Arithmetic test failed: %d\n", result); + return 1; + } + + int fact = factorial(5); + if (fact != 120) { + printf("Recursion test failed: %d\n", fact); + return 1; + } + + int arr[5] = {1, 2, 3, 4, 5}; + int arr_sum = array_sum(arr, 5); + if (arr_sum != 15) { + printf("Array sum test failed: %d\n", arr_sum); + return 1; + } + + // struct Point p = {3, 4}; + // int p_sum = point_sum(&p); + // if (p_sum != 7) { + // printf("Struct test failed: %d\n", p_sum); + // return 1; + // } + + int value = 0; + if (a < b) { + value = 1; + } else { + value = 2; + } + if (value != 1) { + printf("Branching test failed: %d\n", value); + return 1; + } + + printf("All tests passed successfully!\n"); + return 0; +} diff --git a/Assignment4/funCall.c b/Assignment4/funCall.c new file mode 100644 index 0000000..e61d695 --- /dev/null +++ b/Assignment4/funCall.c @@ -0,0 +1,52 @@ +int add_all(int a1, int a2, int a3, int a4, int a5, int a6, int a7, int a8, int a9, int a10, + int a11, int a12, int a13, int a14, int a15, int a16, int a17, int a18, int a19, int a20, + int a21, int a22, int a23, int a24, int a25, int a26, int a27, int a28, int a29, int a30, + int a31, int a32, int a33, int a34, int a35, int a36, int a37, int a38, int a39, int a40, + int a41, int a42, int a43, int a44, int a45, int a46, int a47, int a48, int a49, int a50, + int a51, int a52, int a53, int a54, int a55, int a56, int a57, int a58, int a59, int a60, + int a61, int a62, int a63, int a64, int a65, int a66, int a67, int a68, int a69, int a70, + int a71, int a72, int a73, int a74, int a75, int a76, int a77, int a78, int a79, int a80, + int a81, int a82, int a83, int a84, int a85, int a86, int a87, int a88, int a89, int a90, + int a91, int a92, int a93, int a94, int a95, int a96, int a97, int a98, int a99, int a100) +{ + return a1 + a2 + a3 + a4 + a5 + a6 + a7 + a8 + a9 + a10 + + a11 + a12 + a13 + a14 + a15 + a16 + a17 + a18 + a19 + a20 + + a21 + a22 + a23 + a24 + a25 + a26 + a27 + a28 + a29 + a30 + + a31 + a32 + a33 + a34 + a35 + a36 + a37 + a38 + a39 + a40 + + a41 + a42 + a43 + a44 + a45 + a46 + a47 + a48 + a49 + a50 + + a51 + a52 + a53 + a54 + a55 + a56 + a57 + a58 + a59 + a60 + + a61 + a62 + a63 + a64 + a65 + a66 + a67 + a68 + a69 + a70 + + a71 + a72 + a73 + a74 + a75 + a76 + a77 + a78 + a79 + a80 + + a81 + a82 + a83 + a84 + a85 + a86 + a87 + a88 + a89 + a90 + + a91 + a92 + a93 + a94 + a95 + a96 + a97 + a98 + a99 + a100; +} + +int main() { + // Declare and initialize 100 variables + int a1 = 10, a2 = 10, a3 = 10, a4 = 10, a5 = 10, a6 = 10, a7 = 10, a8 = 10, a9 = 10, a10 = 10; + int a11 = 10, a12 = 10, a13 = 10, a14 = 10, a15 = 10, a16 = 10, a17 = 10, a18 = 10, a19 = 10, a20 = 10; + int a21 = 10, a22 = 10, a23 = 10, a24 = 10, a25 = 10, a26 = 10, a27 = 10, a28 = 10, a29 = 10, a30 = 10; + int a31 = 10, a32 = 10, a33 = 10, a34 = 10, a35 = 10, a36 = 10, a37 = 10, a38 = 10, a39 = 10, a40 = 10; + int a41 = 10, a42 = 10, a43 = 10, a44 = 10, a45 = 10, a46 = 10, a47 = 10, a48 = 10, a49 = 10, a50 = 10; + int a51 = 10, a52 = 10, a53 = 10, a54 = 10, a55 = 10, a56 = 10, a57 = 10, a58 = 10, a59 = 10, a60 = 10; + int a61 = 10, a62 = 10, a63 = 10, a64 = 10, a65 = 10, a66 = 10, a67 = 10, a68 = 10, a69 = 10, a70 = 10; + int a71 = 10, a72 = 10, a73 = 10, a74 = 10, a75 = 10, a76 = 10, a77 = 10, a78 = 10, a79 = 10, a80 = 10; + int a81 = 10, a82 = 10, a83 = 10, a84 = 10, a85 = 10, a86 = 10, a87 = 10, a88 = 10, a89 = 10, a90 = 10; + int a91 = 10, a92 = 10, a93 = 10, a94 = 10, a95 = 10, a96 = 10, a97 = 10, a98 = 10, a99 = 10, a100 = 10; + + // Call the function with 100 arguments + int sum = add_all(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, + a11, a12, a13, a14, a15, a16, a17, a18, a19, a20, + a21, a22, a23, a24, a25, a26, a27, a28, a29, a30, + a31, a32, a33, a34, a35, a36, a37, a38, a39, a40, + a41, a42, a43, a44, a45, a46, a47, a48, a49, a50, + a51, a52, a53, a54, a55, a56, a57, a58, a59, a60, + a61, a62, a63, a64, a65, a66, a67, a68, a69, a70, + a71, a72, a73, a74, a75, a76, a77, a78, a79, a80, + a81, a82, a83, a84, a85, a86, a87, a88, a89, a90, + a91, a92, a93, a94, a95, a96, a97, a98, a99, a100); + + printf("Sum of all variables = %d\n", sum); + + return 0; +} diff --git a/Assignment4/include/3AC.h b/Assignment4/include/3AC.h new file mode 100644 index 0000000..28a00ee --- /dev/null +++ b/Assignment4/include/3AC.h @@ -0,0 +1,26 @@ +#include +#include +using namespace std; + + +// extern map gotoLabels; + + +int counter=0; +int counter_lab=0; + +qid newtemp(string type,scoped_symtab* curr_scope){ + string temp = "t" + to_string(counter); + counter++; + symbol_info* temp_info = new symbol_info(temp, type); + curr_scope->symbol_map[temp] = temp_info; + qid temp_qid = make_pair(temp, temp_info); + return temp_qid; +} + + +string newlabel(){ + string label = "LABEL" + to_string(counter_lab); + counter_lab++; + return label; +} \ No newline at end of file diff --git a/Assignment4/include/functions.h b/Assignment4/include/functions.h new file mode 100644 index 0000000..687e34c --- /dev/null +++ b/Assignment4/include/functions.h @@ -0,0 +1,453 @@ +#ifndef FUNCTIONS_H +#define FUNCTIONS_H + +#include <3AC.h> + + + +map type_priority = {{"char",1},{"int",2},{"float",3},{"double",4}}; +string priority_to_type[] = {"","char", "int", "float", "double"}; + +//set_pointer_data function +// This function sets the value of a pointer in the symbol_info struct based on the type provided. +void set_pointer_data(symbol_info* sym, std::string type, void* ptr){ + if(sym->ptr == nullptr){ + sym->ptr = malloc(sizeof(sym->type)); + } + if(type == "int"){ + *((int*)(sym->ptr)) = *((int*)ptr); + } + else if(type == "float"){ + *((float*)(sym->ptr)) = *((float*)ptr); + } + else if(type == "string"){ + *((std::string*)(sym->ptr)) = *((std::string*)ptr); + } + else if(type == "char"){ + *((char*)(sym->ptr)) = *((char*)ptr); + } + else if(type == "bool"){ + *((bool*)(sym->ptr)) = *((bool*)ptr); + } + else if(type == "double"){ + *((double*)(sym->ptr)) = *((double*)ptr); + } + else if(type == "long"){ + *((long*)(sym->ptr)) = *((long*)ptr); + } + else if(type == "short"){ + *((short*)(sym->ptr)) = *((short*)ptr); + } + else if(type == "unsigned int"){ + *((unsigned int*)(sym->ptr)) = *((unsigned int*)ptr); + } + else if(type == "unsigned char"){ + *((unsigned char*)(sym->ptr)) = *((unsigned char*)ptr); + } + else if(type == "unsigned long"){ + *((unsigned long*)(sym->ptr)) = *((unsigned long*)ptr); + } + else if(type == "unsigned short"){ + *((unsigned short*)(sym->ptr)) = *((unsigned short*)ptr); + } + else if(type == "unsigned long long"){ + *((unsigned long long*)(sym->ptr)) = *((unsigned long long*)ptr); + } + else if(type == "long long"){ + *((long long*)(sym->ptr)) = *((long long*)ptr); + } + else if(type == "void*"){ + *((void**)(sym->ptr)) = *((void**)ptr); + } + else if(type == "char*"){ + *((char**)(sym->ptr)) = *((char**)ptr); + } + else if(type == "int*"){ + *((int**)(sym->ptr)) = *((int**)ptr); + } + else if(type == "float*"){ + *((float**)(sym->ptr)) = *((float**)ptr); + } + else if(type == "string*"){ + *((std::string**)(sym->ptr)) = *((std::string**)ptr); + } + else if(type == "bool*"){ + *((bool**)(sym->ptr)) = *((bool**)ptr); + } + +} + +void convert_type(symbol_info* &sym, std::string new_type){ + std::string curr_type = sym->type; + if(new_type == "int"){ + if(curr_type == "char"){ + char* temp = (char*)sym->ptr; + int* new_ptr = (int*)malloc(sizeof(int)); + *new_ptr = (int)*temp; + sym->ptr = new_ptr; + sym->type = "int"; + } + } + else if(new_type == "float"){ + if(curr_type == "int"){ + int* temp = (int*)sym->ptr; + float* new_ptr = (float*)malloc(sizeof(float)); + *new_ptr = (float)*temp; + sym->ptr = new_ptr; + sym->type = "float"; + } + else if(curr_type == "char"){ + char* temp = (char*)sym->ptr; + float* new_ptr = (float*)malloc(sizeof(float)); + *new_ptr = (float)*temp; + sym->ptr = new_ptr; + sym->type = "float"; + } + } + else if(new_type == "double"){ + if(curr_type == "int"){ + int* temp = (int*)sym->ptr; + double* new_ptr = (double*)malloc(sizeof(double)); + *new_ptr = (double)*temp; + sym->ptr = new_ptr; + sym->type = "double"; + } + else if(curr_type == "float"){ + float* temp = (float*)sym->ptr; + double* new_ptr = (double*)malloc(sizeof(double)); + *new_ptr = (double)*temp; + sym->ptr = new_ptr; + sym->type = "double"; + } + } +} + +bool isSingleNumber(const string &line) { + for (char ch : line) { + if (!isdigit(ch)) return false; // If any non-digit character is found, return false + } + return !line.empty(); // Ensure it's not an empty string +} +bool startsWithPointerOrAddress(const string& line) { + regex pattern(R"(^(\*\*\w+)|(^\*\w+)|(^&&\w+)|(^&\w+))"); + return regex_search(line, pattern); +} + +// Function to clean Three-Address Code from input file and write to output file +void cleanTAC(string input) { + int lineno=1; + string line=""; + int index=0; + while(index +std::string pointer_to_string(T* ptr) { + std::ostringstream oss; + oss << ptr; // streams the address in hex (e.g. 0x7ffc1234abcd) + return oss.str(); +} +vector> clean_vector_TAC(vector>& input) { + vector> cleaned_TAC; + unordered_set paramVars; // to remember param0, param1, … + + for (auto& entry : input) { + string& line = entry.first; + scoped_symtab* scope = entry.second; + while(line.back() == '\n'){ + line.pop_back(); + } + string address=pointer_to_string(entry.second); + // 2) Skip trivial or empty lines + if (line.empty() || + isSingleNumber(line) || + isSingleFloat(line) || + isSingleStringLiteral(line) || + (startsWithPointerOrAddress(line) && line.find('=') == string::npos)) + { + continue; + } + + // 3) Param logic (handles both ":=" and "=") + auto eqPos = line.find('='); + if (eqPos != string::npos) { + string lhs = trimm(line.substr(0, eqPos-1)); + //cout<<"lhs: " << lhs << endl; + string rhs = trimm(line.substr(eqPos + 1)); + + // normalize leading ":=" if present + if (!rhs.empty() && rhs[0] == ':') { + auto p = rhs.find_first_not_of(":="); + if (p != string::npos) rhs = trimm(rhs.substr(p)); + } + + // 3a) collect & drop param declarations + if (rhs == "PARAM") { + paramVars.insert(lhs); + continue; + } + + // 3b) replace var := paramX → var := PARAM + if (paramVars.count(rhs)) { + cleaned_TAC.emplace_back( + lhs + " := PARAM", + scope + ); + continue; + } + } + + // 4) otherwise, keep the line verbatim (with its address) + cleaned_TAC.emplace_back(line, scope); + } + + return cleaned_TAC; +} + + + +void print_vector(const vector>& vec) { + for (const auto& pair : vec) { + cerr<> replace_break_continue_final(vector> original_code,string end_label,string update_label,int i){ + vector> new_code; + int flag=0; + for(int j=0;j>=") + { + tcode=t1 + ":= " + t1+">>"+t2; + } + else if(op=="&=") + { + tcode=t1 + ":= " + t1+"&"+t2; + } + else if(op=="^=") + { + tcode=t1 + ":= " + t1+"^"+t2; + } + else if(op=="|=") + { + tcode=t1 + ":= " + t1+"|"+t2; + } + else{ + tcode="error"; + } + return tcode; +} +void debug(string s1,string s2) + { + cerr< +#include +#include +#include + +using namespace std; +struct scoped_symtab; +struct symbol_info; + +static symbol_info* lookup_symbol_local(const std::string& name, scoped_symtab* curr_scope); +static symbol_info* lookup_symbol_global(const std::string& name, scoped_symtab* curr_scope); +extern vector> cleaned_TAC; + +struct scoped_symtab{ + scoped_symtab* parent = nullptr; + std::map symbol_map; + std::vector child_list; + + scoped_symtab(scoped_symtab* parent = nullptr){ + this->parent = parent; + } +}; + +typedef std::pair qid; + +typedef struct quadruple{ + qid op; + qid arg1; + qid arg2; + qid res; + int idx; +} quad; + +struct symbol_info { + std::string name; + std::string type; // Use std::string instead of char* for safety + void* ptr = nullptr; // Pointer to hold int* or float* + int symbol_size=0; + std::string str_val; + bool is_array = false; + int array_length = 0; + std::vector int_array; + bool is_param_list=false; + int parameter_no=0; + std::vector param_types; + std::vector param_list; + std::vector struct_attr_values; + int pointer_depth=0; + qid place; + std::vector> final_code; + std::string code; + + bool is_return=false; + std::string return_type=""; + bool is_array_access=false; + bool is_continue=false; + bool is_break=false; + int offset=-1; + + symbol_info(std::string name="", std::string type="", void* ptr=nullptr, int symbol_size=0, bool is_array=false, int array_length=0, std::vector int_array={},bool is_param_list=false,std::vector param_types={},std::vector param_list={},int parameter_no=0,int pointer_depth=0, qid place = {"", nullptr}, std::string code = "", + std::vector struct_attr_values = {}, int offset=-1) + : name(name), type(type), ptr(ptr), symbol_size(symbol_size){} + + symbol_info(symbol_info* sym) + : name(sym->name), type(sym->type), ptr(sym->ptr), symbol_size(sym->symbol_size), + is_array(sym->is_array), array_length(sym->array_length), int_array(sym->int_array), + is_param_list(sym->is_param_list), parameter_no(sym->parameter_no), + param_types(sym->param_types), param_list(sym->param_list), + struct_attr_values(sym->struct_attr_values), pointer_depth(sym->pointer_depth), + place(sym->place), code(sym->code), offset(sym->offset) { + // Copy the final_code vector + for (const auto& item : sym->final_code) { + final_code.push_back(item); + } + } +}; + + symbol_info* lookup_symbol_local(const std::string& name, scoped_symtab* curr_scope){ + auto ptr = curr_scope->symbol_map.find(name); + if (ptr != curr_scope->symbol_map.end()) { + return ptr->second; + } + return nullptr; + } + + symbol_info* lookup_symbol_global(const std::string& name, scoped_symtab* curr_scope){ + scoped_symtab* scope = curr_scope; + while (scope != nullptr) { + if(scope->symbol_map.find(name) != scope->symbol_map.end()){ + return scope->symbol_map[name]; + } + scope = scope->parent; + } + return nullptr; + } + + + #endif // SYMBOL_TABLE_H + \ No newline at end of file diff --git a/Assignment4/mix.cpp b/Assignment4/mix.cpp new file mode 100644 index 0000000..f978f15 --- /dev/null +++ b/Assignment4/mix.cpp @@ -0,0 +1,97 @@ +#include +#include // For var args +#include // For malloc and free +#include // For file manipulation +#include +using namespace std; + +// Typedef for a pointer to int +typedef int* IntPtr; + +// Enum for colors +enum Color { RED, GREEN, BLUE }; + +// Union for different data types +union Data { + int intValue; + float floatValue; + char charValue; +}; + +// Function with variable arguments +int sum(int count, ...) { + va_list args; + va_start(args, count); + + int total = 0; + for (int i = 0; i < count; i++) { + total += va_arg(args, int); + } + + va_end(args); + return total; +} + +int main(int argc, char* argv[]) { + // --- Command line input --- + if (argc < 2) { + cout << "Usage: " << argv[0] << " \n"; + return 1; + } + char filename[100]; + strncpy(filename, argv[1], 99); // copy filename to char array + filename[99] = '\0'; // ensure null termination + + // --- Dynamic memory allocation --- + IntPtr p = (IntPtr) malloc(5 * sizeof(int)); // using typedef for int* + if (!p) { + cout << "Memory allocation failed!\n"; + return 1; + } + for (int i = 0; i < 5; i++) { + p[i] = i * 10; + } + + cout << "Dynamically allocated array:\n"; + for (int i = 0; i < 5; i++) { + cout << p[i] << " "; + } + cout << endl; + + free(p); // free dynamically allocated memory + + // --- Enum --- + Color favorite = GREEN; + if (favorite == GREEN) { + cout << "Favorite color is GREEN\n"; + } + + // --- Union --- + Data d; + d.intValue = 100; + cout << "Union int value: " << d.intValue << endl; + d.floatValue = 3.14f; + cout << "Union float value: " << d.floatValue << endl; + d.charValue = 'A'; + cout << "Union char value: " << d.charValue << endl; + // Note: Union only holds one value at a time! + + // --- Var args --- + int total = sum(4, 10, 20, 30, 40); + cout << "Sum using var args: " << total << endl; + + // --- File manipulation --- + ofstream outfile(filename); + if (!outfile) { + cout << "Failed to open file for writing.\n"; + return 1; + } + outfile << "Hello from C++ program!\n"; + outfile << "Sum was: " << total << endl; + outfile.close(); + + cout << "Data written to file: " << filename << endl; + + return 0; +} + diff --git a/Assignment4/output/output1.s b/Assignment4/output/output1.s new file mode 100644 index 0000000..6bf037a --- /dev/null +++ b/Assignment4/output/output1.s @@ -0,0 +1,390 @@ +# =====================LIST OF ERRORS=================================== +#Line 11 : Missing return statement +# ====================================================================== +.data +newline: .asciiz "\n" +str0: .asciiz "Arithmetic test failed:" +str1: .asciiz "Recursion test failed:" +str2: .asciiz "Array sum test failed:" +str3: .asciiz "Branching test failed:" +str4: .asciiz "All tests passed successfully!\n" +.text +.globl main +addx: + move $fp, $sp + addi $sp, $sp, -60 + sw $ra, 56($sp) + sw $fp, 52($sp) + sw $t0, 48($sp) + sw $t1, 44($sp) + sw $t2, 40($sp) + sw $t3, 36($sp) + sw $t4, 32($sp) + sw $t5, 28($sp) + sw $t6, 24($sp) + sw $t7, 20($sp) + sw $t8, 16($sp) + sw $t9, 12($sp) + move $t9, $a0 + move $t8, $a1 + add $t7, $t9, $t8 + move $v0, $t7 + lw $fp, 52($sp) + lw $ra, 56($sp) + lw $t0, 48($sp) + lw $t1, 44($sp) + lw $t2, 40($sp) + lw $t3, 36($sp) + lw $t4, 32($sp) + lw $t5, 28($sp) + lw $t6, 24($sp) + lw $t7, 20($sp) + lw $t8, 16($sp) + lw $t9, 12($sp) + addi $sp, $sp, 60 + jr $ra +factorial: + move $fp, $sp + addi $sp, $sp, -68 + sw $ra, 64($sp) + sw $fp, 60($sp) + sw $t0, 56($sp) + sw $t1, 52($sp) + sw $t2, 48($sp) + sw $t3, 44($sp) + sw $t4, 40($sp) + sw $t5, 36($sp) + sw $t6, 32($sp) + sw $t7, 28($sp) + sw $t8, 24($sp) + sw $t9, 20($sp) + move $t6, $a0 + li $t5, 1 + slt $t4, $t5, $t6 + xori $t4, $t4, 1 + bnez $t4, LABEL0 + j LABEL1 +LABEL0: + li $v0, 1 + lw $fp, 60($sp) + lw $ra, 64($sp) + lw $t0, 56($sp) + lw $t1, 52($sp) + lw $t2, 48($sp) + lw $t3, 44($sp) + lw $t4, 40($sp) + lw $t5, 36($sp) + lw $t6, 32($sp) + lw $t7, 28($sp) + lw $t8, 24($sp) + lw $t9, 20($sp) + addi $sp, $sp, 68 + jr $ra + j LABEL2 +LABEL1: + li $t3, 1 + sub $t2, $t6, $t3 + move $a0, $t2 + jal factorial + move $t1, $v0 + mul $t0, $t6, $t1 + move $v0, $t0 + lw $fp, 60($sp) + lw $ra, 64($sp) + lw $t0, 56($sp) + lw $t1, 52($sp) + lw $t2, 48($sp) + lw $t3, 44($sp) + lw $t4, 40($sp) + lw $t5, 36($sp) + lw $t6, 32($sp) + lw $t7, 28($sp) + lw $t8, 24($sp) + lw $t9, 20($sp) + addi $sp, $sp, 68 + jr $ra +LABEL2: +main: + move $fp, $sp + addi $sp, $sp, -124 + sw $ra, 120($sp) + sw $fp, 116($sp) + # Spilling a from $t9 + li $t9, 5 + # Spilling b from $t8 + li $t8, 10 + move $a0, $t9 + move $a1, $t8 + # Spilling t0 from $t7 + jal addx + move $t7, $v0 + # Spilling n from $t6 + move $t6, $t7 + # Spilling t1 from $t4 + li $t4, 15 + # Spilling t2 from $t2 + sne $t2, $t6, $t4 + bnez $t2, LABEL3 + j LABEL4 +LABEL3: + la $a0, str0 + move $a1, $t6 + # Spilling t3 from $t1 +#printf + move $a0, $a0 + li $v0, 4 +syscall + li $v0, 4 + la $a0, newline + syscall + move $a0, $a1 + li $v0, 1 +syscall + li $v0, 4 + la $a0, newline + syscall + move $t1, $v0 + li $v0, 1 + lw $fp, 116($sp) + lw $ra, 120($sp) +LABEL4: + li $a0, 5 + # Spilling t4 from $t0 + jal factorial + move $t0, $v0 + # Spilling result from $t6 + move $t6, $t0 + # Spilling t5 from $t7 + li $t7, 120 + # Spilling t6 from $t2 + sne $t2, $t6, $t7 + bnez $t2, LABEL5 + j LABEL6 +LABEL5: + la $a0, str1 + move $a1, $t6 + # Spilling t8 from $t0 +#printf + move $a0, $a0 + li $v0, 4 +syscall + li $v0, 4 + la $a0, newline + syscall + move $a0, $a1 + li $v0, 1 +syscall + li $v0, 4 + la $a0, newline + syscall + move $t0, $v0 + li $v0, 1 + lw $fp, 116($sp) + lw $ra, 120($sp) +LABEL6: + # Spilling fact from $t6 + li $t6, 0 + # Spilling t9 from $t2 + li $t2, 4 + # Spilling t7 from $t1 + mul $t1, $t6, $t2 + # Spilling t10 from $t0 + li $t0, 1 + addi $t1, $t1, 0 + add $t1, $t1, $sp + sw $t0, 0($t1) + # Spilling t11 from $t1 + li $t1, 1 + #Pushing a to stack + sw $t9, 20($sp) + li $t9, 4 + #Pushing b to stack + sw $t8, 24($sp) + mul $t8, $t1, $t9 + li $t0, 2 + addi $t8, $t8, 0 + add $t8, $t8, $sp + sw $t0, 0($t8) + # Spilling t12 from $t8 + li $t8, 2 + li $t0, 4 + mul $t0, $t8, $t0 + #Pushing t13 to stack + sw $t0, 28($sp) + li $t0, 3 + lw $t0, 28($sp) + addi $t0, $t0, 0 + add $t0, $t0, $sp + sw $t0, 0($t0) + # Spilling t13 from $t0 + li $t0, 3 + li $t0, 4 + mul $t0, $t0, $t0 + #Pushing t14 to stack + sw $t0, 32($sp) + li $t0, 4 + lw $t0, 32($sp) + addi $t0, $t0, 0 + add $t0, $t0, $sp + sw $t0, 0($t0) + # Spilling t14 from $t0 + li $t0, 4 + li $t0, 4 + mul $t0, $t0, $t0 + #Pushing t15 to stack + sw $t0, 36($sp) + li $t0, 5 + lw $t0, 36($sp) + addi $t0, $t0, 0 + add $t0, $t0, $sp + sw $t0, 0($t0) + # Spilling t15 from $t0 + li $t0, 0 + #Pushing array_sum to stack + sw $t0, 40($sp) + li $t0, 0 + li $t0, 0 +LABEL7: + #Pushing i to stack + sw $t0, 44($sp) + li $t0, 5 + slt $t0, $t0, $t0 + bnez $t0, LABEL9 + j LABEL8 +LABEL9: + # Spilling t16 from $t0 + li $t0, 4 + lw $t0, 44($sp) + #Pushing i to stack + sw $t0, 44($sp) + mul $t0, $t0, $t0 + addi $t0, $t0, 0 + add $t0, $t0, $sp + #Pushing t17 to stack + sw $t0, 48($sp) + lw $t0, 0($t0) + #Pushing t18 to stack + sw $t0, 52($sp) + lw $t0, 40($sp) + #Pushing array_sum to stack + sw $t0, 40($sp) + lw $t0, 52($sp) + #Pushing t18 to stack + sw $t0, 52($sp) + add $t0, $t0, $t0 + #Pushing t19 to stack + sw $t0, 56($sp) + lw $t0, 40($sp) + #Pushing array_sum to stack + sw $t0, 40($sp) + lw $t0, 56($sp) + move $t0, $t0 + # Spilling t19 from $t0 + lw $t0, 44($sp) + #Pushing i to stack + sw $t0, 44($sp) + li $t0, 1 + lw $t0, 44($sp) + add $t0, $t0, $t0 + j LABEL7 +LABEL8: + # Spilling i from $t0 + lw $t0, 40($sp) + #Pushing array_sum to stack + sw $t0, 40($sp) + li $t0, 15 + sne $t0, $t0, $t0 + bnez $t0, LABEL11 + j LABEL12 +LABEL11: + la $a0, str2 + # Spilling t20 from $t0 + lw $t0, 40($sp) + move $a1, $t0 + #Pushing array_sum to stack + sw $t0, 40($sp) +#printf + move $a0, $a0 + li $v0, 4 +syscall + li $v0, 4 + la $a0, newline + syscall + move $a0, $a1 + li $v0, 1 +syscall + li $v0, 4 + la $a0, newline + syscall + move $t0, $v0 + li $v0, 1 + lw $fp, 116($sp) + lw $ra, 120($sp) +LABEL12: + # Spilling t21 from $t0 + li $t0, 0 + #Pushing value to stack + sw $t0, 60($sp) + lw $t0, 20($sp) + #Pushing a to stack + sw $t0, 20($sp) + lw $t0, 24($sp) + #Pushing b to stack + sw $t0, 24($sp) + slt $t0, $t0, $t0 + bnez $t0, LABEL13 + j LABEL14 +LABEL13: + # Spilling t22 from $t0 + lw $t0, 60($sp) + li $t0, 1 + j LABEL15 +LABEL14: + li $t0, 2 +LABEL15: + #Pushing value to stack + sw $t0, 60($sp) + li $t0, 1 + sne $t0, $t0, $t0 + bnez $t0, LABEL16 + j LABEL17 +LABEL16: + la $a0, str3 + # Spilling t23 from $t0 + lw $t0, 60($sp) + move $a1, $t0 + #Pushing value to stack + sw $t0, 60($sp) +#printf + move $a0, $a0 + li $v0, 4 +syscall + li $v0, 4 + la $a0, newline + syscall + move $a0, $a1 + li $v0, 1 +syscall + li $v0, 4 + la $a0, newline + syscall + move $t0, $v0 + li $v0, 1 + lw $fp, 116($sp) + lw $ra, 120($sp) +LABEL17: + la $a0, str4 + # Spilling t24 from $t0 +#printf + move $a0, $a0 + li $v0, 4 +syscall + li $v0, 4 + la $a0, newline + syscall + move $t0, $v0 + li $v0, 0 + lw $fp, 116($sp) + lw $ra, 120($sp) + li $v0, 10 + syscall diff --git a/Assignment4/output/output2.s b/Assignment4/output/output2.s new file mode 100644 index 0000000..ad12f00 --- /dev/null +++ b/Assignment4/output/output2.s @@ -0,0 +1,1781 @@ +# ====================================================================== +# No Errors in the code +# Intermediate code generated successfully +# ====================================================================== +.data +newline: .asciiz "\n" +str0: .asciiz "Sum of all variables =" +.text +.globl main +add_all: + move $fp, $sp + addi $sp, $sp, -844 + sw $ra, 840($sp) + sw $fp, 836($sp) + sw $t0, 832($sp) + sw $t1, 828($sp) + sw $t2, 824($sp) + sw $t3, 820($sp) + sw $t4, 816($sp) + sw $t5, 812($sp) + sw $t6, 808($sp) + sw $t7, 804($sp) + sw $t8, 800($sp) + sw $t9, 796($sp) + move $t9, $a0 + move $t8, $a1 + move $t7, $a2 + move $t6, $a3 + #popping from stack to $t5 + lw $t5, 0($fp) + #pushing into function stack + sw $t5, 0($sp) + #popping from stack to $t4 + lw $t4, 4($fp) + #pushing into function stack + sw $t4, 4($sp) + #popping from stack to $t3 + lw $t3, 8($fp) + #pushing into function stack + sw $t3, 8($sp) + #popping from stack to $t2 + lw $t2, 12($fp) + #pushing into function stack + sw $t2, 12($sp) + #popping from stack to $t1 + lw $t1, 16($fp) + #pushing into function stack + sw $t1, 16($sp) + #popping from stack to $t0 + lw $t0, 20($fp) + #pushing into function stack + sw $t0, 20($sp) + #Pushing a10 to stack + sw $t0, 20($sp) + #popping from stack to $t0 + lw $t0, 24($fp) + #pushing into function stack + sw $t0, 24($sp) + #Pushing a11 to stack + sw $t0, 24($sp) + #popping from stack to $t0 + lw $t0, 28($fp) + #pushing into function stack + sw $t0, 28($sp) + #Pushing a12 to stack + sw $t0, 28($sp) + #popping from stack to $t0 + lw $t0, 32($fp) + #pushing into function stack + sw $t0, 32($sp) + #Pushing a13 to stack + sw $t0, 32($sp) + #popping from stack to $t0 + lw $t0, 36($fp) + #pushing into function stack + sw $t0, 36($sp) + #Pushing a14 to stack + sw $t0, 36($sp) + #popping from stack to $t0 + lw $t0, 40($fp) + #pushing into function stack + sw $t0, 40($sp) + #Pushing a15 to stack + sw $t0, 40($sp) + #popping from stack to $t0 + lw $t0, 44($fp) + #pushing into function stack + sw $t0, 44($sp) + #Pushing a16 to stack + sw $t0, 44($sp) + #popping from stack to $t0 + lw $t0, 48($fp) + #pushing into function stack + sw $t0, 48($sp) + #Pushing a17 to stack + sw $t0, 48($sp) + #popping from stack to $t0 + lw $t0, 52($fp) + #pushing into function stack + sw $t0, 52($sp) + #Pushing a18 to stack + sw $t0, 52($sp) + #popping from stack to $t0 + lw $t0, 56($fp) + #pushing into function stack + sw $t0, 56($sp) + #Pushing a19 to stack + sw $t0, 56($sp) + #popping from stack to $t0 + lw $t0, 60($fp) + #pushing into function stack + sw $t0, 60($sp) + #Pushing a20 to stack + sw $t0, 60($sp) + #popping from stack to $t0 + lw $t0, 64($fp) + #pushing into function stack + sw $t0, 64($sp) + #Pushing a21 to stack + sw $t0, 64($sp) + #popping from stack to $t0 + lw $t0, 68($fp) + #pushing into function stack + sw $t0, 68($sp) + #Pushing a22 to stack + sw $t0, 68($sp) + #popping from stack to $t0 + lw $t0, 72($fp) + #pushing into function stack + sw $t0, 72($sp) + #Pushing a23 to stack + sw $t0, 72($sp) + #popping from stack to $t0 + lw $t0, 76($fp) + #pushing into function stack + sw $t0, 76($sp) + #Pushing a24 to stack + sw $t0, 76($sp) + #popping from stack to $t0 + lw $t0, 80($fp) + #pushing into function stack + sw $t0, 80($sp) + #Pushing a25 to stack + sw $t0, 80($sp) + #popping from stack to $t0 + lw $t0, 84($fp) + #pushing into function stack + sw $t0, 84($sp) + #Pushing a26 to stack + sw $t0, 84($sp) + #popping from stack to $t0 + lw $t0, 88($fp) + #pushing into function stack + sw $t0, 88($sp) + #Pushing a27 to stack + sw $t0, 88($sp) + #popping from stack to $t0 + lw $t0, 92($fp) + #pushing into function stack + sw $t0, 92($sp) + #Pushing a28 to stack + sw $t0, 92($sp) + #popping from stack to $t0 + lw $t0, 96($fp) + #pushing into function stack + sw $t0, 96($sp) + #Pushing a29 to stack + sw $t0, 96($sp) + #popping from stack to $t0 + lw $t0, 100($fp) + #pushing into function stack + sw $t0, 100($sp) + #Pushing a30 to stack + sw $t0, 100($sp) + #popping from stack to $t0 + lw $t0, 104($fp) + #pushing into function stack + sw $t0, 104($sp) + #Pushing a31 to stack + sw $t0, 104($sp) + #popping from stack to $t0 + lw $t0, 108($fp) + #pushing into function stack + sw $t0, 108($sp) + #Pushing a32 to stack + sw $t0, 108($sp) + #popping from stack to $t0 + lw $t0, 112($fp) + #pushing into function stack + sw $t0, 112($sp) + #Pushing a33 to stack + sw $t0, 112($sp) + #popping from stack to $t0 + lw $t0, 116($fp) + #pushing into function stack + sw $t0, 116($sp) + #Pushing a34 to stack + sw $t0, 116($sp) + #popping from stack to $t0 + lw $t0, 120($fp) + #pushing into function stack + sw $t0, 120($sp) + #Pushing a35 to stack + sw $t0, 120($sp) + #popping from stack to $t0 + lw $t0, 124($fp) + #pushing into function stack + sw $t0, 124($sp) + #Pushing a36 to stack + sw $t0, 124($sp) + #popping from stack to $t0 + lw $t0, 128($fp) + #pushing into function stack + sw $t0, 128($sp) + #Pushing a37 to stack + sw $t0, 128($sp) + #popping from stack to $t0 + lw $t0, 132($fp) + #pushing into function stack + sw $t0, 132($sp) + #Pushing a38 to stack + sw $t0, 132($sp) + #popping from stack to $t0 + lw $t0, 136($fp) + #pushing into function stack + sw $t0, 136($sp) + #Pushing a39 to stack + sw $t0, 136($sp) + #popping from stack to $t0 + lw $t0, 140($fp) + #pushing into function stack + sw $t0, 140($sp) + #Pushing a40 to stack + sw $t0, 140($sp) + #popping from stack to $t0 + lw $t0, 144($fp) + #pushing into function stack + sw $t0, 144($sp) + #Pushing a41 to stack + sw $t0, 144($sp) + #popping from stack to $t0 + lw $t0, 148($fp) + #pushing into function stack + sw $t0, 148($sp) + #Pushing a42 to stack + sw $t0, 148($sp) + #popping from stack to $t0 + lw $t0, 152($fp) + #pushing into function stack + sw $t0, 152($sp) + #Pushing a43 to stack + sw $t0, 152($sp) + #popping from stack to $t0 + lw $t0, 156($fp) + #pushing into function stack + sw $t0, 156($sp) + #Pushing a44 to stack + sw $t0, 156($sp) + #popping from stack to $t0 + lw $t0, 160($fp) + #pushing into function stack + sw $t0, 160($sp) + #Pushing a45 to stack + sw $t0, 160($sp) + #popping from stack to $t0 + lw $t0, 164($fp) + #pushing into function stack + sw $t0, 164($sp) + #Pushing a46 to stack + sw $t0, 164($sp) + #popping from stack to $t0 + lw $t0, 168($fp) + #pushing into function stack + sw $t0, 168($sp) + #Pushing a47 to stack + sw $t0, 168($sp) + #popping from stack to $t0 + lw $t0, 172($fp) + #pushing into function stack + sw $t0, 172($sp) + #Pushing a48 to stack + sw $t0, 172($sp) + #popping from stack to $t0 + lw $t0, 176($fp) + #pushing into function stack + sw $t0, 176($sp) + #Pushing a49 to stack + sw $t0, 176($sp) + #popping from stack to $t0 + lw $t0, 180($fp) + #pushing into function stack + sw $t0, 180($sp) + #Pushing a50 to stack + sw $t0, 180($sp) + #popping from stack to $t0 + lw $t0, 184($fp) + #pushing into function stack + sw $t0, 184($sp) + #Pushing a51 to stack + sw $t0, 184($sp) + #popping from stack to $t0 + lw $t0, 188($fp) + #pushing into function stack + sw $t0, 188($sp) + #Pushing a52 to stack + sw $t0, 188($sp) + #popping from stack to $t0 + lw $t0, 192($fp) + #pushing into function stack + sw $t0, 192($sp) + #Pushing a53 to stack + sw $t0, 192($sp) + #popping from stack to $t0 + lw $t0, 196($fp) + #pushing into function stack + sw $t0, 196($sp) + #Pushing a54 to stack + sw $t0, 196($sp) + #popping from stack to $t0 + lw $t0, 200($fp) + #pushing into function stack + sw $t0, 200($sp) + #Pushing a55 to stack + sw $t0, 200($sp) + #popping from stack to $t0 + lw $t0, 204($fp) + #pushing into function stack + sw $t0, 204($sp) + #Pushing a56 to stack + sw $t0, 204($sp) + #popping from stack to $t0 + lw $t0, 208($fp) + #pushing into function stack + sw $t0, 208($sp) + #Pushing a57 to stack + sw $t0, 208($sp) + #popping from stack to $t0 + lw $t0, 212($fp) + #pushing into function stack + sw $t0, 212($sp) + #Pushing a58 to stack + sw $t0, 212($sp) + #popping from stack to $t0 + lw $t0, 216($fp) + #pushing into function stack + sw $t0, 216($sp) + #Pushing a59 to stack + sw $t0, 216($sp) + #popping from stack to $t0 + lw $t0, 220($fp) + #pushing into function stack + sw $t0, 220($sp) + #Pushing a60 to stack + sw $t0, 220($sp) + #popping from stack to $t0 + lw $t0, 224($fp) + #pushing into function stack + sw $t0, 224($sp) + #Pushing a61 to stack + sw $t0, 224($sp) + #popping from stack to $t0 + lw $t0, 228($fp) + #pushing into function stack + sw $t0, 228($sp) + #Pushing a62 to stack + sw $t0, 228($sp) + #popping from stack to $t0 + lw $t0, 232($fp) + #pushing into function stack + sw $t0, 232($sp) + #Pushing a63 to stack + sw $t0, 232($sp) + #popping from stack to $t0 + lw $t0, 236($fp) + #pushing into function stack + sw $t0, 236($sp) + #Pushing a64 to stack + sw $t0, 236($sp) + #popping from stack to $t0 + lw $t0, 240($fp) + #pushing into function stack + sw $t0, 240($sp) + #Pushing a65 to stack + sw $t0, 240($sp) + #popping from stack to $t0 + lw $t0, 244($fp) + #pushing into function stack + sw $t0, 244($sp) + #Pushing a66 to stack + sw $t0, 244($sp) + #popping from stack to $t0 + lw $t0, 248($fp) + #pushing into function stack + sw $t0, 248($sp) + #Pushing a67 to stack + sw $t0, 248($sp) + #popping from stack to $t0 + lw $t0, 252($fp) + #pushing into function stack + sw $t0, 252($sp) + #Pushing a68 to stack + sw $t0, 252($sp) + #popping from stack to $t0 + lw $t0, 256($fp) + #pushing into function stack + sw $t0, 256($sp) + #Pushing a69 to stack + sw $t0, 256($sp) + #popping from stack to $t0 + lw $t0, 260($fp) + #pushing into function stack + sw $t0, 260($sp) + #Pushing a70 to stack + sw $t0, 260($sp) + #popping from stack to $t0 + lw $t0, 264($fp) + #pushing into function stack + sw $t0, 264($sp) + #Pushing a71 to stack + sw $t0, 264($sp) + #popping from stack to $t0 + lw $t0, 268($fp) + #pushing into function stack + sw $t0, 268($sp) + #Pushing a72 to stack + sw $t0, 268($sp) + #popping from stack to $t0 + lw $t0, 272($fp) + #pushing into function stack + sw $t0, 272($sp) + #Pushing a73 to stack + sw $t0, 272($sp) + #popping from stack to $t0 + lw $t0, 276($fp) + #pushing into function stack + sw $t0, 276($sp) + #Pushing a74 to stack + sw $t0, 276($sp) + #popping from stack to $t0 + lw $t0, 280($fp) + #pushing into function stack + sw $t0, 280($sp) + #Pushing a75 to stack + sw $t0, 280($sp) + #popping from stack to $t0 + lw $t0, 284($fp) + #pushing into function stack + sw $t0, 284($sp) + #Pushing a76 to stack + sw $t0, 284($sp) + #popping from stack to $t0 + lw $t0, 288($fp) + #pushing into function stack + sw $t0, 288($sp) + #Pushing a77 to stack + sw $t0, 288($sp) + #popping from stack to $t0 + lw $t0, 292($fp) + #pushing into function stack + sw $t0, 292($sp) + #Pushing a78 to stack + sw $t0, 292($sp) + #popping from stack to $t0 + lw $t0, 296($fp) + #pushing into function stack + sw $t0, 296($sp) + #Pushing a79 to stack + sw $t0, 296($sp) + #popping from stack to $t0 + lw $t0, 300($fp) + #pushing into function stack + sw $t0, 300($sp) + #Pushing a80 to stack + sw $t0, 300($sp) + #popping from stack to $t0 + lw $t0, 304($fp) + #pushing into function stack + sw $t0, 304($sp) + #Pushing a81 to stack + sw $t0, 304($sp) + #popping from stack to $t0 + lw $t0, 308($fp) + #pushing into function stack + sw $t0, 308($sp) + #Pushing a82 to stack + sw $t0, 308($sp) + #popping from stack to $t0 + lw $t0, 312($fp) + #pushing into function stack + sw $t0, 312($sp) + #Pushing a83 to stack + sw $t0, 312($sp) + #popping from stack to $t0 + lw $t0, 316($fp) + #pushing into function stack + sw $t0, 316($sp) + #Pushing a84 to stack + sw $t0, 316($sp) + #popping from stack to $t0 + lw $t0, 320($fp) + #pushing into function stack + sw $t0, 320($sp) + #Pushing a85 to stack + sw $t0, 320($sp) + #popping from stack to $t0 + lw $t0, 324($fp) + #pushing into function stack + sw $t0, 324($sp) + #Pushing a86 to stack + sw $t0, 324($sp) + #popping from stack to $t0 + lw $t0, 328($fp) + #pushing into function stack + sw $t0, 328($sp) + #Pushing a87 to stack + sw $t0, 328($sp) + #popping from stack to $t0 + lw $t0, 332($fp) + #pushing into function stack + sw $t0, 332($sp) + #Pushing a88 to stack + sw $t0, 332($sp) + #popping from stack to $t0 + lw $t0, 336($fp) + #pushing into function stack + sw $t0, 336($sp) + #Pushing a89 to stack + sw $t0, 336($sp) + #popping from stack to $t0 + lw $t0, 340($fp) + #pushing into function stack + sw $t0, 340($sp) + #Pushing a90 to stack + sw $t0, 340($sp) + #popping from stack to $t0 + lw $t0, 344($fp) + #pushing into function stack + sw $t0, 344($sp) + #Pushing a91 to stack + sw $t0, 344($sp) + #popping from stack to $t0 + lw $t0, 348($fp) + #pushing into function stack + sw $t0, 348($sp) + #Pushing a92 to stack + sw $t0, 348($sp) + #popping from stack to $t0 + lw $t0, 352($fp) + #pushing into function stack + sw $t0, 352($sp) + #Pushing a93 to stack + sw $t0, 352($sp) + #popping from stack to $t0 + lw $t0, 356($fp) + #pushing into function stack + sw $t0, 356($sp) + #Pushing a94 to stack + sw $t0, 356($sp) + #popping from stack to $t0 + lw $t0, 360($fp) + #pushing into function stack + sw $t0, 360($sp) + #Pushing a95 to stack + sw $t0, 360($sp) + #popping from stack to $t0 + lw $t0, 364($fp) + #pushing into function stack + sw $t0, 364($sp) + #Pushing a96 to stack + sw $t0, 364($sp) + #popping from stack to $t0 + lw $t0, 368($fp) + #pushing into function stack + sw $t0, 368($sp) + #Pushing a97 to stack + sw $t0, 368($sp) + #popping from stack to $t0 + lw $t0, 372($fp) + #pushing into function stack + sw $t0, 372($sp) + #Pushing a98 to stack + sw $t0, 372($sp) + #popping from stack to $t0 + lw $t0, 376($fp) + #pushing into function stack + sw $t0, 376($sp) + #Pushing a99 to stack + sw $t0, 376($sp) + #popping from stack to $t0 + lw $t0, 380($fp) + #pushing into function stack + sw $t0, 380($sp) + #Pushing a100 to stack + sw $t0, 380($sp) + add $t0, $t9, $t8 + # Spilling a1 from $t9 + add $t9, $t0, $t7 + # Spilling a2 from $t8 + add $t8, $t9, $t6 + # Spilling a3 from $t7 + add $t7, $t8, $t5 + # Spilling a4 from $t6 + add $t6, $t7, $t4 + # Spilling a5 from $t5 + add $t5, $t6, $t3 + # Spilling a6 from $t4 + add $t4, $t5, $t2 + # Spilling a7 from $t3 + add $t3, $t4, $t1 + # Spilling a8 from $t2 + lw $t2, 20($sp) + # Spilling a9 from $t1 + add $t1, $t3, $t2 + # Spilling a10 from $t2 + lw $t2, 24($sp) + # Spilling t0 from $t0 + add $t0, $t1, $t2 + # Spilling a11 from $t2 + lw $t2, 28($sp) + # Spilling t1 from $t9 + add $t9, $t0, $t2 + # Spilling a12 from $t2 + lw $t2, 32($sp) + # Spilling t2 from $t8 + add $t8, $t9, $t2 + # Spilling a13 from $t2 + lw $t2, 36($sp) + # Spilling t10 from $t9 + add $t9, $t8, $t2 + # Spilling a14 from $t2 + lw $t2, 40($sp) + # Spilling t11 from $t8 + add $t8, $t9, $t2 + # Spilling a15 from $t2 + lw $t2, 44($sp) + # Spilling t12 from $t9 + add $t9, $t8, $t2 + # Spilling a16 from $t2 + lw $t2, 48($sp) + # Spilling t13 from $t8 + add $t8, $t9, $t2 + # Spilling a17 from $t2 + lw $t2, 52($sp) + # Spilling t14 from $t9 + add $t9, $t8, $t2 + # Spilling a18 from $t2 + lw $t2, 56($sp) + # Spilling t15 from $t8 + add $t8, $t9, $t2 + # Spilling a19 from $t2 + lw $t2, 60($sp) + # Spilling t16 from $t9 + add $t9, $t8, $t2 + # Spilling a20 from $t2 + lw $t2, 64($sp) + # Spilling t17 from $t8 + add $t8, $t9, $t2 + # Spilling a21 from $t2 + lw $t2, 68($sp) + # Spilling t18 from $t9 + add $t9, $t8, $t2 + # Spilling a22 from $t2 + lw $t2, 72($sp) + # Spilling t19 from $t8 + add $t8, $t9, $t2 + # Spilling a23 from $t2 + lw $t2, 76($sp) + # Spilling t20 from $t9 + add $t9, $t8, $t2 + # Spilling a24 from $t2 + lw $t2, 80($sp) + # Spilling t21 from $t8 + add $t8, $t9, $t2 + # Spilling a25 from $t2 + lw $t2, 84($sp) + # Spilling t22 from $t9 + add $t9, $t8, $t2 + # Spilling a26 from $t2 + lw $t2, 88($sp) + # Spilling t23 from $t8 + add $t8, $t9, $t2 + # Spilling a27 from $t2 + lw $t2, 92($sp) + # Spilling t24 from $t9 + add $t9, $t8, $t2 + # Spilling a28 from $t2 + lw $t2, 96($sp) + # Spilling t25 from $t8 + add $t8, $t9, $t2 + # Spilling a29 from $t2 + lw $t2, 100($sp) + # Spilling t26 from $t9 + add $t9, $t8, $t2 + # Spilling a30 from $t2 + lw $t2, 104($sp) + # Spilling t27 from $t8 + add $t8, $t9, $t2 + # Spilling a31 from $t2 + lw $t2, 108($sp) + # Spilling t28 from $t9 + add $t9, $t8, $t2 + # Spilling a32 from $t2 + lw $t2, 112($sp) + # Spilling t29 from $t8 + add $t8, $t9, $t2 + # Spilling a33 from $t2 + lw $t2, 116($sp) + # Spilling t3 from $t7 + add $t7, $t8, $t2 + # Spilling a34 from $t2 + lw $t2, 120($sp) + # Spilling t30 from $t9 + add $t9, $t7, $t2 + # Spilling a35 from $t2 + lw $t2, 124($sp) + # Spilling t31 from $t8 + add $t8, $t9, $t2 + # Spilling a36 from $t2 + lw $t2, 128($sp) + # Spilling t32 from $t7 + add $t7, $t8, $t2 + # Spilling a37 from $t2 + lw $t2, 132($sp) + # Spilling t33 from $t9 + add $t9, $t7, $t2 + # Spilling a38 from $t2 + lw $t2, 136($sp) + # Spilling t34 from $t8 + add $t8, $t9, $t2 + # Spilling a39 from $t2 + lw $t2, 140($sp) + # Spilling t35 from $t7 + add $t7, $t8, $t2 + # Spilling a40 from $t2 + lw $t2, 144($sp) + # Spilling t36 from $t9 + add $t9, $t7, $t2 + # Spilling a41 from $t2 + lw $t2, 148($sp) + # Spilling t37 from $t8 + add $t8, $t9, $t2 + # Spilling a42 from $t2 + lw $t2, 152($sp) + # Spilling t38 from $t7 + add $t7, $t8, $t2 + # Spilling a43 from $t2 + lw $t2, 156($sp) + # Spilling t39 from $t9 + add $t9, $t7, $t2 + # Spilling a44 from $t2 + lw $t2, 160($sp) + # Spilling t4 from $t6 + add $t6, $t9, $t2 + # Spilling a45 from $t2 + lw $t2, 164($sp) + # Spilling t40 from $t8 + add $t8, $t6, $t2 + # Spilling a46 from $t2 + lw $t2, 168($sp) + # Spilling t41 from $t7 + add $t7, $t8, $t2 + # Spilling a47 from $t2 + lw $t2, 172($sp) + # Spilling t42 from $t9 + add $t9, $t7, $t2 + # Spilling a48 from $t2 + lw $t2, 176($sp) + # Spilling t43 from $t6 + add $t6, $t9, $t2 + # Spilling a49 from $t2 + lw $t2, 180($sp) + # Spilling t44 from $t8 + add $t8, $t6, $t2 + # Spilling a50 from $t2 + lw $t2, 184($sp) + # Spilling t45 from $t7 + add $t7, $t8, $t2 + # Spilling a51 from $t2 + lw $t2, 188($sp) + # Spilling t46 from $t9 + add $t9, $t7, $t2 + # Spilling a52 from $t2 + lw $t2, 192($sp) + # Spilling t47 from $t6 + add $t6, $t9, $t2 + # Spilling a53 from $t2 + lw $t2, 196($sp) + # Spilling t48 from $t8 + add $t8, $t6, $t2 + # Spilling a54 from $t2 + lw $t2, 200($sp) + # Spilling t49 from $t7 + add $t7, $t8, $t2 + # Spilling a55 from $t2 + lw $t2, 204($sp) + # Spilling t5 from $t5 + add $t5, $t7, $t2 + # Spilling a56 from $t2 + lw $t2, 208($sp) + # Spilling t50 from $t9 + add $t9, $t5, $t2 + # Spilling a57 from $t2 + lw $t2, 212($sp) + # Spilling t51 from $t6 + add $t6, $t9, $t2 + # Spilling a58 from $t2 + lw $t2, 216($sp) + # Spilling t52 from $t8 + add $t8, $t6, $t2 + # Spilling a59 from $t2 + lw $t2, 220($sp) + # Spilling t53 from $t7 + add $t7, $t8, $t2 + # Spilling a60 from $t2 + lw $t2, 224($sp) + # Spilling t54 from $t5 + add $t5, $t7, $t2 + # Spilling a61 from $t2 + lw $t2, 228($sp) + # Spilling t55 from $t9 + add $t9, $t5, $t2 + # Spilling a62 from $t2 + lw $t2, 232($sp) + # Spilling t56 from $t6 + add $t6, $t9, $t2 + # Spilling a63 from $t2 + lw $t2, 236($sp) + # Spilling t57 from $t8 + add $t8, $t6, $t2 + # Spilling a64 from $t2 + lw $t2, 240($sp) + # Spilling t58 from $t7 + add $t7, $t8, $t2 + # Spilling a65 from $t2 + lw $t2, 244($sp) + # Spilling t59 from $t5 + add $t5, $t7, $t2 + # Spilling a66 from $t2 + lw $t2, 248($sp) + # Spilling t6 from $t4 + add $t4, $t5, $t2 + # Spilling a67 from $t2 + lw $t2, 252($sp) + # Spilling t60 from $t9 + add $t9, $t4, $t2 + # Spilling a68 from $t2 + lw $t2, 256($sp) + # Spilling t61 from $t6 + add $t6, $t9, $t2 + # Spilling a69 from $t2 + lw $t2, 260($sp) + # Spilling t62 from $t8 + add $t8, $t6, $t2 + # Spilling a70 from $t2 + lw $t2, 264($sp) + # Spilling t63 from $t7 + add $t7, $t8, $t2 + # Spilling a71 from $t2 + lw $t2, 268($sp) + # Spilling t64 from $t5 + add $t5, $t7, $t2 + # Spilling a72 from $t2 + lw $t2, 272($sp) + # Spilling t65 from $t4 + add $t4, $t5, $t2 + # Spilling a73 from $t2 + lw $t2, 276($sp) + # Spilling t66 from $t9 + add $t9, $t4, $t2 + # Spilling a74 from $t2 + lw $t2, 280($sp) + # Spilling t67 from $t6 + add $t6, $t9, $t2 + # Spilling a75 from $t2 + lw $t2, 284($sp) + # Spilling t68 from $t8 + add $t8, $t6, $t2 + # Spilling a76 from $t2 + lw $t2, 288($sp) + # Spilling t69 from $t7 + add $t7, $t8, $t2 + # Spilling a77 from $t2 + lw $t2, 292($sp) + # Spilling t7 from $t3 + add $t3, $t7, $t2 + # Spilling a78 from $t2 + lw $t2, 296($sp) + # Spilling t70 from $t5 + add $t5, $t3, $t2 + # Spilling a79 from $t2 + lw $t2, 300($sp) + # Spilling t71 from $t4 + add $t4, $t5, $t2 + # Spilling a80 from $t2 + lw $t2, 304($sp) + # Spilling t72 from $t9 + add $t9, $t4, $t2 + # Spilling a81 from $t2 + lw $t2, 308($sp) + # Spilling t73 from $t6 + add $t6, $t9, $t2 + # Spilling a82 from $t2 + lw $t2, 312($sp) + # Spilling t74 from $t8 + add $t8, $t6, $t2 + # Spilling a83 from $t2 + lw $t2, 316($sp) + # Spilling t75 from $t7 + add $t7, $t8, $t2 + # Spilling a84 from $t2 + lw $t2, 320($sp) + # Spilling t76 from $t3 + add $t3, $t7, $t2 + # Spilling a85 from $t2 + lw $t2, 324($sp) + # Spilling t77 from $t5 + add $t5, $t3, $t2 + # Spilling a86 from $t2 + lw $t2, 328($sp) + # Spilling t78 from $t4 + add $t4, $t5, $t2 + # Spilling a87 from $t2 + lw $t2, 332($sp) + # Spilling t79 from $t9 + add $t9, $t4, $t2 + # Spilling a88 from $t2 + lw $t2, 336($sp) + # Spilling t8 from $t1 + add $t1, $t9, $t2 + # Spilling a89 from $t2 + lw $t2, 340($sp) + # Spilling t80 from $t6 + add $t6, $t1, $t2 + # Spilling a90 from $t2 + lw $t2, 344($sp) + # Spilling t81 from $t8 + add $t8, $t6, $t2 + # Spilling a91 from $t2 + lw $t2, 348($sp) + # Spilling t82 from $t7 + add $t7, $t8, $t2 + # Spilling a92 from $t2 + lw $t2, 352($sp) + # Spilling t83 from $t3 + add $t3, $t7, $t2 + # Spilling a93 from $t2 + lw $t2, 356($sp) + # Spilling t84 from $t5 + add $t5, $t3, $t2 + # Spilling a94 from $t2 + lw $t2, 360($sp) + # Spilling t85 from $t4 + add $t4, $t5, $t2 + # Spilling a95 from $t2 + lw $t2, 364($sp) + # Spilling t86 from $t9 + add $t9, $t4, $t2 + # Spilling a96 from $t2 + lw $t2, 368($sp) + # Spilling t87 from $t1 + add $t1, $t9, $t2 + # Spilling a97 from $t2 + lw $t2, 372($sp) + # Spilling t88 from $t6 + add $t6, $t1, $t2 + # Spilling a98 from $t2 + lw $t2, 376($sp) + # Spilling t89 from $t8 + add $t8, $t6, $t2 + # Spilling a99 from $t2 + lw $t2, 380($sp) + # Spilling t9 from $t0 + add $t0, $t8, $t2 + move $v0, $t0 + lw $fp, 836($sp) + lw $ra, 840($sp) + lw $t0, 832($sp) + lw $t1, 828($sp) + lw $t2, 824($sp) + lw $t3, 820($sp) + lw $t4, 816($sp) + lw $t5, 812($sp) + lw $t6, 808($sp) + lw $t7, 804($sp) + lw $t8, 800($sp) + lw $t9, 796($sp) + addi $sp, $sp, 844 + jr $ra +main: + move $fp, $sp + addi $sp, $sp, -420 + sw $ra, 416($sp) + sw $fp, 412($sp) + # Spilling a100 from $t2 + li $t2, 10 + # Spilling t90 from $t7 + li $t7, 10 + # Spilling t91 from $t3 + li $t3, 10 + # Spilling t92 from $t5 + li $t5, 10 + # Spilling t93 from $t4 + li $t4, 10 + # Spilling t94 from $t9 + li $t9, 10 + # Spilling t95 from $t1 + li $t1, 10 + # Spilling t96 from $t6 + li $t6, 10 + # Spilling t97 from $t8 + li $t8, 10 + # Spilling t98 from $t0 + li $t0, 10 + #Pushing a1 to stack + sw $t2, 0($sp) + li $t2, 10 + #Pushing a10 to stack + sw $t0, 4($sp) + li $t0, 10 + #Pushing a11 to stack + sw $t2, 8($sp) + li $t2, 10 + #Pushing a12 to stack + sw $t0, 12($sp) + li $t0, 10 + #Pushing a13 to stack + sw $t2, 16($sp) + li $t2, 10 + #Pushing a14 to stack + sw $t0, 20($sp) + li $t0, 10 + #Pushing a15 to stack + sw $t2, 24($sp) + li $t2, 10 + #Pushing a16 to stack + sw $t0, 28($sp) + li $t0, 10 + #Pushing a17 to stack + sw $t2, 32($sp) + li $t2, 10 + #Pushing a18 to stack + sw $t0, 36($sp) + li $t0, 10 + #Pushing a19 to stack + sw $t2, 40($sp) + li $t2, 10 + #Pushing a2 to stack + sw $t7, 44($sp) + li $t7, 10 + #Pushing a20 to stack + sw $t0, 48($sp) + li $t0, 10 + #Pushing a21 to stack + sw $t2, 52($sp) + li $t2, 10 + #Pushing a22 to stack + sw $t7, 56($sp) + li $t7, 10 + #Pushing a23 to stack + sw $t0, 60($sp) + li $t0, 10 + #Pushing a24 to stack + sw $t2, 64($sp) + li $t2, 10 + #Pushing a25 to stack + sw $t7, 68($sp) + li $t7, 10 + #Pushing a26 to stack + sw $t0, 72($sp) + li $t0, 10 + #Pushing a27 to stack + sw $t2, 76($sp) + li $t2, 10 + #Pushing a28 to stack + sw $t7, 80($sp) + li $t7, 10 + #Pushing a29 to stack + sw $t0, 84($sp) + li $t0, 10 + #Pushing a3 to stack + sw $t3, 88($sp) + li $t3, 10 + #Pushing a30 to stack + sw $t2, 92($sp) + li $t2, 10 + #Pushing a31 to stack + sw $t7, 96($sp) + li $t7, 10 + #Pushing a32 to stack + sw $t0, 100($sp) + li $t0, 10 + #Pushing a33 to stack + sw $t3, 104($sp) + li $t3, 10 + #Pushing a34 to stack + sw $t2, 108($sp) + li $t2, 10 + #Pushing a35 to stack + sw $t7, 112($sp) + li $t7, 10 + #Pushing a36 to stack + sw $t0, 116($sp) + li $t0, 10 + #Pushing a37 to stack + sw $t3, 120($sp) + li $t3, 10 + #Pushing a38 to stack + sw $t2, 124($sp) + li $t2, 10 + #Pushing a39 to stack + sw $t7, 128($sp) + li $t7, 10 + #Pushing a4 to stack + sw $t5, 132($sp) + li $t5, 10 + #Pushing a40 to stack + sw $t0, 136($sp) + li $t0, 10 + #Pushing a41 to stack + sw $t3, 140($sp) + li $t3, 10 + #Pushing a42 to stack + sw $t2, 144($sp) + li $t2, 10 + #Pushing a43 to stack + sw $t7, 148($sp) + li $t7, 10 + #Pushing a44 to stack + sw $t5, 152($sp) + li $t5, 10 + #Pushing a45 to stack + sw $t0, 156($sp) + li $t0, 10 + #Pushing a46 to stack + sw $t3, 160($sp) + li $t3, 10 + #Pushing a47 to stack + sw $t2, 164($sp) + li $t2, 10 + #Pushing a48 to stack + sw $t7, 168($sp) + li $t7, 10 + #Pushing a49 to stack + sw $t5, 172($sp) + li $t5, 10 + #Pushing a5 to stack + sw $t4, 176($sp) + li $t4, 10 + #Pushing a50 to stack + sw $t0, 180($sp) + li $t0, 10 + #Pushing a51 to stack + sw $t3, 184($sp) + li $t3, 10 + #Pushing a52 to stack + sw $t2, 188($sp) + li $t2, 10 + #Pushing a53 to stack + sw $t7, 192($sp) + li $t7, 10 + #Pushing a54 to stack + sw $t5, 196($sp) + li $t5, 10 + #Pushing a55 to stack + sw $t4, 200($sp) + li $t4, 10 + #Pushing a56 to stack + sw $t0, 204($sp) + li $t0, 10 + #Pushing a57 to stack + sw $t3, 208($sp) + li $t3, 10 + #Pushing a58 to stack + sw $t2, 212($sp) + li $t2, 10 + #Pushing a59 to stack + sw $t7, 216($sp) + li $t7, 10 + #Pushing a6 to stack + sw $t9, 220($sp) + li $t9, 10 + #Pushing a60 to stack + sw $t5, 224($sp) + li $t5, 10 + #Pushing a61 to stack + sw $t4, 228($sp) + li $t4, 10 + #Pushing a62 to stack + sw $t0, 232($sp) + li $t0, 10 + #Pushing a63 to stack + sw $t3, 236($sp) + li $t3, 10 + #Pushing a64 to stack + sw $t2, 240($sp) + li $t2, 10 + #Pushing a65 to stack + sw $t7, 244($sp) + li $t7, 10 + #Pushing a66 to stack + sw $t9, 248($sp) + li $t9, 10 + #Pushing a67 to stack + sw $t5, 252($sp) + li $t5, 10 + #Pushing a68 to stack + sw $t4, 256($sp) + li $t4, 10 + #Pushing a69 to stack + sw $t0, 260($sp) + li $t0, 10 + #Pushing a7 to stack + sw $t1, 264($sp) + li $t1, 10 + #Pushing a70 to stack + sw $t3, 268($sp) + li $t3, 10 + #Pushing a71 to stack + sw $t2, 272($sp) + li $t2, 10 + #Pushing a72 to stack + sw $t7, 276($sp) + li $t7, 10 + #Pushing a73 to stack + sw $t9, 280($sp) + li $t9, 10 + #Pushing a74 to stack + sw $t5, 284($sp) + li $t5, 10 + #Pushing a75 to stack + sw $t4, 288($sp) + li $t4, 10 + #Pushing a76 to stack + sw $t0, 292($sp) + li $t0, 10 + #Pushing a77 to stack + sw $t1, 296($sp) + li $t1, 10 + #Pushing a78 to stack + sw $t3, 300($sp) + li $t3, 10 + #Pushing a79 to stack + sw $t2, 304($sp) + li $t2, 10 + #Pushing a8 to stack + sw $t6, 308($sp) + li $t6, 10 + #Pushing a80 to stack + sw $t7, 312($sp) + li $t7, 10 + #Pushing a81 to stack + sw $t9, 316($sp) + li $t9, 10 + #Pushing a82 to stack + sw $t5, 320($sp) + li $t5, 10 + #Pushing a83 to stack + sw $t4, 324($sp) + li $t4, 10 + #Pushing a84 to stack + sw $t0, 328($sp) + li $t0, 10 + #Pushing a85 to stack + sw $t1, 332($sp) + li $t1, 10 + #Pushing a86 to stack + sw $t3, 336($sp) + li $t3, 10 + #Pushing a87 to stack + sw $t2, 340($sp) + li $t2, 10 + #Pushing a88 to stack + sw $t6, 344($sp) + li $t6, 10 + #Pushing a89 to stack + sw $t7, 348($sp) + li $t7, 10 + #Pushing a9 to stack + sw $t8, 352($sp) + li $t8, 10 + #Pushing a90 to stack + sw $t9, 356($sp) + li $t9, 10 + #Pushing a100 to stack + sw $t9, 360($sp) + lw $t9, 0($sp) + move $a0, $t9 + #Pushing a1 to stack + sw $t9, 0($sp) + lw $t9, 44($sp) + move $a1, $t9 + #Pushing a2 to stack + sw $t9, 44($sp) + lw $t9, 88($sp) + move $a2, $t9 + #Pushing a3 to stack + sw $t9, 88($sp) + lw $t9, 132($sp) + move $a3, $t9 + #Pushing a4 to stack + sw $t9, 132($sp) + lw $t9, 176($sp) + #Pushing a5 to stack + sw $t9, 176($sp) + lw $t9, 220($sp) + #Pushing a6 to stack + sw $t9, 220($sp) + lw $t9, 264($sp) + #Pushing a7 to stack + sw $t9, 264($sp) + lw $t9, 308($sp) + #Pushing a8 to stack + sw $t9, 308($sp) + lw $t9, 352($sp) + #Pushing a9 to stack + sw $t9, 352($sp) + lw $t9, 4($sp) + #Pushing a10 to stack + sw $t9, 4($sp) + lw $t9, 8($sp) + #Pushing a11 to stack + sw $t9, 8($sp) + lw $t9, 12($sp) + #Pushing a12 to stack + sw $t9, 12($sp) + lw $t9, 16($sp) + #Pushing a13 to stack + sw $t9, 16($sp) + lw $t9, 20($sp) + #Pushing a14 to stack + sw $t9, 20($sp) + lw $t9, 24($sp) + #Pushing a15 to stack + sw $t9, 24($sp) + lw $t9, 28($sp) + #Pushing a16 to stack + sw $t9, 28($sp) + lw $t9, 32($sp) + #Pushing a17 to stack + sw $t9, 32($sp) + lw $t9, 36($sp) + #Pushing a18 to stack + sw $t9, 36($sp) + lw $t9, 40($sp) + #Pushing a19 to stack + sw $t9, 40($sp) + lw $t9, 48($sp) + #Pushing a20 to stack + sw $t9, 48($sp) + lw $t9, 52($sp) + #Pushing a21 to stack + sw $t9, 52($sp) + lw $t9, 56($sp) + #Pushing a22 to stack + sw $t9, 56($sp) + lw $t9, 60($sp) + #Pushing a23 to stack + sw $t9, 60($sp) + lw $t9, 64($sp) + #Pushing a24 to stack + sw $t9, 64($sp) + lw $t9, 68($sp) + #Pushing a25 to stack + sw $t9, 68($sp) + lw $t9, 72($sp) + #Pushing a26 to stack + sw $t9, 72($sp) + lw $t9, 76($sp) + #Pushing a27 to stack + sw $t9, 76($sp) + lw $t9, 80($sp) + #Pushing a28 to stack + sw $t9, 80($sp) + lw $t9, 84($sp) + #Pushing a29 to stack + sw $t9, 84($sp) + lw $t9, 92($sp) + #Pushing a30 to stack + sw $t9, 92($sp) + lw $t9, 96($sp) + #Pushing a31 to stack + sw $t9, 96($sp) + lw $t9, 100($sp) + #Pushing a32 to stack + sw $t9, 100($sp) + lw $t9, 104($sp) + #Pushing a33 to stack + sw $t9, 104($sp) + lw $t9, 108($sp) + #Pushing a34 to stack + sw $t9, 108($sp) + lw $t9, 112($sp) + #Pushing a35 to stack + sw $t9, 112($sp) + lw $t9, 116($sp) + #Pushing a36 to stack + sw $t9, 116($sp) + lw $t9, 120($sp) + #Pushing a37 to stack + sw $t9, 120($sp) + lw $t9, 124($sp) + #Pushing a38 to stack + sw $t9, 124($sp) + lw $t9, 128($sp) + #Pushing a39 to stack + sw $t9, 128($sp) + lw $t9, 136($sp) + #Pushing a40 to stack + sw $t9, 136($sp) + lw $t9, 140($sp) + #Pushing a41 to stack + sw $t9, 140($sp) + lw $t9, 144($sp) + #Pushing a42 to stack + sw $t9, 144($sp) + lw $t9, 148($sp) + #Pushing a43 to stack + sw $t9, 148($sp) + lw $t9, 152($sp) + #Pushing a44 to stack + sw $t9, 152($sp) + lw $t9, 156($sp) + #Pushing a45 to stack + sw $t9, 156($sp) + lw $t9, 160($sp) + #Pushing a46 to stack + sw $t9, 160($sp) + lw $t9, 164($sp) + #Pushing a47 to stack + sw $t9, 164($sp) + lw $t9, 168($sp) + #Pushing a48 to stack + sw $t9, 168($sp) + lw $t9, 172($sp) + #Pushing a49 to stack + sw $t9, 172($sp) + lw $t9, 180($sp) + #Pushing a50 to stack + sw $t9, 180($sp) + lw $t9, 184($sp) + #Pushing a51 to stack + sw $t9, 184($sp) + lw $t9, 188($sp) + #Pushing a52 to stack + sw $t9, 188($sp) + lw $t9, 192($sp) + #Pushing a53 to stack + sw $t9, 192($sp) + lw $t9, 196($sp) + #Pushing a54 to stack + sw $t9, 196($sp) + lw $t9, 200($sp) + #Pushing a55 to stack + sw $t9, 200($sp) + lw $t9, 204($sp) + #Pushing a56 to stack + sw $t9, 204($sp) + lw $t9, 208($sp) + #Pushing a57 to stack + sw $t9, 208($sp) + lw $t9, 212($sp) + #Pushing a58 to stack + sw $t9, 212($sp) + lw $t9, 216($sp) + #Pushing a59 to stack + sw $t9, 216($sp) + lw $t9, 224($sp) + #Pushing a60 to stack + sw $t9, 224($sp) + lw $t9, 228($sp) + #Pushing a61 to stack + sw $t9, 228($sp) + lw $t9, 232($sp) + #Pushing a62 to stack + sw $t9, 232($sp) + lw $t9, 236($sp) + #Pushing a63 to stack + sw $t9, 236($sp) + lw $t9, 240($sp) + #Pushing a64 to stack + sw $t9, 240($sp) + lw $t9, 244($sp) + #Pushing a65 to stack + sw $t9, 244($sp) + lw $t9, 248($sp) + #Pushing a66 to stack + sw $t9, 248($sp) + lw $t9, 252($sp) + #Pushing a67 to stack + sw $t9, 252($sp) + lw $t9, 256($sp) + #Pushing a68 to stack + sw $t9, 256($sp) + lw $t9, 260($sp) + #Pushing a69 to stack + sw $t9, 260($sp) + lw $t9, 268($sp) + #Pushing a70 to stack + sw $t9, 268($sp) + lw $t9, 272($sp) + #Pushing a71 to stack + sw $t9, 272($sp) + lw $t9, 276($sp) + #Pushing a72 to stack + sw $t9, 276($sp) + lw $t9, 280($sp) + #Pushing a73 to stack + sw $t9, 280($sp) + lw $t9, 284($sp) + #Pushing a74 to stack + sw $t9, 284($sp) + lw $t9, 288($sp) + #Pushing a75 to stack + sw $t9, 288($sp) + lw $t9, 292($sp) + #Pushing a76 to stack + sw $t9, 292($sp) + lw $t9, 296($sp) + #Pushing a77 to stack + sw $t9, 296($sp) + lw $t9, 300($sp) + #Pushing a78 to stack + sw $t9, 300($sp) + lw $t9, 304($sp) + #Pushing a79 to stack + sw $t9, 304($sp) + lw $t9, 312($sp) + #Pushing a80 to stack + sw $t9, 312($sp) + lw $t9, 316($sp) + #Pushing a81 to stack + sw $t9, 316($sp) + lw $t9, 320($sp) + #Pushing a82 to stack + sw $t9, 320($sp) + lw $t9, 324($sp) + #Pushing a83 to stack + sw $t9, 324($sp) + lw $t9, 328($sp) + #Pushing a84 to stack + sw $t9, 328($sp) + lw $t9, 332($sp) + #Pushing a85 to stack + sw $t9, 332($sp) + lw $t9, 336($sp) + #Pushing a86 to stack + sw $t9, 336($sp) + lw $t9, 340($sp) + #Pushing a87 to stack + sw $t9, 340($sp) + lw $t9, 344($sp) + #Pushing a88 to stack + sw $t9, 344($sp) + lw $t9, 348($sp) + #Pushing a89 to stack + sw $t9, 348($sp) + lw $t9, 356($sp) + #Pushing a90 to stack + sw $t9, 356($sp) + lw $t9, 360($sp) + #Pushing a100 to stack + sw $t9, 360($sp) + addi $sp, $sp, -4 + sw $t9, 0($sp) + addi $sp, $sp, -4 + sw $t8, 0($sp) + addi $sp, $sp, -4 + sw $t7, 0($sp) + addi $sp, $sp, -4 + sw $t6, 0($sp) + addi $sp, $sp, -4 + sw $t2, 0($sp) + addi $sp, $sp, -4 + sw $t3, 0($sp) + addi $sp, $sp, -4 + sw $t1, 0($sp) + addi $sp, $sp, -4 + sw $t0, 0($sp) + addi $sp, $sp, -4 + sw $t4, 0($sp) + addi $sp, $sp, -4 + sw $t5, 0($sp) + addi $sp, $sp, -4 + sw $t9, 0($sp) + addi $sp, $sp, -4 + sw $t9, 0($sp) + addi $sp, $sp, -4 + sw $t9, 0($sp) + addi $sp, $sp, -4 + sw $t9, 0($sp) + addi $sp, $sp, -4 + sw $t9, 0($sp) + addi $sp, $sp, -4 + sw $t9, 0($sp) + addi $sp, $sp, -4 + sw $t9, 0($sp) + addi $sp, $sp, -4 + sw $t9, 0($sp) + addi $sp, $sp, -4 + sw $t9, 0($sp) + addi $sp, $sp, -4 + sw $t9, 0($sp) + addi $sp, $sp, -4 + sw $t9, 0($sp) + addi $sp, $sp, -4 + sw $t9, 0($sp) + addi $sp, $sp, -4 + sw $t9, 0($sp) + addi $sp, $sp, -4 + sw $t9, 0($sp) + addi $sp, $sp, -4 + sw $t9, 0($sp) + addi $sp, $sp, -4 + sw $t9, 0($sp) + addi $sp, $sp, -4 + sw $t9, 0($sp) + addi $sp, $sp, -4 + sw $t9, 0($sp) + addi $sp, $sp, -4 + sw $t9, 0($sp) + addi $sp, $sp, -4 + sw $t9, 0($sp) + addi $sp, $sp, -4 + sw $t9, 0($sp) + addi $sp, $sp, -4 + sw $t9, 0($sp) + addi $sp, $sp, -4 + sw $t9, 0($sp) + addi $sp, $sp, -4 + sw $t9, 0($sp) + addi $sp, $sp, -4 + sw $t9, 0($sp) + addi $sp, $sp, -4 + sw $t9, 0($sp) + addi $sp, $sp, -4 + sw $t9, 0($sp) + addi $sp, $sp, -4 + sw $t9, 0($sp) + addi $sp, $sp, -4 + sw $t9, 0($sp) + addi $sp, $sp, -4 + sw $t9, 0($sp) + addi $sp, $sp, -4 + sw $t9, 0($sp) + addi $sp, $sp, -4 + sw $t9, 0($sp) + addi $sp, $sp, -4 + sw $t9, 0($sp) + addi $sp, $sp, -4 + sw $t9, 0($sp) + addi $sp, $sp, -4 + sw $t9, 0($sp) + addi $sp, $sp, -4 + sw $t9, 0($sp) + addi $sp, $sp, -4 + sw $t9, 0($sp) + addi $sp, $sp, -4 + sw $t9, 0($sp) + addi $sp, $sp, -4 + sw $t9, 0($sp) + addi $sp, $sp, -4 + sw $t9, 0($sp) + addi $sp, $sp, -4 + sw $t9, 0($sp) + addi $sp, $sp, -4 + sw $t9, 0($sp) + addi $sp, $sp, -4 + sw $t9, 0($sp) + addi $sp, $sp, -4 + sw $t9, 0($sp) + addi $sp, $sp, -4 + sw $t9, 0($sp) + addi $sp, $sp, -4 + sw $t9, 0($sp) + addi $sp, $sp, -4 + sw $t9, 0($sp) + addi $sp, $sp, -4 + sw $t9, 0($sp) + addi $sp, $sp, -4 + sw $t9, 0($sp) + addi $sp, $sp, -4 + sw $t9, 0($sp) + addi $sp, $sp, -4 + sw $t9, 0($sp) + addi $sp, $sp, -4 + sw $t9, 0($sp) + addi $sp, $sp, -4 + sw $t9, 0($sp) + addi $sp, $sp, -4 + sw $t9, 0($sp) + addi $sp, $sp, -4 + sw $t9, 0($sp) + addi $sp, $sp, -4 + sw $t9, 0($sp) + addi $sp, $sp, -4 + sw $t9, 0($sp) + addi $sp, $sp, -4 + sw $t9, 0($sp) + addi $sp, $sp, -4 + sw $t9, 0($sp) + addi $sp, $sp, -4 + sw $t9, 0($sp) + addi $sp, $sp, -4 + sw $t9, 0($sp) + addi $sp, $sp, -4 + sw $t9, 0($sp) + addi $sp, $sp, -4 + sw $t9, 0($sp) + addi $sp, $sp, -4 + sw $t9, 0($sp) + addi $sp, $sp, -4 + sw $t9, 0($sp) + addi $sp, $sp, -4 + sw $t9, 0($sp) + addi $sp, $sp, -4 + sw $t9, 0($sp) + addi $sp, $sp, -4 + sw $t9, 0($sp) + addi $sp, $sp, -4 + sw $t9, 0($sp) + addi $sp, $sp, -4 + sw $t9, 0($sp) + addi $sp, $sp, -4 + sw $t9, 0($sp) + addi $sp, $sp, -4 + sw $t9, 0($sp) + addi $sp, $sp, -4 + sw $t9, 0($sp) + addi $sp, $sp, -4 + sw $t9, 0($sp) + addi $sp, $sp, -4 + sw $t9, 0($sp) + addi $sp, $sp, -4 + sw $t9, 0($sp) + addi $sp, $sp, -4 + sw $t9, 0($sp) + addi $sp, $sp, -4 + sw $t9, 0($sp) + addi $sp, $sp, -4 + sw $t9, 0($sp) + addi $sp, $sp, -4 + sw $t9, 0($sp) + addi $sp, $sp, -4 + sw $t9, 0($sp) + addi $sp, $sp, -4 + sw $t9, 0($sp) + addi $sp, $sp, -4 + sw $t9, 0($sp) + addi $sp, $sp, -4 + sw $t9, 0($sp) + addi $sp, $sp, -4 + sw $t9, 0($sp) + addi $sp, $sp, -4 + sw $t9, 0($sp) + jal add_all + move $t9, $v0 + #Pushing a91 to stack + sw $t5, 364($sp) + move $t5, $t9 + la $a0, str0 + move $a1, $t5 + # Spilling t99 from $t9 +#printf + move $a0, $a0 + li $v0, 4 +syscall + li $v0, 4 + la $a0, newline + syscall + move $a0, $a1 + li $v0, 1 +syscall + li $v0, 4 + la $a0, newline + syscall + move $t9, $v0 + li $v0, 0 + lw $fp, 412($sp) + lw $ra, 416($sp) + li $v0, 10 + syscall diff --git a/Assignment4/output/output3.s b/Assignment4/output/output3.s new file mode 100644 index 0000000..3026161 --- /dev/null +++ b/Assignment4/output/output3.s @@ -0,0 +1,179 @@ +# ====================================================================== +# No Errors in the code +# Intermediate code generated successfully +# ====================================================================== +.data +newline: .asciiz "\n" +str0: .asciiz "This branch is always taken.\n" +str1: .asciiz "This branch is never taken.\n" +str2: .asciiz "Results: x=" +str3: .asciiz "Counter:" +float_const_5.000000: .float 5.000000 +float_const_30.000000: .float 30.000000 +.text +.globl main +main: + move $fp, $sp + addi $sp, $sp, -104 + sw $ra, 100($sp) + sw $fp, 96($sp) + li $t9, 5 + li $t8, 10 + li $t7, 15 + li $t6, 20 + li $t5, 2 + mul $t4, $t9, $t5 + move $t3, $t4 + add $t2, $t9, $t9 + move $t1, $t2 + li $t0, 4 + # Spilling a from $t9 + li $t9, 5 + # Spilling c from $t7 + mul $t7, $t0, $t9 + # Spilling t0 from $t4 + move $t4, $t7 + # Spilling t1 from $t2 + la $t2, float_const_30.000000 + l.s $f31, 0($t2) + la $t2, float_const_5.000000 + l.s $f30, 0($t2) + div.s $f29, $f31, $f30 + mov.s $f28, $f29 + li $t2, 8 + # Spilling t2 from $t7 + mul $t7, $t6, $t2 + # Spilling d from $t6 + move $t6, $t7 + # Spilling t4 from $t7 + li $t7, 100 + # Spilling unused from $t7 + li $t7, 0 + #Pushing u to stack + sw $t6, 0($sp) + li $t6, 1 + #Pushing x to stack + sw $t3, 4($sp) + add $t3, $t7, $t6 + move $t7, $t3 + # Spilling t5 from $t3 + li $t3, 1 + #Pushing y to stack + sw $t1, 8($sp) + add $t1, $t7, $t3 + move $t7, $t1 + # Spilling t6 from $t1 + li $t1, 1 + #Pushing z to stack + sw $t4, 12($sp) + add $t4, $t7, $t1 + move $t7, $t4 + # Spilling t7 from $t4 + move $t4, $t8 + move $t4, $t4 + # Spilling b from $t8 + li $t8, 1 + bnez $t8, LABEL0 + j LABEL1 +LABEL0: + la $a0, str0 + # Spilling temp from $t4 +#printf + move $a0, $a0 + li $v0, 4 +syscall + li $v0, 4 + la $a0, newline + syscall + move $t4, $v0 + j LABEL2 +LABEL1: + la $a0, str1 + # Spilling t8 from $t4 +#printf + move $a0, $a0 + li $v0, 4 +syscall + li $v0, 4 + la $a0, newline + syscall + move $t4, $v0 +LABEL2: + la $a0, str2 + # Spilling t9 from $t4 + lw $t4, 4($sp) + move $a1, $t4 + #Pushing counter to stack + sw $t7, 16($sp) + lw $t7, 8($sp) + move $a2, $t7 + #Pushing x to stack + sw $t4, 4($sp) + lw $t4, 12($sp) + move $a3, $t4 + mov.s $f12, $f28 +#printf + move $a0, $a0 + li $v0, 4 +syscall + li $v0, 4 + la $a0, newline + syscall + move $a0, $a1 + li $v0, 1 +syscall + li $v0, 4 + la $a0, newline + syscall + move $a0, $a2 + li $v0, 1 +syscall + li $v0, 4 + la $a0, newline + syscall + move $a0, $a3 + li $v0, 1 +syscall + li $v0, 4 + la $a0, newline + syscall + mov.s $f12, $f12 + li $v0, 2 +syscall + li $v0, 4 + la $a0, newline + syscall + move $t0, $v0 + la $a0, str3 + # Spilling t10 from $t0 + lw $t0, 0($sp) + move $a1, $t0 + # Spilling y from $t7 + lw $t7, 16($sp) + move $a2, $t7 + # Spilling z from $t4 +#printf + move $a0, $a0 + li $v0, 4 +syscall + li $v0, 4 + la $a0, newline + syscall + move $a0, $a1 + li $v0, 1 +syscall + li $v0, 4 + la $a0, newline + syscall + move $a0, $a2 + li $v0, 1 +syscall + li $v0, 4 + la $a0, newline + syscall + move $t4, $v0 + li $v0, 0 + lw $fp, 96($sp) + lw $ra, 100($sp) + li $v0, 10 + syscall diff --git a/Assignment4/output/output4.s b/Assignment4/output/output4.s new file mode 100644 index 0000000..e0768a2 --- /dev/null +++ b/Assignment4/output/output4.s @@ -0,0 +1,699 @@ +# ====================================================================== +# No Errors in the code +# Intermediate code generated successfully +# ====================================================================== +.data +newline: .asciiz "\n" +str0: .asciiz "Sum of all variables =" +.text +.globl main +main: + move $fp, $sp + addi $sp, $sp, -812 + sw $ra, 808($sp) + sw $fp, 804($sp) + li $t9, 10 + li $t8, 10 + li $t7, 10 + li $t6, 10 + li $t5, 10 + li $t4, 10 + li $t3, 10 + li $t2, 10 + li $t1, 10 + li $t0, 10 + #Pushing a10 to stack + sw $t0, 0($sp) + li $t0, 10 + #Pushing a11 to stack + sw $t0, 4($sp) + li $t0, 10 + #Pushing a12 to stack + sw $t0, 8($sp) + li $t0, 10 + #Pushing a13 to stack + sw $t0, 12($sp) + li $t0, 10 + #Pushing a14 to stack + sw $t0, 16($sp) + li $t0, 10 + #Pushing a15 to stack + sw $t0, 20($sp) + li $t0, 10 + #Pushing a16 to stack + sw $t0, 24($sp) + li $t0, 10 + #Pushing a17 to stack + sw $t0, 28($sp) + li $t0, 10 + #Pushing a18 to stack + sw $t0, 32($sp) + li $t0, 10 + #Pushing a19 to stack + sw $t0, 36($sp) + li $t0, 10 + #Pushing a20 to stack + sw $t0, 40($sp) + li $t0, 10 + #Pushing a21 to stack + sw $t0, 44($sp) + li $t0, 10 + #Pushing a22 to stack + sw $t0, 48($sp) + li $t0, 10 + #Pushing a23 to stack + sw $t0, 52($sp) + li $t0, 10 + #Pushing a24 to stack + sw $t0, 56($sp) + li $t0, 10 + #Pushing a25 to stack + sw $t0, 60($sp) + li $t0, 10 + #Pushing a26 to stack + sw $t0, 64($sp) + li $t0, 10 + #Pushing a27 to stack + sw $t0, 68($sp) + li $t0, 10 + #Pushing a28 to stack + sw $t0, 72($sp) + li $t0, 10 + #Pushing a29 to stack + sw $t0, 76($sp) + li $t0, 10 + #Pushing a30 to stack + sw $t0, 80($sp) + li $t0, 10 + #Pushing a31 to stack + sw $t0, 84($sp) + li $t0, 10 + #Pushing a32 to stack + sw $t0, 88($sp) + li $t0, 10 + #Pushing a33 to stack + sw $t0, 92($sp) + li $t0, 10 + #Pushing a34 to stack + sw $t0, 96($sp) + li $t0, 10 + #Pushing a35 to stack + sw $t0, 100($sp) + li $t0, 10 + #Pushing a36 to stack + sw $t0, 104($sp) + li $t0, 10 + #Pushing a37 to stack + sw $t0, 108($sp) + li $t0, 10 + #Pushing a38 to stack + sw $t0, 112($sp) + li $t0, 10 + #Pushing a39 to stack + sw $t0, 116($sp) + li $t0, 10 + #Pushing a40 to stack + sw $t0, 120($sp) + li $t0, 10 + #Pushing a41 to stack + sw $t0, 124($sp) + li $t0, 10 + #Pushing a42 to stack + sw $t0, 128($sp) + li $t0, 10 + #Pushing a43 to stack + sw $t0, 132($sp) + li $t0, 10 + #Pushing a44 to stack + sw $t0, 136($sp) + li $t0, 10 + #Pushing a45 to stack + sw $t0, 140($sp) + li $t0, 10 + #Pushing a46 to stack + sw $t0, 144($sp) + li $t0, 10 + #Pushing a47 to stack + sw $t0, 148($sp) + li $t0, 10 + #Pushing a48 to stack + sw $t0, 152($sp) + li $t0, 10 + #Pushing a49 to stack + sw $t0, 156($sp) + li $t0, 10 + #Pushing a50 to stack + sw $t0, 160($sp) + li $t0, 10 + #Pushing a51 to stack + sw $t0, 164($sp) + li $t0, 10 + #Pushing a52 to stack + sw $t0, 168($sp) + li $t0, 10 + #Pushing a53 to stack + sw $t0, 172($sp) + li $t0, 10 + #Pushing a54 to stack + sw $t0, 176($sp) + li $t0, 10 + #Pushing a55 to stack + sw $t0, 180($sp) + li $t0, 10 + #Pushing a56 to stack + sw $t0, 184($sp) + li $t0, 10 + #Pushing a57 to stack + sw $t0, 188($sp) + li $t0, 10 + #Pushing a58 to stack + sw $t0, 192($sp) + li $t0, 10 + #Pushing a59 to stack + sw $t0, 196($sp) + li $t0, 10 + #Pushing a60 to stack + sw $t0, 200($sp) + li $t0, 10 + #Pushing a61 to stack + sw $t0, 204($sp) + li $t0, 10 + #Pushing a62 to stack + sw $t0, 208($sp) + li $t0, 10 + #Pushing a63 to stack + sw $t0, 212($sp) + li $t0, 10 + #Pushing a64 to stack + sw $t0, 216($sp) + li $t0, 10 + #Pushing a65 to stack + sw $t0, 220($sp) + li $t0, 10 + #Pushing a66 to stack + sw $t0, 224($sp) + li $t0, 10 + #Pushing a67 to stack + sw $t0, 228($sp) + li $t0, 10 + #Pushing a68 to stack + sw $t0, 232($sp) + li $t0, 10 + #Pushing a69 to stack + sw $t0, 236($sp) + li $t0, 10 + #Pushing a70 to stack + sw $t0, 240($sp) + li $t0, 10 + #Pushing a71 to stack + sw $t0, 244($sp) + li $t0, 10 + #Pushing a72 to stack + sw $t0, 248($sp) + li $t0, 10 + #Pushing a73 to stack + sw $t0, 252($sp) + li $t0, 10 + #Pushing a74 to stack + sw $t0, 256($sp) + li $t0, 10 + #Pushing a75 to stack + sw $t0, 260($sp) + li $t0, 10 + #Pushing a76 to stack + sw $t0, 264($sp) + li $t0, 10 + #Pushing a77 to stack + sw $t0, 268($sp) + li $t0, 10 + #Pushing a78 to stack + sw $t0, 272($sp) + li $t0, 10 + #Pushing a79 to stack + sw $t0, 276($sp) + li $t0, 10 + #Pushing a80 to stack + sw $t0, 280($sp) + li $t0, 10 + #Pushing a81 to stack + sw $t0, 284($sp) + li $t0, 10 + #Pushing a82 to stack + sw $t0, 288($sp) + li $t0, 10 + #Pushing a83 to stack + sw $t0, 292($sp) + li $t0, 10 + #Pushing a84 to stack + sw $t0, 296($sp) + li $t0, 10 + #Pushing a85 to stack + sw $t0, 300($sp) + li $t0, 10 + #Pushing a86 to stack + sw $t0, 304($sp) + li $t0, 10 + #Pushing a87 to stack + sw $t0, 308($sp) + li $t0, 10 + #Pushing a88 to stack + sw $t0, 312($sp) + li $t0, 10 + #Pushing a89 to stack + sw $t0, 316($sp) + li $t0, 10 + #Pushing a90 to stack + sw $t0, 320($sp) + li $t0, 10 + #Pushing a91 to stack + sw $t0, 324($sp) + li $t0, 10 + #Pushing a92 to stack + sw $t0, 328($sp) + li $t0, 10 + #Pushing a93 to stack + sw $t0, 332($sp) + li $t0, 10 + #Pushing a94 to stack + sw $t0, 336($sp) + li $t0, 10 + #Pushing a95 to stack + sw $t0, 340($sp) + li $t0, 10 + #Pushing a96 to stack + sw $t0, 344($sp) + li $t0, 10 + #Pushing a97 to stack + sw $t0, 348($sp) + li $t0, 10 + #Pushing a98 to stack + sw $t0, 352($sp) + li $t0, 10 + #Pushing a99 to stack + sw $t0, 356($sp) + li $t0, 10 + #Pushing a100 to stack + sw $t0, 360($sp) + add $t0, $t9, $t8 + # Spilling a1 from $t9 + add $t9, $t0, $t7 + # Spilling a2 from $t8 + add $t8, $t9, $t6 + # Spilling a3 from $t7 + add $t7, $t8, $t5 + # Spilling a4 from $t6 + add $t6, $t7, $t4 + # Spilling a5 from $t5 + add $t5, $t6, $t3 + # Spilling a6 from $t4 + add $t4, $t5, $t2 + # Spilling a7 from $t3 + add $t3, $t4, $t1 + # Spilling a8 from $t2 + lw $t2, 0($sp) + # Spilling a9 from $t1 + add $t1, $t3, $t2 + # Spilling a10 from $t2 + lw $t2, 4($sp) + # Spilling t0 from $t0 + add $t0, $t1, $t2 + # Spilling a11 from $t2 + lw $t2, 8($sp) + # Spilling t1 from $t9 + add $t9, $t0, $t2 + # Spilling a12 from $t2 + lw $t2, 12($sp) + # Spilling t2 from $t8 + add $t8, $t9, $t2 + # Spilling a13 from $t2 + lw $t2, 16($sp) + # Spilling t10 from $t9 + add $t9, $t8, $t2 + # Spilling a14 from $t2 + lw $t2, 20($sp) + # Spilling t11 from $t8 + add $t8, $t9, $t2 + # Spilling a15 from $t2 + lw $t2, 24($sp) + # Spilling t12 from $t9 + add $t9, $t8, $t2 + # Spilling a16 from $t2 + lw $t2, 28($sp) + # Spilling t13 from $t8 + add $t8, $t9, $t2 + # Spilling a17 from $t2 + lw $t2, 32($sp) + # Spilling t14 from $t9 + add $t9, $t8, $t2 + # Spilling a18 from $t2 + lw $t2, 36($sp) + # Spilling t15 from $t8 + add $t8, $t9, $t2 + # Spilling a19 from $t2 + lw $t2, 40($sp) + # Spilling t16 from $t9 + add $t9, $t8, $t2 + # Spilling a20 from $t2 + lw $t2, 44($sp) + # Spilling t17 from $t8 + add $t8, $t9, $t2 + # Spilling a21 from $t2 + lw $t2, 48($sp) + # Spilling t18 from $t9 + add $t9, $t8, $t2 + # Spilling a22 from $t2 + lw $t2, 52($sp) + # Spilling t19 from $t8 + add $t8, $t9, $t2 + # Spilling a23 from $t2 + lw $t2, 56($sp) + # Spilling t20 from $t9 + add $t9, $t8, $t2 + # Spilling a24 from $t2 + lw $t2, 60($sp) + # Spilling t21 from $t8 + add $t8, $t9, $t2 + # Spilling a25 from $t2 + lw $t2, 64($sp) + # Spilling t22 from $t9 + add $t9, $t8, $t2 + # Spilling a26 from $t2 + lw $t2, 68($sp) + # Spilling t23 from $t8 + add $t8, $t9, $t2 + # Spilling a27 from $t2 + lw $t2, 72($sp) + # Spilling t24 from $t9 + add $t9, $t8, $t2 + # Spilling a28 from $t2 + lw $t2, 76($sp) + # Spilling t25 from $t8 + add $t8, $t9, $t2 + # Spilling a29 from $t2 + lw $t2, 80($sp) + # Spilling t26 from $t9 + add $t9, $t8, $t2 + # Spilling a30 from $t2 + lw $t2, 84($sp) + # Spilling t27 from $t8 + add $t8, $t9, $t2 + # Spilling a31 from $t2 + lw $t2, 88($sp) + # Spilling t28 from $t9 + add $t9, $t8, $t2 + # Spilling a32 from $t2 + lw $t2, 92($sp) + # Spilling t29 from $t8 + add $t8, $t9, $t2 + # Spilling a33 from $t2 + lw $t2, 96($sp) + # Spilling t3 from $t7 + add $t7, $t8, $t2 + # Spilling a34 from $t2 + lw $t2, 100($sp) + # Spilling t30 from $t9 + add $t9, $t7, $t2 + # Spilling a35 from $t2 + lw $t2, 104($sp) + # Spilling t31 from $t8 + add $t8, $t9, $t2 + # Spilling a36 from $t2 + lw $t2, 108($sp) + # Spilling t32 from $t7 + add $t7, $t8, $t2 + # Spilling a37 from $t2 + lw $t2, 112($sp) + # Spilling t33 from $t9 + add $t9, $t7, $t2 + # Spilling a38 from $t2 + lw $t2, 116($sp) + # Spilling t34 from $t8 + add $t8, $t9, $t2 + # Spilling a39 from $t2 + lw $t2, 120($sp) + # Spilling t35 from $t7 + add $t7, $t8, $t2 + # Spilling a40 from $t2 + lw $t2, 124($sp) + # Spilling t36 from $t9 + add $t9, $t7, $t2 + # Spilling a41 from $t2 + lw $t2, 128($sp) + # Spilling t37 from $t8 + add $t8, $t9, $t2 + # Spilling a42 from $t2 + lw $t2, 132($sp) + # Spilling t38 from $t7 + add $t7, $t8, $t2 + # Spilling a43 from $t2 + lw $t2, 136($sp) + # Spilling t39 from $t9 + add $t9, $t7, $t2 + # Spilling a44 from $t2 + lw $t2, 140($sp) + # Spilling t4 from $t6 + add $t6, $t9, $t2 + # Spilling a45 from $t2 + lw $t2, 144($sp) + # Spilling t40 from $t8 + add $t8, $t6, $t2 + # Spilling a46 from $t2 + lw $t2, 148($sp) + # Spilling t41 from $t7 + add $t7, $t8, $t2 + # Spilling a47 from $t2 + lw $t2, 152($sp) + # Spilling t42 from $t9 + add $t9, $t7, $t2 + # Spilling a48 from $t2 + lw $t2, 156($sp) + # Spilling t43 from $t6 + add $t6, $t9, $t2 + # Spilling a49 from $t2 + lw $t2, 160($sp) + # Spilling t44 from $t8 + add $t8, $t6, $t2 + # Spilling a50 from $t2 + lw $t2, 164($sp) + # Spilling t45 from $t7 + add $t7, $t8, $t2 + # Spilling a51 from $t2 + lw $t2, 168($sp) + # Spilling t46 from $t9 + add $t9, $t7, $t2 + # Spilling a52 from $t2 + lw $t2, 172($sp) + # Spilling t47 from $t6 + add $t6, $t9, $t2 + # Spilling a53 from $t2 + lw $t2, 176($sp) + # Spilling t48 from $t8 + add $t8, $t6, $t2 + # Spilling a54 from $t2 + lw $t2, 180($sp) + # Spilling t49 from $t7 + add $t7, $t8, $t2 + # Spilling a55 from $t2 + lw $t2, 184($sp) + # Spilling t5 from $t5 + add $t5, $t7, $t2 + # Spilling a56 from $t2 + lw $t2, 188($sp) + # Spilling t50 from $t9 + add $t9, $t5, $t2 + # Spilling a57 from $t2 + lw $t2, 192($sp) + # Spilling t51 from $t6 + add $t6, $t9, $t2 + # Spilling a58 from $t2 + lw $t2, 196($sp) + # Spilling t52 from $t8 + add $t8, $t6, $t2 + # Spilling a59 from $t2 + lw $t2, 200($sp) + # Spilling t53 from $t7 + add $t7, $t8, $t2 + # Spilling a60 from $t2 + lw $t2, 204($sp) + # Spilling t54 from $t5 + add $t5, $t7, $t2 + # Spilling a61 from $t2 + lw $t2, 208($sp) + # Spilling t55 from $t9 + add $t9, $t5, $t2 + # Spilling a62 from $t2 + lw $t2, 212($sp) + # Spilling t56 from $t6 + add $t6, $t9, $t2 + # Spilling a63 from $t2 + lw $t2, 216($sp) + # Spilling t57 from $t8 + add $t8, $t6, $t2 + # Spilling a64 from $t2 + lw $t2, 220($sp) + # Spilling t58 from $t7 + add $t7, $t8, $t2 + # Spilling a65 from $t2 + lw $t2, 224($sp) + # Spilling t59 from $t5 + add $t5, $t7, $t2 + # Spilling a66 from $t2 + lw $t2, 228($sp) + # Spilling t6 from $t4 + add $t4, $t5, $t2 + # Spilling a67 from $t2 + lw $t2, 232($sp) + # Spilling t60 from $t9 + add $t9, $t4, $t2 + # Spilling a68 from $t2 + lw $t2, 236($sp) + # Spilling t61 from $t6 + add $t6, $t9, $t2 + # Spilling a69 from $t2 + lw $t2, 240($sp) + # Spilling t62 from $t8 + add $t8, $t6, $t2 + # Spilling a70 from $t2 + lw $t2, 244($sp) + # Spilling t63 from $t7 + add $t7, $t8, $t2 + # Spilling a71 from $t2 + lw $t2, 248($sp) + # Spilling t64 from $t5 + add $t5, $t7, $t2 + # Spilling a72 from $t2 + lw $t2, 252($sp) + # Spilling t65 from $t4 + add $t4, $t5, $t2 + # Spilling a73 from $t2 + lw $t2, 256($sp) + # Spilling t66 from $t9 + add $t9, $t4, $t2 + # Spilling a74 from $t2 + lw $t2, 260($sp) + # Spilling t67 from $t6 + add $t6, $t9, $t2 + # Spilling a75 from $t2 + lw $t2, 264($sp) + # Spilling t68 from $t8 + add $t8, $t6, $t2 + # Spilling a76 from $t2 + lw $t2, 268($sp) + # Spilling t69 from $t7 + add $t7, $t8, $t2 + # Spilling a77 from $t2 + lw $t2, 272($sp) + # Spilling t7 from $t3 + add $t3, $t7, $t2 + # Spilling a78 from $t2 + lw $t2, 276($sp) + # Spilling t70 from $t5 + add $t5, $t3, $t2 + # Spilling a79 from $t2 + lw $t2, 280($sp) + # Spilling t71 from $t4 + add $t4, $t5, $t2 + # Spilling a80 from $t2 + lw $t2, 284($sp) + # Spilling t72 from $t9 + add $t9, $t4, $t2 + # Spilling a81 from $t2 + lw $t2, 288($sp) + # Spilling t73 from $t6 + add $t6, $t9, $t2 + # Spilling a82 from $t2 + lw $t2, 292($sp) + # Spilling t74 from $t8 + add $t8, $t6, $t2 + # Spilling a83 from $t2 + lw $t2, 296($sp) + # Spilling t75 from $t7 + add $t7, $t8, $t2 + # Spilling a84 from $t2 + lw $t2, 300($sp) + # Spilling t76 from $t3 + add $t3, $t7, $t2 + # Spilling a85 from $t2 + lw $t2, 304($sp) + # Spilling t77 from $t5 + add $t5, $t3, $t2 + # Spilling a86 from $t2 + lw $t2, 308($sp) + # Spilling t78 from $t4 + add $t4, $t5, $t2 + # Spilling a87 from $t2 + lw $t2, 312($sp) + # Spilling t79 from $t9 + add $t9, $t4, $t2 + # Spilling a88 from $t2 + lw $t2, 316($sp) + # Spilling t8 from $t1 + add $t1, $t9, $t2 + # Spilling a89 from $t2 + lw $t2, 320($sp) + # Spilling t80 from $t6 + add $t6, $t1, $t2 + # Spilling a90 from $t2 + lw $t2, 324($sp) + # Spilling t81 from $t8 + add $t8, $t6, $t2 + # Spilling a91 from $t2 + lw $t2, 328($sp) + # Spilling t82 from $t7 + add $t7, $t8, $t2 + # Spilling a92 from $t2 + lw $t2, 332($sp) + # Spilling t83 from $t3 + add $t3, $t7, $t2 + # Spilling a93 from $t2 + lw $t2, 336($sp) + # Spilling t84 from $t5 + sub $t5, $t3, $t2 + # Spilling a94 from $t2 + lw $t2, 340($sp) + # Spilling t85 from $t4 + add $t4, $t5, $t2 + # Spilling a95 from $t2 + lw $t2, 344($sp) + # Spilling t86 from $t9 + add $t9, $t4, $t2 + # Spilling a96 from $t2 + lw $t2, 348($sp) + # Spilling t87 from $t1 + add $t1, $t9, $t2 + # Spilling a97 from $t2 + lw $t2, 352($sp) + # Spilling t88 from $t6 + add $t6, $t1, $t2 + # Spilling a98 from $t2 + lw $t2, 356($sp) + # Spilling t89 from $t8 + add $t8, $t6, $t2 + # Spilling a99 from $t2 + lw $t2, 360($sp) + # Spilling t9 from $t0 + add $t0, $t8, $t2 + # Spilling a100 from $t2 + move $t2, $t0 + la $a0, str0 + move $a1, $t2 + # Spilling t90 from $t7 +#printf + move $a0, $a0 + li $v0, 4 +syscall + li $v0, 4 + la $a0, newline + syscall + move $a0, $a1 + li $v0, 1 +syscall + li $v0, 4 + la $a0, newline + syscall + move $t7, $v0 + li $v0, 0 + lw $fp, 804($sp) + lw $ra, 808($sp) + li $v0, 10 + syscall diff --git a/Assignment4/output/output5.s b/Assignment4/output/output5.s new file mode 100644 index 0000000..e76f0b9 --- /dev/null +++ b/Assignment4/output/output5.s @@ -0,0 +1,160 @@ +# ====================================================================== +# No Errors in the code +# Intermediate code generated successfully +# ====================================================================== +.data +newline: .asciiz "\n" +static_repeat: .word 0 +str0: .asciiz "Static counter =" +str1: .asciiz "i =" +str2: .asciiz "Repeating the loop using goto!\n\n" +str3: .asciiz "Program finished.\n" +.text +.globl main +count_with_static: + move $fp, $sp + addi $sp, $sp, -56 + sw $ra, 52($sp) + sw $fp, 48($sp) + sw $t0, 44($sp) + sw $t1, 40($sp) + sw $t2, 36($sp) + sw $t3, 32($sp) + sw $t4, 28($sp) + sw $t5, 24($sp) + sw $t6, 20($sp) + sw $t7, 16($sp) + sw $t8, 12($sp) + sw $t9, 8($sp) + li $t9, 0 + li $t8, 1 + add $t9, $t9, $t8 + la $a0, str0 + move $a1, $t9 +#printf + move $a0, $a0 + li $v0, 4 +syscall + li $v0, 4 + la $a0, newline + syscall + move $a0, $a1 + li $v0, 1 +syscall + li $v0, 4 + la $a0, newline + syscall + move $t7, $v0 + li $v0, 1 + lw $fp, 48($sp) + lw $ra, 52($sp) + lw $t0, 44($sp) + lw $t1, 40($sp) + lw $t2, 36($sp) + lw $t3, 32($sp) + lw $t4, 28($sp) + lw $t5, 24($sp) + lw $t6, 20($sp) + lw $t7, 16($sp) + lw $t8, 12($sp) + lw $t9, 8($sp) + addi $sp, $sp, 56 + jr $ra +main: + move $fp, $sp + addi $sp, $sp, -56 + sw $ra, 52($sp) + sw $fp, 48($sp) + li $t6, 0 +LABEL8: + li $t6, 0 +LABEL4: + li $t5, 10 + slt $t4, $t6, $t5 + bnez $t4, LABEL6 + j LABEL5 +LABEL6: + li $t3, 2 + seq $t2, $t6, $t3 + bnez $t2, LABEL0 + j LABEL1 +LABEL0: + j LABEL7 +LABEL1: + li $t1, 5 + seq $t0, $t6, $t1 + bnez $t0, LABEL2 + j LABEL3 +LABEL2: + j LABEL5 +LABEL3: + la $a0, str1 + move $a1, $t6 + # Spilling counter from $t9 +#printf + move $a0, $a0 + li $v0, 4 +syscall + li $v0, 4 + la $a0, newline + syscall + move $a0, $a1 + li $v0, 1 +syscall + li $v0, 4 + la $a0, newline + syscall + move $t9, $v0 + # Spilling t0 from $t7 + jal count_with_static + move $t7, $v0 + # Spilling t1 from $t4 + move $t4, $t7 +LABEL7: + # Spilling r from $t4 + li $t4, 1 + add $t6, $t6, $t4 + j LABEL4 +LABEL5: + # Spilling i from $t6 + lw $t6, static_repeat + # Spilling t2 from $t2 + li $t2, 0 + # Spilling t3 from $t0 + seq $t0, $t6, $t2 + sw $t6, static_repeat + bnez $t0, LABEL9 + j LABEL10 +LABEL9: + lw $t6, static_repeat + # Spilling t6 from $t0 + li $t0, 1 + move $t6, $t0 + sw $t6, static_repeat + la $a0, str2 + # Spilling repeat from $t6 +#printf + move $a0, $a0 + li $v0, 4 +syscall + li $v0, 4 + la $a0, newline + syscall + move $t6, $v0 + j LABEL8 +LABEL10: + la $a0, str3 + # Spilling t4 from $t9 +#printf + move $a0, $a0 + li $v0, 4 +syscall + li $v0, 4 + la $a0, newline + syscall + move $t9, $v0 + li $v0, 0 + lw $fp, 48($sp) + lw $ra, 52($sp) + li $v0, 10 + syscall diff --git a/Assignment4/output/output6.s b/Assignment4/output/output6.s new file mode 100644 index 0000000..0d6816e --- /dev/null +++ b/Assignment4/output/output6.s @@ -0,0 +1,90 @@ +# ====================================================================== +# No Errors in the code +# Intermediate code generated successfully +# ====================================================================== +.data +newline: .asciiz "\n" +str0: .asciiz "" +.text +.globl main +main: + move $fp, $sp + addi $sp, $sp, -52 + sw $ra, 48($sp) + sw $fp, 44($sp) + addi $t9, $sp, 0 + #Loading constant 7 into register + li $t8, 7 + sw $t8, 0($t9) + addi $t7, $sp, 4 + #Loading constant 8 into register + li $t6, 8 + sw $t6, 0($t7) + li $t5, 0 + li $t4, 4 + mul $t3, $t5, $t4 + li $t2, 5 + addi $t3, $t3, 8 + add $t3, $t3, $sp + sw $t2, 0($t3) + li $t1, 1 + li $t0, 4 + # Spilling t0 from $t9 + mul $t9, $t1, $t0 + # Spilling t1 from $t7 + li $t7, 4 + addi $t9, $t9, 8 + add $t9, $t9, $sp + sw $t7, 0($t9) + # Spilling t2 from $t3 + li $t3, 2 + # Spilling t3 from $t9 + li $t9, 4 + mul $t0, $t3, $t9 + #Pushing t4 to stack + sw $t0, 20($sp) + li $t0, 5 + lw $t0, 20($sp) + addi $t0, $t0, 8 + add $t0, $t0, $sp + sw $t0, 0($t0) + # Spilling t4 from $t0 + li $t0, 4 + li $t0, 0 + mul $t0, $t0, $t0 + addi $t0, $t0, 8 + add $t0, $t0, $sp + #Pushing t5 to stack + sw $t0, 24($sp) + lw $t0, 0($t0) + #Pushing t6 to stack + sw $t0, 28($sp) + #Pushing c to stack + sw $t0, 32($sp) + lw $t0, 28($sp) + move $t0, $t0 + la $a0, str0 + # Spilling t6 from $t0 + lw $t0, 32($sp) + move $a1, $t0 + #Pushing c to stack + sw $t0, 32($sp) +#printf + move $a0, $a0 + li $v0, 4 +syscall + li $v0, 4 + la $a0, newline + syscall + move $a0, $a1 + li $v0, 1 +syscall + li $v0, 4 + la $a0, newline + syscall + move $t0, $v0 + li $v0, 0 + lw $fp, 44($sp) + lw $ra, 48($sp) + li $v0, 10 + syscall diff --git a/Assignment4/output/output7.s b/Assignment4/output/output7.s new file mode 100644 index 0000000..e241e3f --- /dev/null +++ b/Assignment4/output/output7.s @@ -0,0 +1,71 @@ +# ====================================================================== +# No Errors in the code +# Intermediate code generated successfully +# ====================================================================== +.data +newline: .asciiz "\n" +str0: .asciiz "" +str1: .asciiz "Single level pointer value:" +.text +.globl main +main: + move $fp, $sp + addi $sp, $sp, -40 + sw $ra, 36($sp) + sw $fp, 32($sp) + li $t9, 0 + #Pushing i to stack + sw $t9, 0($sp) + addi $t8, $sp, 0 + lw $t9, 0($sp) + li $t7, 1 + add $t9, $t9, $t7 + la $a0, str0 + #Pushing i to stack + sw $t9, 0($sp) + lw $t6, 0($t8) + sw $t6, 4($sp) + move $a1, $t6 +#printf + move $a0, $a0 + li $v0, 4 +syscall + li $v0, 4 + la $a0, newline + syscall + move $a0, $a1 + li $v0, 1 +syscall + li $v0, 4 + la $a0, newline + syscall + move $t9, $v0 + li $t5, 50 + li $t4, 1 + sub $t5, $t5, $t4 + #Pushing y to stack + sw $t5, 8($sp) + addi $t3, $sp, 8 + la $a0, str1 + lw $t5, 0($t3) + sw $t5, 12($sp) + move $a1, $t5 +#printf + move $a0, $a0 + li $v0, 4 +syscall + li $v0, 4 + la $a0, newline + syscall + move $a0, $a1 + li $v0, 1 +syscall + li $v0, 4 + la $a0, newline + syscall + move $t2, $v0 + li $v0, 0 + lw $fp, 32($sp) + lw $ra, 36($sp) + li $v0, 10 + syscall diff --git a/Assignment4/output/output8.s b/Assignment4/output/output8.s new file mode 100644 index 0000000..22fcf54 --- /dev/null +++ b/Assignment4/output/output8.s @@ -0,0 +1,155 @@ +# ====================================================================== +# No Errors in the code +# Intermediate code generated successfully +# ====================================================================== +.data +newline: .asciiz "\n" +str0: .asciiz "c is" +str1: .asciiz "c is" +str2: .asciiz "c is" +str3: .asciiz "c is" +str4: .asciiz "i is" +.text +.globl main +main: + move $fp, $sp + addi $sp, $sp, -76 + sw $ra, 72($sp) + sw $fp, 68($sp) + li $t9, 3 + li $t8, 10 + li $t7, 1 + seq $t6, $t9, $t7 + bnez $t6, LABEL0 + li $t5, 2 + seq $t4, $t9, $t5 + bnez $t4, LABEL1 + li $t3, 3 + seq $t2, $t9, $t3 + bnez $t2, LABEL2 + j LABEL3 +LABEL0: + add $t1, $t9, $t8 + move $t0, $t1 + la $a0, str0 + move $a1, $t0 + # Spilling t10 from $t2 +#printf + move $a0, $a0 + li $v0, 4 +syscall + li $v0, 4 + la $a0, newline + syscall + move $a0, $a1 + li $v0, 1 +syscall + li $v0, 4 + la $a0, newline + syscall + move $t2, $v0 + j LABEL4 +LABEL1: + # Spilling t8 from $t6 + sub $t6, $t9, $t8 + move $t0, $t6 + la $a0, str1 + move $a1, $t0 + # Spilling t9 from $t4 +#printf + move $a0, $a0 + li $v0, 4 +syscall + li $v0, 4 + la $a0, newline + syscall + move $a0, $a1 + li $v0, 1 +syscall + li $v0, 4 + la $a0, newline + syscall + move $t4, $v0 + j LABEL4 +LABEL2: + # Spilling t0 from $t1 + mul $t1, $t9, $t8 + move $t0, $t1 + la $a0, str2 + move $a1, $t0 + # Spilling t1 from $t2 +#printf + move $a0, $a0 + li $v0, 4 +syscall + li $v0, 4 + la $a0, newline + syscall + move $a0, $a1 + li $v0, 1 +syscall + li $v0, 4 + la $a0, newline + syscall + move $t2, $v0 + j LABEL4 +LABEL3: + # Spilling t2 from $t6 + div $t9, $t8 + mflo $t6 + move $t0, $t6 + la $a0, str3 + move $a1, $t0 + # Spilling a from $t9 +#printf + move $a0, $a0 + li $v0, 4 +syscall + li $v0, 4 + la $a0, newline + syscall + move $a0, $a1 + li $v0, 1 +syscall + li $v0, 4 + la $a0, newline + syscall + move $t9, $v0 +LABEL4: + # Spilling b from $t8 + li $t8, 2 +LABEL5: + # Spilling c from $t0 + li $t0, 0 + # Spilling t3 from $t4 + slt $t4, $t8, $t0 + bnez $t4, LABEL6 + j LABEL7 +LABEL7: + la $a0, str4 + move $a1, $t8 + # Spilling t11 from $t4 +#printf + move $a0, $a0 + li $v0, 4 +syscall + li $v0, 4 + la $a0, newline + syscall + move $a0, $a1 + li $v0, 1 +syscall + li $v0, 4 + la $a0, newline + syscall + move $t4, $v0 + # Spilling t4 from $t1 + li $t1, 1 + sub $t8, $t8, $t1 + j LABEL5 +LABEL6: + li $v0, 0 + lw $fp, 68($sp) + lw $ra, 72($sp) + li $v0, 10 + syscall diff --git a/Assignment4/peep.c b/Assignment4/peep.c new file mode 100644 index 0000000..c76652a --- /dev/null +++ b/Assignment4/peep.c @@ -0,0 +1,36 @@ +int main() { + int a = 5, b = 10, c = 15, d = 20; + + // Redundant calculation + int x = a * 2; + int y = a + a; + + // Constant folding + int z = 4 * 5; + float w = 30.0 / 5.0; + + // Strength reduction + int u = d * 8; + + // Dead code (if optimization is enabled) + int unused = 100; + + // Combine multiple increments + int counter = 0; + counter = counter + 1; + counter = counter + 1; + counter = counter + 1; + + int temp = b; + temp = temp;// Useless assignment + + if (1) { + printf("This branch is always taken.\n"); + } else { + printf("This branch is never taken.\n"); + } + + printf("Results: x=%d, y=%d, z=%d, w=%f, u=%d, counter=%d\n", x, y, z, w, u, counter); + + return 0; +} diff --git a/Assignment4/run.sh b/Assignment4/run.sh new file mode 100755 index 0000000..4c40299 --- /dev/null +++ b/Assignment4/run.sh @@ -0,0 +1,20 @@ +#!/bin/bash + +# Define paths +EXEC="./parser" +TEST_DIR="./test" +OUTPUT_DIR="./output" + +# Create output directory if not exists +mkdir -p $OUTPUT_DIR + +# Run parser on each test file and store output separately +counter=1 +for testfile in $TEST_DIR/*.c; do + output_file="$OUTPUT_DIR/output${counter}.s" + echo "Processing $(basename "$testfile") -> $(basename "$output_file")" + $EXEC < "$testfile"> "$output_file" 2>&1 + ((counter++)) +done + +# echo "All test cases executed. Outputs stored in $OUTPUT_DIR." diff --git a/Assignment4/src/codegen.cpp b/Assignment4/src/codegen.cpp new file mode 100644 index 0000000..854ce3b --- /dev/null +++ b/Assignment4/src/codegen.cpp @@ -0,0 +1,1824 @@ +#include +#include +#include +using namespace std; +int currentInstructionIndex = -1; +static int paramCounter = 0; +static int paramFloatCounter = 0; +int paramReceiveCounter = 0; +int param_receive_offset=0; +int paramFloatReceiveCounter = 0; +int string_counter = 0; +scoped_symtab* globalscope; +map,string> var_to_reg; +map> reg_to_var; +std::vector> static_var; +map scope_id; +map funcStackSize; +map size_of_extra_parameters; +stack last_offset; +vector functionparams; +// --- Global Variables --- +map regMap; +static vector argRegisters = {"$a0", "$a1", "$a2", "$a3"}; +vector availableRegs = {"$t0", "$t1", "$t2", "$t3", "$t4", "$t5","$t6", "$t7", "$t8", "$t9"}; +vector availableFloatRegs = {"$f0", "$f1", "$f2", "$f3", "$f4", "$f5", "$f6", "$f7","$f8", "$f9", "$f10", "$f11", "$f12", "$f13", "$f14", "$f15", "$f16", "$f17", "$f18", "$f19", "$f20", "$f21", "$f22", "$f23", "$f24", "$f25", "$f26", "$f27", "$f28", "$f29", "$f30", "$f31"}; +map, string> floatVarToReg; +vector availableDoubleRegs={"$f0","$f2","$f4","$f6","$f8","$f10","$f12","$f14","$f16","$f18","$f20","$f22","$f24","$f26","$f28","$f30"}; +map, string> doubleVarToReg; +vector mipsCode; +vector data_section; +vector paramtype; +map string_to_label; +map loadedConstants; +map reg_of_const; +vector reg_for_scanf; +vector var_for_printf; +map> offset_to_var; +map,int> pointer_to_offset; +int get_size_from_type(string type); +void handle_function_call(const string& line); + +struct pair_hash { + template + size_t operator()(const pair& p) const { + return hash()(p.first) ^ (hash()(p.second) << 1); + } +}; + +struct LivenessInfo { + scoped_symtab* scope; + string code; + unordered_set, pair_hash> use, def, live_in, live_out; + vector successors; + int index; +}; + +vector currentLiveness; + +vector operators = { + "==", "!=", "<=", ">=", "&&", "||", "+=", "-=", "*=", "/=", "%=", + "<<", ">>", "<", ">", "+", "-", "*", "/", "%", "=", "&", "|", "^", "!", "~" +}; + +string trim(const string& s) { + size_t start = s.find_first_not_of(" \t\r\n"); + size_t end = s.find_last_not_of(" \t\r\n"); + return (start == string::npos) ? "" : s.substr(start, end - start + 1); +} + +bool isIntLiteral(const string& s) { + return !s.empty() && all_of(s.begin(), s.end(), ::isdigit); +} + +bool isCharLiteral(const std::string& s) { + return s.length() >= 3 && s.front() == '\'' && s.back() == '\'' && s.length() == 3; +} +bool isStringLiteral(const std::string& s) { + return s.length() >= 2 && s.front() == '"' && s.back() == '"'; +} + +bool isFloatLiteral(const string& s) { + size_t dotPos = s.find('.'); + if (dotPos == string::npos) return false; + + string intPart = s.substr(0, dotPos); + string fracPart = s.substr(dotPos + 1); + + return !intPart.empty() && !fracPart.empty() && + all_of(intPart.begin(), intPart.end(), ::isdigit) && + all_of(fracPart.begin(), fracPart.end(), ::isdigit); +} + + +scoped_symtab* getScope(scoped_symtab* scope, string& var) { + if (var=="PARAM"||var=="CALL"||var=="RETURN") return scope; + while(scope != nullptr) { + if (scope->symbol_map.count(var)) { + return scope; + } + scope = scope->parent; + } + return nullptr; +} + + +// Pushes a variable from register to stack, handles different data types + +void push_into_stack(pair varPair){ + mipsCode.push_back(" #Pushing " + varPair.second + " to stack"); + scoped_symtab* scope = varPair.first; + string var = varPair.second; + symbol_info* sym = scope->symbol_map[var]; + string type=sym->type; + string reg; + if(type.find("struct") != string::npos || type.find("union") != string::npos){ + reg=var_to_reg[{scope, var}]; + availableRegs.push_back(reg); + return; + + } + if(type.substr(0,3)=="int") reg = var_to_reg[{scope, var}]; + else if(type.substr(0,5)=="float") reg = floatVarToReg[{scope, var}]; + else if(type.substr(0,6)=="double"){ + reg = doubleVarToReg[{scope, var}]; + } + if(scope->symbol_map[var]->offset == -1){ + sym->offset = last_offset.top(); + last_offset.top()+=get_size_from_type(sym->type); + if(type.substr(0,3)=="int") + mipsCode.push_back(" sw " + reg + ", " + to_string(sym->offset) + "($sp)"); + else if(type.substr(0,5)=="float") + mipsCode.push_back(" s.s " + reg + ", " + to_string(sym->offset) + "($sp)"); + else if(type.substr(0,6)=="double") + mipsCode.push_back(" s.d " + reg + ", " + to_string(sym->offset) + "($sp)"); + else{ + return; + } + }else{ + if(type.substr(0,3)=="int") + mipsCode.push_back(" sw " + reg + ", " + to_string(sym->offset) + "($sp)"); + else if(type.substr(0,5)=="float") + mipsCode.push_back(" s.s " + reg + ", " + to_string(sym->offset) + "($sp)"); + else if(type.substr(0,6)=="double") + mipsCode.push_back(" s.d " + reg + ", " + to_string(sym->offset) + "($sp)"); + else{ + return; + } + } + if(type.substr(0,3)=="int") + { + availableRegs.push_back(reg); + var_to_reg.erase({scope, var}); + } + else if(type.substr(0,5)=="float") + { + + floatVarToReg.erase({scope, var}); + } + else if(type.substr(0,6)=="double") + { + + doubleVarToReg.erase({scope, var}); + } + else{ + return; + } + + reg_to_var.erase(reg); +} + +// Handles register spill for double precision values by finding unused registers + +void handleDoubleRegisterSpill(scoped_symtab* currentScope, const string& newVar) { + + for (auto it = doubleVarToReg.begin(); it != doubleVarToReg.end(); ++it) { + auto [vscope, vname] = it->first; + string reg = it->second; + + bool usedNow = currentLiveness[currentInstructionIndex] + .use.count({vscope, vname}); + bool liveFuture = false; + for (int i = currentInstructionIndex + 1; + i < (int)currentLiveness.size(); ++i) { + if (currentLiveness[i].live_in.count({vscope, vname})) { + liveFuture = true; + break; + } + } + + if (!usedNow && !liveFuture) { + mipsCode.push_back(" # Spilling " + vname + " from " + reg); + availableDoubleRegs.push_back(reg); + availableFloatRegs.push_back(reg); + int num = stoi(reg.substr(2)); + string odd = "$f" + to_string(num + 1); + availableFloatRegs.push_back(odd); + doubleVarToReg.erase(it); + return; + } + } + + for (auto fit = floatVarToReg.begin(); fit != floatVarToReg.end(); ++fit) { + auto [vscope, vname] = fit->first; + string reg = fit->second; + + bool usedNow = currentLiveness[currentInstructionIndex] + .use.count({vscope, vname}); + bool liveFuture = false; + for (int i = currentInstructionIndex + 1; + i < (int)currentLiveness.size(); ++i) { + if (currentLiveness[i].live_in.count({vscope, vname})) { + liveFuture = true; + break; + } + } + if (usedNow || liveFuture) + continue; + + int num = stoi(reg.substr(2)); + bool regIsEven = (num % 2 == 0); + string buddy = "$f" + to_string(regIsEven ? num + 1 : num - 1); + auto budIt = find_if( + floatVarToReg.begin(), floatVarToReg.end(), + [&](auto const& kv){ return kv.second == buddy; } + ); + if (budIt == floatVarToReg.end()) + continue; + auto [bScope, bName] = budIt->first; + bool budUsedNow = currentLiveness[currentInstructionIndex] + .use.count({bScope, bName}); + bool budLiveFuture = false; + for (int i = currentInstructionIndex + 1; + i < (int)currentLiveness.size(); ++i) { + if (currentLiveness[i].live_in.count({bScope, bName})) { + budLiveFuture = true; + break; + } + } + if (budUsedNow || budLiveFuture) + continue; + + mipsCode.push_back(" # Spilling " + vname + " from " + reg); + availableFloatRegs.push_back(reg); + floatVarToReg.erase(fit); + + mipsCode.push_back(" # Spilling " + bName + " from " + buddy); + availableFloatRegs.push_back(buddy); + floatVarToReg.erase(budIt); + + string evenReg = regIsEven ? reg : buddy; + auto dit = find(availableDoubleRegs.begin(), + availableDoubleRegs.end(), evenReg); + if (dit != availableDoubleRegs.end()) + availableDoubleRegs.erase(dit); + + doubleVarToReg[{currentScope, newVar}] = evenReg; + return; + } + + auto dit = doubleVarToReg.begin(); + auto varPair = dit->first; + string regToSpill = dit->second; + mipsCode.push_back(" # Spilling " + varPair.second + + " from " + regToSpill); + availableDoubleRegs.push_back(regToSpill); + int n = stoi(regToSpill.substr(2)); + string odd2 = "$f" + to_string(n + 1); + availableFloatRegs.push_back(regToSpill); + availableFloatRegs.push_back(odd2); + doubleVarToReg.erase(dit); + push_into_stack(varPair); +} + + +// Manages register spilling for floating point values when no free registers are available +void handleFloatRegisterSpill(scoped_symtab* currentScope, const string& newVar) { + + for (auto it = floatVarToReg.begin(); it != floatVarToReg.end(); ++it) { + auto [vscope, vname] = it->first; + string reg = it->second; + + bool usedNow = currentLiveness[currentInstructionIndex] + .use.count({vscope, vname}); + bool liveFuture = false; + for (int i = currentInstructionIndex + 1; + i < (int)currentLiveness.size(); ++i) { + if (currentLiveness[i].live_in.count({vscope, vname})) { + liveFuture = true; + break; + } + } + + if (!usedNow && !liveFuture) { + mipsCode.push_back(" # Spilling " + vname + " from " + reg); + availableFloatRegs.push_back(reg); + int reg_num = stoi(reg.substr(2)); + if(reg_num%2==1) + { + string pair=reg.substr(0,2)+to_string(reg_num-1); + if(find(availableFloatRegs.begin(), availableFloatRegs.end(), pair) != availableFloatRegs.end()) + { + availableDoubleRegs.push_back(pair); + } + + } + else{ + string pair=reg.substr(0,2)+to_string(reg_num+1); + if(find(availableFloatRegs.begin(), availableFloatRegs.end(), pair) != availableFloatRegs.end()) + { + availableDoubleRegs.push_back(reg); + } + } + floatVarToReg.erase(it); + return; + } + } + + for (auto it = doubleVarToReg.begin(); it != doubleVarToReg.end(); ++it) { + auto [vscope, vname] = it->first; + string reg = it->second; + + bool usedNow = currentLiveness[currentInstructionIndex] + .use.count({vscope, vname}); + bool liveFuture = false; + for (int i = currentInstructionIndex + 1; + i < (int)currentLiveness.size(); ++i) { + if (currentLiveness[i].live_in.count({vscope, vname})) { + liveFuture = true; + break; + } + } + + if (!usedNow && !liveFuture) { + mipsCode.push_back(" # Spilling double " + vname + " from " + reg); + string pair=reg.substr(0,2)+to_string(stoi(reg.substr(2))+1); + availableDoubleRegs.push_back(reg); + availableFloatRegs.push_back(reg); + availableFloatRegs.push_back(pair); + doubleVarToReg.erase(it); + return; + } + } + + auto it = floatVarToReg.begin(); + auto varPair = it->first; + string reg = it->second; + mipsCode.push_back(" # Spilling " + varPair.second + " from " + reg); + availableFloatRegs.push_back(reg); + int reg_num = stoi(reg.substr(2)); + if(reg_num%2==1) + { + string pair=reg.substr(0,2)+to_string(reg_num-1); + if(find(availableFloatRegs.begin(), availableFloatRegs.end(), pair) != availableFloatRegs.end()) + { + availableDoubleRegs.push_back(pair); + } + + } + else{ + string pair=reg.substr(0,2)+to_string(reg_num+1); + if(find(availableFloatRegs.begin(), availableFloatRegs.end(), pair) != availableFloatRegs.end()) + { + availableDoubleRegs.push_back(reg); + } + } + floatVarToReg.erase(it); + + push_into_stack(varPair); +} + + + +// Manages register spilling for integer values by selecting least-used registers + +void handleRegisterSpill(scoped_symtab* currentScope, string& newVar) { + int maxdist=0; + string regi="$t0"; + for (auto it = var_to_reg.begin(); it != var_to_reg.end(); ++it) { + auto [vscope, vname] = it->first; + string reg = it->second; + bool isUsedNow = currentLiveness[currentInstructionIndex].use.count({vscope, vname}); + bool isLiveInFuture = false; + + for (int i = currentInstructionIndex + 1; i < currentLiveness.size(); ++i) { + if (currentLiveness[i].live_in.count({vscope, vname})) { + if (currentLiveness[i].index - currentInstructionIndex > maxdist && !isUsedNow) { + maxdist = currentLiveness[i].index - currentInstructionIndex; + regi = reg; + } + isLiveInFuture = true; + break; + } + } + if (!isLiveInFuture && !isUsedNow) { + mipsCode.push_back(" # Spilling " + vname + " from " + reg); + availableRegs.push_back(reg); + reg_to_var.erase(reg); + var_to_reg.erase({vscope, vname}); + return; + } + } + pair varPair = reg_to_var[regi]; + if(varPair.second==""){ + availableRegs.push_back(regi); + reg_to_var.erase(regi); + + return; + } + push_into_stack(varPair); +} + +// Returns a float register for a variable, handling register allocation for both float and double types + +string getFloatRegister(scoped_symtab* scope, string& var,string type="float") { + scope = getScope(scope, var); + if (availableFloatRegs.empty()) { + exit(1); + } + if(type=="float") + { + if (floatVarToReg.count({scope, var})) return floatVarToReg[{scope, var}]; + + string freg = availableFloatRegs.back(); + availableFloatRegs.pop_back(); + string correspondingdreg=freg; + if(stoi(freg.substr(2))%2==1) + { + correspondingdreg="$f"+to_string(stoi(freg.substr(2))-1); + } + auto it = find(availableDoubleRegs.begin(), availableDoubleRegs.end(), correspondingdreg); + if (it != availableDoubleRegs.end()) availableDoubleRegs.erase(it); + floatVarToReg[{scope, var}] = freg; + return freg; + } + else if(type=="double") + { + if (doubleVarToReg.count({scope, var})) return doubleVarToReg[{scope, var}]; + + string freg = availableDoubleRegs.back(); + availableDoubleRegs.pop_back(); + string s="$f"+to_string(stoi(freg.substr(2))+1); + auto it = find(availableFloatRegs.begin(), availableFloatRegs.end(), freg); + if (it != availableFloatRegs.end()) availableFloatRegs.erase(it); + auto it2=find(availableFloatRegs.begin(), availableFloatRegs.end(), s); + if(it2 != availableFloatRegs.end()) availableFloatRegs.erase(it2); + doubleVarToReg[{scope, var}] = freg; + return freg; + } + +} + +// Returns a register for a variable, handling cases like constants and variables already in registers + +string getRegister(scoped_symtab* scope, string& var) { + if(isIntLiteral(var)){ + if(availableRegs.empty()) handleRegisterSpill(scope,var); + string reg = availableRegs.back(); + availableRegs.pop_back(); + return reg; + } + scope = getScope(scope, var); + if(var_to_reg.count({scope,var})) { + return var_to_reg[{scope,var}]; + } + + if (availableRegs.empty()) { + handleRegisterSpill(scope,var); + } + if(scope->symbol_map[var]->offset != -1){ + string reg = availableRegs.back(); + availableRegs.pop_back(); + mipsCode.push_back(" lw " + reg + ", " + to_string(scope->symbol_map[var]->offset) + "($sp)"); + var_to_reg[{scope,var}] = reg; + reg_to_var[reg] = {scope,var}; + return reg; + } + string reg = availableRegs.back(); + availableRegs.pop_back(); + var_to_reg[{scope,var}] = reg; + reg_to_var[reg] = {scope,var}; + return reg; +} + +// Returns a register for a variable, handling cases like constants and variables already in registers + +pair find_operator(const string& line) { + string detectedOp; + size_t opPos = string::npos; + for (const string& op : operators) { + size_t pos = line.find(op); + if (pos != string::npos && (opPos == string::npos || pos < opPos)) { + opPos = pos; + detectedOp = op; + } + } + return {opPos, detectedOp}; +} + +// Generates MIPS code for function entry, setting up stack frame and saving registers + + +void generate_func_begin_MIPS(const string &func, int stackSize) { + if (func != "main") + stackSize += 40; + mipsCode.push_back(func + ":"); + mipsCode.push_back(" move $fp, $sp"); + mipsCode.push_back(" addi $sp, $sp, -" + to_string(stackSize) ); + mipsCode.push_back(" sw $ra, " + to_string(stackSize - 4) + "($sp)"); + mipsCode.push_back(" sw $fp, " + to_string(stackSize - 8) + "($sp)"); + if (func != "main") + { + int spillCount = 10; + int slot = 0; + for (int i = 0; i < spillCount; i++){ + string reg = "$t" + to_string(i); + mipsCode.push_back(" sw " + reg + ", " + to_string(stackSize - 12 - 4*slot) + "($sp)"); + slot++; + } + } + last_offset.push(0); +} + +// Cleans up at function end, restoring registers and stack pointer + + +void generate_func_end_MIPS( string &func, int stackSize) { + if(!last_offset.empty()) + last_offset.pop(); +} + +// Generates MIPS code for return statements, restoring registers and frame pointer + + +void generate_return_MIPS(string& func, scoped_symtab* scope,string val) { + if(val.empty()){ + // cerr << "HERE" << endl; + //void + } + else if(isIntLiteral(val)) + { + mipsCode.push_back(" li $v0, " + val); + } + else if(isFloatLiteral(val)) + { + mipsCode.push_back(" li.s $f0, " + val); + } + else { + string type=globalscope->symbol_map[func]->type; + string reg; + if(type=="float") + { + reg=getFloatRegister(scope,val); + mipsCode.push_back(" mov.s $f0, " + reg); + } + else{ + reg=getRegister(scope,val); + mipsCode.push_back(" move $v0, " + reg); + } + + } + int stackSize = funcStackSize[func]; + if(func!="main")stackSize += 40; + mipsCode.push_back(" lw $fp, " + to_string(stackSize - 8) + "($sp)"); + mipsCode.push_back(" lw $ra, " + to_string(stackSize - 4) + "($sp)"); + if(func != "main"){ + int slot = 0, spillCount = 10; + for (int i = 0; i < spillCount; i++){ + string reg = "$t" + to_string(i); + mipsCode.push_back(" lw " + reg + ", " + to_string(stackSize - 12 - 4*slot) + "($sp)"); + slot++; + } + mipsCode.push_back(" addi $sp, $sp, " + to_string(stackSize)); + } + if(func!="main") mipsCode.push_back(" jr $ra"); + +} + +// Loads constants (integer or float) into registers + +void load_if_constant(scoped_symtab* scope, string& var, const string& reg) { + if (isIntLiteral(var)) { + mipsCode.push_back(" li " + reg + ", " + var); + loadedConstants[var] = true; + reg_of_const[var] = reg; + return; + } + + if (isFloatLiteral(var)) { + string floatLabel = "float_const_" + var; // like float_const_3.14 + static set emittedFloats; + if (!emittedFloats.count(var)) { + emittedFloats.insert(var); + mipsCode.insert(mipsCode.begin(), floatLabel + ": .float " + var); + } + if(availableRegs.empty()) handleRegisterSpill(scope,var); + string reg1 = availableRegs.back(); + mipsCode.push_back(" la " + reg1 + ", " + floatLabel); + mipsCode.push_back(" l.s " + reg + ", 0(" + reg1 + ")"); + loadedConstants[var] = true; + reg_of_const[var] = reg; + return; + } + + symbol_info* sym = scope->symbol_map[var]; + if (sym && sym->ptr) { + if (sym->type == "int") { + int* val = static_cast(sym->ptr); + mipsCode.push_back(" li " + reg + ", " + to_string(*val)); + loadedConstants[var] = true; + reg_of_const[var] = reg; + } else if (sym->type == "float") { + float* val = static_cast(sym->ptr); + string valStr = to_string(*val); + string floatLabel = "float_sym_" + var; + mipsCode.insert(mipsCode.begin(), floatLabel + ": .float " + valStr); + + mipsCode.push_back(" la " + reg + ", " + floatLabel); + mipsCode.push_back(" l.s " + reg + ", 0(" + reg + ")"); + loadedConstants[var] = true; + reg_of_const[var] = reg; + } + } +} + +// Handles arithmetic and comparison operations between two operands + + +void handle_operation(string lhs, string rhs, size_t operator_pos, const string& opp, scoped_symtab* scope) { + bool isFloat; + isFloat = (getScope(scope,lhs)->symbol_map[lhs]->type == "float"); + string op1 = trim(rhs.substr(0, operator_pos)); + string op2 = trim(rhs.substr(operator_pos + opp.size())); + vector> stat; + if (isFloat){ + string r1,r2,rd; + string rx,ry; + if(isFloatLiteral(op1)){ + if(availableFloatRegs.empty()) handleRegisterSpill(scope,op1); + r1=availableFloatRegs.back(); + rx=r1; + availableFloatRegs.pop_back(); + load_if_constant(scope, op1, r1); + } + else{ + int fl=0; + + for(auto x:static_var){ + if(x.first==scope && x.second==op1){ + r1 = getRegister(scope,op1); + mipsCode.push_back(" la " + r1 + ", " + "static_" + op1); + string rr=getFloatRegister(scope,op1); + mipsCode.push_back(" l.s "+rr+", 0("+r1+")"); + floatVarToReg[{scope,op1}] = rr; + reg_to_var[rr] = {scope,op1}; + fl=1; + rx=rr; + break; + + } + } + if(fl==0){ + string typ = getScope(scope,op1)->symbol_map[op1]->type; + if(typ == "int"){ + string r1 = getRegister(scope,op1); + string tempr = getFloatRegister(scope,op1); + mipsCode.push_back(" mtc1 " + r1 + ", " + tempr); + mipsCode.push_back(" cvt.s.w " + tempr+ ", " + tempr); + rx = tempr; + } + else{ + string tempr = getFloatRegister(scope,op1); + rx = tempr; + } + } + + + } + if(isFloatLiteral(op2)){ + if(availableFloatRegs.empty()) handleRegisterSpill(scope,op1); + r2=availableFloatRegs.back(); + ry=r2; + availableFloatRegs.pop_back(); + load_if_constant(scope, op2, r2); + } + else{ + int fl=0; + + for(auto x:static_var){ + if(x.first==scope && x.second==op1){ + r2 = getRegister(scope,op1); + mipsCode.push_back(" la " + r2 + ", " + "static_" + op2); + string rr=getFloatRegister(scope,op2); + mipsCode.push_back(" l.s "+rr+", 0("+r2+")"); + floatVarToReg[{scope,op1}] = rr; + reg_to_var[rr] = {scope,op1}; + fl=1; + ry=rr; + break; + + } + } + if(fl==0){ + string typ = getScope(scope,op2)->symbol_map[op2]->type; + if(typ == "int"){ + string r1 = getRegister(scope,op2); + string tempr = getFloatRegister(scope,op2); + mipsCode.push_back(" mtc1 " + r1 + ", " + tempr); + mipsCode.push_back(" cvt.s.w " + tempr+ ", " + tempr); + ry = tempr; + } + else{ + string tempr = getFloatRegister(scope,op2); + ry = tempr; + } + } + + } + rd = getFloatRegister(scope,lhs); + + if (opp == "+") mipsCode.push_back(" add.s " + rd + ", " + rx + ", " + ry ); + else if (opp == "-") mipsCode.push_back(" sub.s " + rd + ", " + rx + ", " + ry ); + else if (opp == "*") mipsCode.push_back(" mul.s " + rd + ", " + rx + ", " + ry ); + else if (opp == "/") mipsCode.push_back(" div.s " + rd + ", " + rx + ", " + ry ); + return; + } + string r1,r2,rd; + + if(isIntLiteral(op1)){ + if(availableRegs.empty()) handleRegisterSpill(scope,op1); + r1=availableRegs.back(); + availableRegs.pop_back(); + load_if_constant(scope, op1, r1); + } + else{ + int fl=0; + + for(auto x:static_var){ + if(getScope(x.first,op1)==scope && x.second==op1){ + r1 = getRegister(scope,op1); + mipsCode.push_back(" lw " + r1 + ", " + "static_" + op1); + stat.push_back({r1,"static_" + op1}); + var_to_reg[{scope,op1}] = r1; + reg_to_var[r1] = {scope,op1}; + fl=1; + break; + + } + } + if(fl==0){ + r1 = getRegister(scope,op1); + } + + } + if(isIntLiteral(op2)){ + if(availableRegs.empty()) handleRegisterSpill(scope,op1); + r2=availableRegs.back(); + availableRegs.pop_back(); + load_if_constant(scope, op2, r2); + } + else{ + int fl=0; + + for(auto x:static_var){ + if(getScope(x.first,op2)==scope && x.second==op2){ + r2 = getRegister(scope,op2); + mipsCode.push_back(" lw " + r2 + ", " + "static_" + op2); + var_to_reg[{scope,op2}] = r2; + reg_to_var[r2] = {scope,op2}; + fl=1; + break; + + } + } + if(fl==0){ + r2 = getRegister(scope,op2); + } + } + for(auto x:static_var){ + if(getScope(x.first,lhs)==scope && x.second==lhs){ + rd=getRegister(scope,lhs); + mipsCode.push_back(" lw " + rd + ", " + "static_" + lhs); + stat.push_back({rd,"static_" + lhs}); + var_to_reg[{scope,lhs}] = rd; + reg_to_var[rd] = {scope,lhs}; + } + } + rd = getRegister(scope,lhs); + if (opp == "+") mipsCode.push_back(" add " + rd + ", " + r1 + ", " + r2); + else if (opp == "-") mipsCode.push_back(" sub " + rd + ", " + r1 + ", " + r2); + else if (opp == "*") mipsCode.push_back(" mul " + rd + ", " + r1 + ", " + r2); + else if (opp == "/") { + mipsCode.push_back(" div " + r1 + ", " + r2); + mipsCode.push_back(" mflo " + rd); + } + else if(opp=="=="){ + mipsCode.push_back(" seq " + rd + ", " + r1 + ", " + r2); + } + else if (opp == "!=") mipsCode.push_back(" sne " + rd + ", " + r1 + ", " + r2); + else if (opp == "<") mipsCode.push_back(" slt " + rd + ", " + r1 + ", " + r2); + else if (opp == "<=") { + mipsCode.push_back(" slt " + rd + ", " + r2 + ", " + r1); + mipsCode.push_back(" xori " + rd + ", " + rd + ", 1"); + } + else if (opp == ">") mipsCode.push_back(" slt " + rd + ", " + r2 + ", " + r1); + else if (opp == ">=") { + mipsCode.push_back(" slt " + rd + ", " + r1 + ", " + r2); + mipsCode.push_back(" xori " + rd + ", " + rd + ", 1"); + } + for(auto x:stat) mipsCode.push_back(" sw " + x.first + ", " + x.second); + +} + +// Processes assignment statements, handling different data types + + +void handle_assignment(string lhs, string rhs, scoped_symtab* scope) { + + for(auto x:static_var){ + if(getScope(scope,lhs)==x.first && x.second==lhs){ + string r1=getRegister(scope,lhs); + mipsCode.push_back(" lw " + r1 + ", " + "static_" + lhs); + var_to_reg[{scope,lhs}] = r1; + reg_to_var[r1] = {scope,lhs}; + string rr=getRegister(scope,rhs); + if(isIntLiteral(rhs)){ + mipsCode.push_back(" li " + rr + ", " + rhs); + } + mipsCode.push_back(" move " + r1 + ", " + rr); + mipsCode.push_back(" sw " + r1 + ", " + "static_" + lhs); + return; + } + } + symbol_info* lhsInfo = getScope(scope,lhs)->symbol_map[lhs]; + bool isFloat = (lhsInfo && lhsInfo->type == "float" && rhs.find("CALL") == string::npos && rhs.find("alloc") == string::npos); + bool isDouble = (lhsInfo && lhsInfo->type == "double" && rhs.find("CALL") == string::npos && rhs.find("alloc") == string::npos); + if (isFloat) { + string dst = getFloatRegister(scope, lhs); + if (isFloatLiteral(rhs)) { + + mipsCode.push_back(" li.s " + dst + ", " + rhs); + } + else if (isIntLiteral(rhs)) { + + mipsCode.push_back(" li.s " + dst + ", " + rhs+".0"); + } + else { + string src = getFloatRegister(scope, rhs); + mipsCode.push_back(" mov.s " + dst + ", " + src); + } + return; + } + + else if (isDouble) { + string dst = getFloatRegister(scope, lhs,"double"); + if (isFloatLiteral(rhs)) { + mipsCode.push_back(" li.d " + dst + ", " + rhs); + } + else if (isIntLiteral(rhs)) { + + mipsCode.push_back(" li.d " + dst + ", " + rhs+".0"); + } + else { + string src = getFloatRegister(scope, rhs,"double"); + mipsCode.push_back(" mov.d " + dst + ", " + src); + } + return; + } + if(rhs.find("alloc")!=string::npos){ + int rest=stoi(rhs.substr(rhs.find("alloc")+6)); + lhsInfo->offset=last_offset.top(); + last_offset.top()+=rest; + return; + } + string dst = getRegister(scope,lhs); + if(rhs.find("CALL") != string::npos){ + handle_function_call(rhs); + istringstream iss(rhs); + string call, funcWithComma; + int argCount; + iss >> call >> funcWithComma; + iss.ignore(); + iss >> argCount; + int arg_no=0; + string funcName = trim(funcWithComma); + if (!funcName.empty() && funcName.back() == ',') funcName.pop_back(); + if(funcName.find(",")!=string::npos){ + arg_no=stoi(funcName.substr(funcName.find(",")+1)); + funcName = funcName.substr(0,funcName.find(",")); + } + if(globalscope->symbol_map[funcName]->type=="float"){ + string dst1 = getFloatRegister(scope, lhs); + mipsCode.push_back(" mov.s " + dst1 + ", $f0"); + } + else mipsCode.push_back(" move " + dst + ", $v0"); + + return; + } + if (isIntLiteral(rhs)||isCharLiteral(rhs)) { + mipsCode.push_back(" li " + dst + ", " + rhs); + loadedConstants[lhs] = true; + reg_of_const[rhs]=dst; + } + else if(isFloatLiteral(rhs)) { + string dst1 = getFloatRegister(scope, lhs); + mipsCode.push_back(" li.s " + dst1 + ", " + rhs); + } + else { + string src = getRegister(scope,rhs); + mipsCode.push_back(" move " + dst + ", " + src); + } +} + +int get_symbol_size(symbol_info* sym) { + if (sym->is_array) { + return sym->symbol_size * sym->array_length; + } + if (!sym->struct_attr_values.empty()) { + int total = 0; + for (auto* attr : sym->struct_attr_values) { + total += get_symbol_size(attr); + } + return total; + } + if (sym->pointer_depth > 0) { + return 4; + } + return sym->symbol_size; +} + +int get_size_from_type(string type) { + if (type == "int") return 4; + else if (type == "float") return 4; + else if(type == "char")return 4; + else if(type == "bool")return 1; + else if(type=="double")return 8; + return 4; +} + +int calculate_function_stack_size(scoped_symtab* scope) { + int size = 0; + for (const auto& [name, sym] : scope->symbol_map) { + if (!sym->is_param_list && !sym->is_return) { + size += sym->type == "string" ? get_symbol_size(sym) : get_size_from_type(sym->type); + } + } + return size; +} + +int space_for_extra_params(symbol_info* sym) { + int size = 0; + if (sym->param_list.size() > 4) { + for (int i=4; i < sym->param_list.size(); ++i) { + size += get_size_from_type(sym->param_types[i]); + } + } + return size; +} +string newstring(){ + string label = "str" + to_string(string_counter); + string_counter++; + return label; +} + +// Handles function parameter passing for function calls + +void handle_param_pass(const string& line, scoped_symtab* scope) { + string var = trim(line.substr(5)); // after "PARAM" + if(var[0] == '&')var = var.substr(1); + string srcReg; + if(isStringLiteral(var)) + { + string literal = var; + size_t pos = var.find('%'); + if (pos != string::npos) { + literal = var.substr(0, pos); + } + else literal.pop_back(); + size_t start = literal.find_first_not_of(' '); + size_t end = literal.find_last_not_of(' '); + if (start != string::npos && end != string::npos) { + literal = literal.substr(start, end - start + 1); + literal=literal+"\""; + } else { + literal = ""; + } + string str=newstring(); + data_section.push_back(str+": .asciiz "+literal); + string_to_label[var]=str; + mipsCode.push_back(" la $a0, " + str); + paramCounter++; + paramtype.push_back("string"); + return; + } + if(isIntLiteral(var)){ + paramtype.push_back("int"); + if (paramCounter >= argRegisters.size()) { + srcReg=getRegister(scope, var); + functionparams.push_back(" addi $sp, $sp, -4 \n li "+srcReg+", "+var+"\n sw " + srcReg + ", " + to_string(0) + "($sp)"); + param_receive_offset=0; + } + else if(paramCounter == argRegisters.size()){ + mipsCode.push_back(" li " + argRegisters[paramCounter] + ", " + var); + param_receive_offset=0; + } + else mipsCode.push_back(" li " + argRegisters[paramCounter] + ", " + var); + paramCounter++; + return; + + } + else if(isFloatLiteral(var)){ + paramtype.push_back("float"); + if (paramFloatCounter == 0) + mipsCode.push_back(" li.s $f12, " + var); + else if (paramFloatCounter == 1) + mipsCode.push_back(" li.s $f14, " + var); + else { + srcReg=getFloatRegister(scope, var); + functionparams.push_back(" addi $sp, $sp, -4 \n li.s "+srcReg+", "+var+"\n s.s " + srcReg + ", " + to_string(0) + "($sp)"); + } + paramFloatCounter++; + return; + + } + symbol_info* sym = getScope(scope, var)->symbol_map[var]; + if (!sym) { + exit(1); + } + + if (sym->type == "float") { + paramtype.push_back("float"); + srcReg = getFloatRegister(scope, var); + reg_for_scanf.push_back(srcReg); + if (paramFloatCounter == 0) + mipsCode.push_back(" mov.s $f12, " + srcReg); + else if (paramFloatCounter == 1) + mipsCode.push_back(" mov.s $f14, " + srcReg); + else { + functionparams.push_back(" addi $sp, $sp, -4 \n s.s " + srcReg + ", " + to_string(0) + "($sp)"); + } + paramFloatCounter++; + } + else if (sym->type =="int" || sym->type == "char") { + if(sym->type=="int") paramtype.push_back("int"); + if(sym->type=="char") paramtype.push_back("char"); + srcReg = getRegister(scope, var); + reg_for_scanf.push_back(srcReg); + if (paramCounter >= argRegisters.size()) { + functionparams.push_back(" addi $sp, $sp, -4 \n sw " + srcReg + ", " + to_string(0) + "($sp)"); + param_receive_offset=0; + } + else if(paramCounter == argRegisters.size()){ + mipsCode.push_back(" move " + argRegisters[paramCounter] + ", " + srcReg); + param_receive_offset=0; + } + else mipsCode.push_back(" move " + argRegisters[paramCounter] + ", " + srcReg); + paramCounter++; + } + + +} +// Processes function calls, including system calls like printf and scanf + +void handle_function_call(const string& line) { + istringstream iss(line); + string call, funcWithComma; + int argCount; + iss >> call >> funcWithComma; + iss.ignore(); + iss >> argCount; + int arg_no=0; + string funcName = trim(funcWithComma); + if (!funcName.empty() && funcName.back() == ',') funcName.pop_back(); + if(funcName.find(",")!=string::npos){ + arg_no=stoi(funcName.substr(funcName.find(",")+1)); + funcName = funcName.substr(0,funcName.find(",")); + + } + if(funcName=="printf") + { + int floatCounter = 0; + mipsCode.push_back("#printf"); + int cnt=0; + for(auto &type : paramtype){ + if(type=="int" || type=="char" || type=="string") {mipsCode.push_back(" move $a0, $a"+to_string(cnt));cnt++;} + if(type=="float"||type=="double") {mipsCode.push_back(" mov.s $f12, $f"+to_string(12+2*floatCounter));floatCounter++;} + if(type=="int") mipsCode.push_back(" li $v0, 1"); + else if(type=="char") mipsCode.push_back(" li $v0, 11"); + else if(type=="string") mipsCode.push_back(" li $v0, 4"); + else if(type=="float") mipsCode.push_back(" li $v0, 2"); + else if(type=="bool") mipsCode.push_back(" li $v0, 1"); + else if(type=="double") mipsCode.push_back(" li $v0, 3"); + mipsCode.push_back("syscall"); + mipsCode.push_back(" li $v0, 4 \n la $a0, newline \n syscall"); + } + paramtype.clear(); + reg_for_scanf.clear(); + arg_no=0; + paramCounter = 0; + paramFloatCounter = 0; + return; + } + if(funcName == "scanf") { + int floatCounter=0; + int cnt=0; + mipsCode.push_back("#scanf"); + for(auto &type : paramtype){ + if(type=="int") + {mipsCode.push_back(" li $v0, 5"); mipsCode.push_back("syscall"); mipsCode.push_back("move "+ reg_for_scanf[cnt]+" ,$v0");cnt++;} + else if(type=="char") {mipsCode.push_back(" li $v0, 12"), mipsCode.push_back("syscall"); mipsCode.push_back("move "+ reg_for_scanf[cnt]+" ,$v0");cnt++;} + else if(type=="string") + { + mipsCode.push_back(" li $v0, 4"); + mipsCode.push_back("syscall"); + } + else if(type=="float") + {mipsCode.push_back(" li $v0, 6"); + mipsCode.push_back("syscall"); + mipsCode.push_back("mov.s "+reg_for_scanf[cnt]+",$f0"); + cnt++; + } + else if(type=="double") {mipsCode.push_back(" li $v0, 7"); + mipsCode.push_back("syscall"); + mipsCode.push_back("mov.d "+reg_for_scanf[cnt]+",$f0"); + cnt++; + } + } + reg_for_scanf.clear(); + paramtype.clear(); + paramCounter = 0; // Reset after call + paramFloatCounter = 0; + arg_no=0; + return; + } + if(functionparams.size() > 0){ + reverse(functionparams.begin(), functionparams.end()); + for(auto ¶m : functionparams){ + mipsCode.push_back(param); + } + functionparams.clear(); + } + + paramtype.clear(); + mipsCode.push_back(" jal " + funcName); + paramCounter = 0; + paramFloatCounter = 0; + arg_no=0; + reg_for_scanf.clear(); +} + +// Handles parameter receiving at the beginning of functions + + +void handle_param_receive(const string& line, scoped_symtab* scope) { + size_t assignPos = line.find(":="); + string lhs = trim(line.substr(0, assignPos)); + symbol_info* sym = getScope(scope, lhs)->symbol_map[lhs]; + if (!sym) { + exit(1); + } + + string dst; + + if (sym->type == "float") { + dst= getFloatRegister(scope, lhs); + if (paramFloatReceiveCounter == 0) + mipsCode.push_back(" mov.s " + dst + ", $f12"); + else if (paramFloatReceiveCounter == 1) + mipsCode.push_back(" mov.s " + dst + ", $f14"); + else { + mipsCode.push_back(" #popping from stack to " + dst); + mipsCode.push_back(" l.s " + dst + ", " +to_string(param_receive_offset) + "($fp)"); + param_receive_offset+=4; + mipsCode.push_back(" #pushing into function stack"); + sym->offset = last_offset.top(); + last_offset.top()+=get_size_from_type(sym->type); + mipsCode.push_back(" s.s " + dst + ", " + to_string(sym->offset) + "($sp)"); + } + paramFloatReceiveCounter++; + } else { + + dst= getRegister(scope, lhs); + if (paramReceiveCounter >= argRegisters.size()) { + mipsCode.push_back(" #popping from stack to " + dst); + mipsCode.push_back(" lw " + dst + ", " +to_string(param_receive_offset) + "($fp)"); + param_receive_offset+=4; + mipsCode.push_back(" #pushing into function stack"); + sym->offset = last_offset.top(); + last_offset.top()+=get_size_from_type(sym->type); + mipsCode.push_back(" sw " + dst + ", " + to_string(sym->offset) + "($sp)"); + } + else{ + string from = argRegisters[paramReceiveCounter]; + mipsCode.push_back(" move " + dst + ", " + from); + } + paramReceiveCounter++; + + } + +} + +// Processes array accesses and assignments + + +void handle_array(const string& line, scoped_symtab* scope) { + size_t assignPos = line.find(":="); + string lhs = trim(line.substr(0, assignPos)); + string rhs = trim(line.substr(assignPos + 2)); + string r1; + if(line[0]=='*'){ + string arr_name=trim(lhs.substr(2).substr(0,lhs.substr(2).find("+"))); + if(isIntLiteral(rhs)){ + if(availableRegs.empty()) handleRegisterSpill(scope,rhs); + r1=availableRegs.back(); + availableRegs.pop_back(); + load_if_constant(scope, rhs, r1); + lhs = lhs.substr(3); + //split on plus + size_t plusPos = lhs.find("+"); + string lhs1 = trim(lhs.substr(0, plusPos)); + string lhs2 = trim(lhs.substr(plusPos + 1)); + lhs2.pop_back(); + lhs2 = trim(lhs2); + string regis = getRegister(scope,lhs2); + mipsCode.push_back(" addi " + regis + ", " + regis + ", " + to_string(getScope(scope,lhs1)->symbol_map[lhs1]->offset)); + mipsCode.push_back(" add " + regis + ", " + regis + ", $sp"); + mipsCode.push_back(" sw " + r1 + ", 0(" + regis + ")"); + } + else if(isFloatLiteral(rhs)){ + if(getScope(scope,arr_name)->symbol_map[arr_name]->type=="float"){ + r1=getFloatRegister(scope,rhs); + load_if_constant(scope, rhs, r1); + lhs = lhs.substr(3); + //split on plus + size_t plusPos = lhs.find("+"); + string lhs1 = trim(lhs.substr(0, plusPos)); + string lhs2 = trim(lhs.substr(plusPos + 1)); + lhs2.pop_back(); + lhs2 = trim(lhs2); + string regis = getRegister(scope,lhs2); + string val=to_string(getScope(scope,lhs1)->symbol_map[lhs1]->offset); + string regii = getRegister(scope,val); + mipsCode.push_back(" li " + regii + ", " + val); + mipsCode.push_back(" add " + regis + ", " + regis + ", " + regii); + mipsCode.push_back(" add " + regis + ", " + regis + ", $sp"); + mipsCode.push_back(" s.s " + r1 + ", 0(" + regis + ")"); + } + else if(getScope(scope,arr_name)->symbol_map[arr_name]->type=="double"){ + r1=getFloatRegister(scope,rhs,"double"); + load_if_constant(scope, rhs, r1); + lhs = lhs.substr(3); + //split on plus + size_t plusPos = lhs.find("+"); + string lhs1 = trim(lhs.substr(0, plusPos)); + string lhs2 = trim(lhs.substr(plusPos + 1)); + lhs2.pop_back(); + lhs2 = trim(lhs2); + string regis = getRegister(scope,lhs2); + string val=to_string(getScope(scope,lhs1)->symbol_map[lhs1]->offset); + string regii = getRegister(scope,val); + mipsCode.push_back(" li " + regii + ", " + val); + mipsCode.push_back(" add " + regis + ", " + regis + ", " + regii); + + mipsCode.push_back(" add " + regis + ", " + regis + ", $sp"); + mipsCode.push_back(" s.d" + r1 + ", 0(" + regis + ")"); + } + } + }else{ + rhs = rhs.substr(3); + string arr_name=trim(rhs.substr(0,rhs.find("+"))); + size_t plusPos = rhs.find("+"); + string rhs1 = trim(rhs.substr(0, plusPos)); + string rhs2 = trim(rhs.substr(plusPos + 1)); + rhs2.pop_back(); + rhs2 = trim(rhs2); + if(getScope(scope,arr_name)->symbol_map[arr_name]->type=="float"){ + string regis = getRegister(scope,rhs2); + string val=to_string(getScope(scope,rhs1)->symbol_map[rhs1]->offset); + string regii = getRegister(scope,val); + mipsCode.push_back(" li " + regii + ", " + val); + mipsCode.push_back(" add " + regis + ", " + regis + ", " + regii); + mipsCode.push_back(" add " + regis + ", " + regis + ", $sp"); + string dst = getFloatRegister(scope,lhs); + mipsCode.push_back(" l.s " + dst + ", 0(" + regis + ")"); + } + else if(getScope(scope,arr_name)->symbol_map[arr_name]->type=="double"){ + string regis = getRegister(scope,rhs2); + string val=to_string(getScope(scope,rhs1)->symbol_map[rhs1]->offset); + string regii = getRegister(scope,val); + mipsCode.push_back(" li " + regii + ", " + val); + mipsCode.push_back(" add " + regis + ", " + regis + ", " + regii); + mipsCode.push_back(" add " + regis + ", " + regis + ", $sp"); + string dst = getFloatRegister(scope,lhs,"double"); + mipsCode.push_back(" l.d " + dst + ", 0(" + regis + ")"); + } + else{ + string regis = getRegister(scope,rhs2); + mipsCode.push_back(" addi " + regis + ", " + regis + ", " + to_string(getScope(scope,rhs1)->symbol_map[rhs1]->offset)); + mipsCode.push_back(" add " + regis + ", " + regis + ", $sp"); + string dst = getRegister(scope,lhs); + mipsCode.push_back(" lw " + dst + ", 0(" + regis + ")"); + } + + } +} + +// Handles pointer operations like dereferencing and address-of + + +void handle_pointer(const string& line, scoped_symtab* scope) { + size_t assignPos = line.find(":="); + string lhs = trim(line.substr(0, assignPos)); + string rhs = trim(line.substr(assignPos + 2)); + int rhs_ptr=0; + size_t amppos = rhs.find("&"); + if(lhs[0] == '*'){ + lhs = lhs.substr(1); + } + string dst; + if (amppos != string::npos) + rhs = rhs.substr(amppos + 1); + if(rhs[0] == '*'){ + rhs = rhs.substr(1); + rhs_ptr=1; + } + if(isIntLiteral(rhs)){ + dst=getRegister(scope, lhs); + mipsCode.push_back(" #Loading constant " + rhs + " into register"); + if(availableRegs.empty()){ + handleRegisterSpill(scope,rhs); + } + string reg = availableRegs.back(); + availableRegs.pop_back(); + mipsCode.push_back(" li " + reg + ", " + rhs); + loadedConstants[rhs] = true; + reg_of_const[rhs] = reg; + mipsCode.push_back(" sw " + reg + ", " + to_string(0) + "("+dst + ")"); + } + else if(isFloatLiteral(rhs)){ + if(getScope(scope,lhs)->symbol_map[lhs]->type=="float"){ + dst=getFloatRegister(scope, lhs); + mipsCode.push_back(" #Loading constant " + rhs + " into register"); + if(availableFloatRegs.empty()){ + handleFloatRegisterSpill(scope,rhs); + } + string reg = getFloatRegister(scope,rhs); + mipsCode.push_back(" li.s " + reg + ", " + rhs); + loadedConstants[rhs] = true; + reg_of_const[rhs] = reg; + mipsCode.push_back(" s.s " + reg + ", " + to_string(0) + "("+dst + ")"); + } + else { + dst=getFloatRegister(scope, lhs,"double"); + mipsCode.push_back(" #Loading constant " + rhs + " into register"); + if(availableFloatRegs.empty()){ + handleDoubleRegisterSpill(scope,rhs); + } + string reg =getFloatRegister(scope,rhs,"double"); + mipsCode.push_back(" li.d " + reg + ", " + rhs); + loadedConstants[rhs] = true; + reg_of_const[rhs] = reg; + mipsCode.push_back(" s.d " + reg + ", " + to_string(0) + "("+dst + ")"); + } + + } + + else{ + if(rhs_ptr){ + if(var_to_reg.count({getScope(scope, rhs), rhs})){ + dst=getRegister(scope, lhs); + pair var = offset_to_var[pointer_to_offset[{getScope(scope, rhs), rhs}]]; + if(var_to_reg.count(var) && !var.first->symbol_map[var.second]->is_array){ + push_into_stack(var); + } + mipsCode.push_back(" lw " + dst + ", " + "0(" + var_to_reg[{getScope(scope, rhs), rhs}] + ")"); + symbol_info* sym = getScope(scope, rhs)->symbol_map[rhs]; + if(getScope(scope, rhs)->symbol_map[rhs]->offset == -1){ + sym->offset = last_offset.top(); + last_offset.top()+=get_size_from_type(sym->type); + mipsCode.push_back(" sw " + dst + ", " + to_string(sym->offset) + "($sp)"); + } + else{ + mipsCode.push_back(" sw " + dst + ", " + to_string(sym->offset) + "($sp)"); + } + } + else if(floatVarToReg.count({getScope(scope, rhs), rhs})){ + dst=getFloatRegister(scope, lhs); + mipsCode.push_back(" l.s " + dst + ", " + "0(" + floatVarToReg[{getScope(scope, rhs), rhs}] + ")"); + symbol_info* sym = getScope(scope, rhs)->symbol_map[rhs]; + if(getScope(scope, rhs)->symbol_map[rhs]->offset == -1){ + sym->offset = last_offset.top(); + last_offset.top()+=get_size_from_type(sym->type); + mipsCode.push_back(" s.s " + dst + ", " + to_string(sym->offset) + "($sp)"); + } + else{ + mipsCode.push_back(" s.s " + dst + ", " + to_string(sym->offset) + "($sp)"); + } + } + else if(doubleVarToReg.count({getScope(scope, rhs), rhs})){ + dst=getFloatRegister(scope, lhs,"double"); + mipsCode.push_back(" l.d " + dst + ", " + "0(" + doubleVarToReg[{getScope(scope, rhs), rhs}] + ")"); + symbol_info* sym = getScope(scope, rhs)->symbol_map[rhs]; + if(getScope(scope, rhs)->symbol_map[rhs]->offset == -1){ + sym->offset = last_offset.top(); + last_offset.top()+=get_size_from_type(sym->type); + mipsCode.push_back(" s.d " + dst + ", " + to_string(sym->offset) + "($sp)"); + } + else{ + mipsCode.push_back(" s.d " + dst + ", " + to_string(sym->offset) + "($sp)"); + } + } + } + else{ + symbol_info* rhsInfo = getScope(scope, rhs)->symbol_map[rhs]; + if(rhsInfo->type.substr(0,3)=="int"){ + dst=getRegister(scope, lhs); + if(var_to_reg.count({scope, rhs})){ + push_into_stack({scope, rhs}); + } + offset_to_var[rhsInfo->offset] = {scope, rhs}; + pointer_to_offset[{getScope(scope, lhs), lhs}] = rhsInfo->offset; + mipsCode.push_back(" addi " + dst + ", $sp, " + to_string(rhsInfo->offset)); + } + else if(rhsInfo->type.substr(0,5)=="float"){ + dst=getFloatRegister(scope, lhs); + string regis=floatVarToReg[{scope, rhs}]; + if(floatVarToReg.count({scope, rhs})){ + push_into_stack({scope, rhs}); + } + availableFloatRegs.push_back(regis); + if(stoi(regis.substr(2))%2==1){ + string pair=regis.substr(0,2)+to_string(stoi(regis.substr(2))-1); + if(find(availableFloatRegs.begin(), availableFloatRegs.end(), pair) != availableFloatRegs.end()){ + availableDoubleRegs.push_back(pair); + } + } + else{ + string pair=regis.substr(0,2)+to_string(stoi(regis.substr(2))+1); + if(find(availableFloatRegs.begin(), availableFloatRegs.end(), pair) != availableFloatRegs.end()){ + availableDoubleRegs.push_back(regis); + } + } + string val=to_string(rhsInfo->offset); + string regii = getFloatRegister(scope,val); + mipsCode.push_back(" li.s " + regii + ", " + val); + mipsCode.push_back(" add.s " + dst + ", $sp, " + regii); + } + else if(rhsInfo->type.substr(0,6)=="double"){ + string reg = getFloatRegister(scope, rhs,"double"); + string regis=doubleVarToReg[{scope, rhs}]; + if(doubleVarToReg.count({scope, rhs})){ + push_into_stack({scope, rhs}); + } + availableDoubleRegs.push_back(regis); + string pair=regis.substr(0,2)+to_string(stoi(regis.substr(2))+1); + availableFloatRegs.push_back(pair); + availableFloatRegs.push_back(regis); + string val=to_string(rhsInfo->offset); + string regii = getFloatRegister(scope,val,"double"); + mipsCode.push_back(" li.d " + regii + ", " + val); + mipsCode.push_back(" add.d " + reg + ", $sp, " + regii); + } + + + } + } +} + +bool check_struct(const string& line, scoped_symtab* scope) { + auto pos = line.find(":="); + string lhs = trim(line.substr(0, pos)); + string rhs = trim(line.substr(pos + 2)); + auto ppos = rhs.find("+"); + if(ppos == string::npos) return false; + if(isIntLiteral(trim(rhs.substr(0,ppos))) || isFloatLiteral(trim(rhs.substr(0,ppos)))) return false; + string structName = trim(rhs.substr(0, ppos)); + if(isIntLiteral(structName) || isFloatLiteral(structName) || isStringLiteral(structName)){ + return false; + } + symbol_info* sym = getScope(scope, structName)->symbol_map[structName]; + if(sym->type.substr(0,6) == "struct" || sym->type.substr(0,5) == "union") { + return true; + } + return false; +} + +void handle_struct(const string& line, scoped_symtab* scope) { + auto pos = line.find(":="); + string lhs = trim(line.substr(0, pos)); + string rhs = trim(line.substr(pos + 2)); + auto ppos = rhs.find("+"); + string structName = trim(rhs.substr(0, ppos)); + int offset = stoi(trim(rhs.substr(ppos + 2))); + int symoffset = getScope(scope,structName)->symbol_map[structName]->offset; + string dst = getRegister(scope, lhs); + if (var_to_reg.count({scope, structName})) { + push_into_stack({scope, structName}); + } + + if(symoffset == -1){ + push_into_stack({scope, structName}); + } + symoffset = scope->symbol_map[structName]->offset; + int totoffset = symoffset + offset; + mipsCode.push_back(" addi " + dst + ", $sp, " + to_string(totoffset)); +} + +// First pass to calculate function stack sizes and parameter sizes + +void pass1(vector>& codeList) { + for (int i = 0; i < codeList.size(); i++) { + string t = trim(codeList[i].first); + if (t.empty()) { + } else if (t.rfind("FUNC_BEGIN", 0) == 0) { + istringstream iss(t); + string dummy, funcName; + iss >> dummy >> funcName; + int size=0; + i++; + map visited_scopes; + while(isymbol_map[funcName]); + funcStackSize[funcName] = size+8; + break; + }else{ + scoped_symtab* scope = codeList[i].second; + if(visited_scopes.find(scope)==visited_scopes.end()){ + visited_scopes[scope]=1; + size+=calculate_function_stack_size(scope); + } + } + i++; + } + } + } +} + + +string curr_func; + +// Second pass that generates MIPS code for each TAC instruction + +void pass2(vector>& codeList){ + for(int idx = 0; idx < codeList.size(); ++idx){ + auto& code = codeList[idx]; + currentInstructionIndex = idx; + string t = trim(code.first); + if (t.empty()){ + continue; + } + else{ + if(t.rfind("FUNC_BEGIN", 0) == 0){ + istringstream iss(t); + string dummy, funcName; + iss >> dummy >> funcName; + trim(funcName); + curr_func = funcName; + globalscope=code.second; + generate_func_begin_MIPS(funcName, funcStackSize[funcName]); + paramReceiveCounter = 0; + paramFloatReceiveCounter = 0; + } + else if (t.rfind("FUNC_END",0) == 0) { + istringstream iss(t); + string dummy, funcName; + iss >> dummy >> funcName; + curr_func = ""; + generate_func_end_MIPS(funcName, funcStackSize[funcName]); + + continue; + } + else if(t.rfind("RETURN",0) == 0){ + istringstream iss(t); + string keyword, val; + iss >> keyword >> val; + if(val.empty())val = ""; + generate_return_MIPS(curr_func, code.second, val); + } + else if (t.rfind("if (", 0) == 0 && t.find("goto") != string::npos) { + size_t start = t.find('(') + 1; + size_t end = t.find(')'); + string condition = trim(t.substr(start, end - start)); + string label = trim(t.substr(t.find("goto") + 4)); + string reg = getRegister(code.second, condition); + load_if_constant(code.second, condition, reg); + mipsCode.push_back(" bnez " + reg + ", " + label); + } + else if (t.rfind("goto", 0) == 0) { + string label = trim(t.substr(4)); + mipsCode.push_back(" j " + label); + } + else if (t.back() == ':' && isalpha(t[0])) { + mipsCode.push_back(t); + } + else if (t.rfind("PARAM", 0) == 0) { + handle_param_pass(t, code.second); + continue; + } + else if (t.rfind("CALL", 0) == 0) { + handle_function_call(t); + continue; + } + else if (t.find(":= PARAM") != string::npos) { + handle_param_receive(t, code.second); + continue; + } + else if((t.find("*") != string::npos && t.find("(")!=string::npos && t[t.find("*")+1] == '(')){ + handle_array(t, code.second); + continue; + } + else if(t.find("&") != string::npos || (t.find("*") != string::npos && t[t.find("*")+1] != ' ')){ + handle_pointer(t, code.second); + continue; + } + else if(check_struct(t, code.second)){ + handle_struct(t, code.second); + continue; + } + if (t.find(":=") != string::npos) { + size_t lhsEnd = t.find(":="); + string lhs = trim(t.substr(0, lhsEnd)); + string rhs = trim(t.substr(lhsEnd + 2)); + + auto [opPos, opp] = find_operator(rhs); + if (opPos != string::npos) handle_operation(lhs, rhs, opPos, opp, code.second); + else handle_assignment(lhs, rhs, code.second); + } + } + } +} + +bool isAddress(const std::string& token) { + return token.size() > 2 && token[0] == '0' && token[1] == 'x'; +} + +// Computes use-def information for liveness analysis + +void compute_use_def(LivenessInfo& inst) { + const string& line = inst.code; + if(line.find("printf")!=string::npos){ + for(auto var: var_for_printf) inst.use.insert({getScope(inst.scope,var), var}); + var_for_printf.clear(); + } + if (line.find(":=") != string::npos) { + size_t eq = line.find(":="); + string lhs = trim(line.substr(0, eq)); + string rhs = trim(line.substr(eq + 2)); + if(lhs[0] == '*'){ + lhs = lhs.substr(1); + } + istringstream iss(rhs); + string token; + while (iss >> token) + if (isalpha(token[0]) && token != lhs){ + inst.use.insert({getScope(inst.scope,token), token}); + } + + istringstream iss2(lhs); + string token2; + bool first=true; + while (iss2 >> token2) + if (isalpha(token2[0])){ + if(first){ + inst.def.insert({getScope(inst.scope,token2), token2}); + inst.use.insert({getScope(inst.scope,token2), token2}); + first=false; + + } + else{ + inst.use.insert({getScope(inst.scope,token2), token2}); + } + } + } else if (line.find("if(") == 0) { + size_t start = line.find('(') + 1; + size_t end = line.find(')'); + string cond = line.substr(start, end - start); + istringstream iss(cond); + string token; + while (iss >> token) + if (isalpha(token[0])){ + inst.use.insert({getScope(inst.scope,token), token}); + } + } else if (line.find("RETURN") == 0) { + string word, val; + istringstream iss(line); + iss >> word >> val; + if(isalpha(val[0])) inst.use.insert({getScope(inst.scope,val), val}); + }else if(line.find("PARAM")!=string::npos){ + string word, val; + istringstream iss(line); + iss >> word >> val; + if(isalpha(val[0])) var_for_printf.push_back(val); + } +} + +// Identifies successor instructions for control flow graph construction + +void compute_successors(vector& program) { + for (int i = 0; i < program.size(); ++i) { + string line = trim(program[i].code); + if (line.find("goto") == 0) { + string label = trim(line.substr(4)); + for (int j = 0; j < program.size(); ++j) + if (program[j].code == label + ":") + program[i].successors = {j}; + } else if (line.find("if(") == 0) { + string label = trim(line.substr(line.find("goto") + 4)); + for (int j = 0; j < program.size(); ++j) + if (program[j].code == label + ":") { + program[i].successors = {i + 1, j}; + break; + } + } else if (line.back() != ':') { + program[i].successors = {i + 1}; + } + } +} + +// Performs liveness analysis on the three-address code + +void run_liveness(vector& program) { + compute_successors(program); + for (auto& inst : program) + compute_use_def(inst); + + bool changed; + do { + changed = false; + + for (int i = (int)program.size() - 1; i >= 0; --i) { + auto old_in = program[i].live_in; + auto old_out = program[i].live_out; + program[i].live_out.clear(); + for (int s : program[i].successors){ + if(program[s].live_in.empty()) + program[i].live_out.insert(program[s].live_in.begin(), program[s].live_in.end()); + } + + program[i].live_in = program[i].use; + for (auto& v : program[i].live_out) + if (!program[i].def.count(v)) + program[i].live_in.insert(v); + + if (old_in != program[i].live_in || old_out != program[i].live_out) + changed = true; + } + } while (changed); + +} + +// Extracts static variables and adds them to data section + +vector> handle_static_code(vector>& codeList) { + vector> staticCode; + for (int i = 0; i < codeList.size(); ++i) { + string t = trim(codeList[i].first); + if (t.empty()) { + } else if (t.rfind("FUNC_BEGIN", 0) == 0) { + break; + } else { + staticCode.push_back(codeList[i]); + } + } + //remove static code from original list + codeList.erase(codeList.begin(), codeList.begin() + staticCode.size()); + + //iterate over static code and find all the variables and put in data section with name static_ + for (auto& code : staticCode) { + string line = code.first; + size_t assignPos = line.find(":="); + if (assignPos != string::npos) { + string lhs = trim(line.substr(0, assignPos)); + string rhs = trim(line.substr(assignPos + 2)); + static_var.push_back({code.second,lhs}); + if (isIntLiteral(rhs)) { + data_section.push_back("static_"+ lhs + ": .word " + rhs); + } else if (isFloatLiteral(rhs)) { + data_section.push_back("static_" + lhs + ": .float " + rhs); + } else if (isStringLiteral(rhs)) { + data_section.push_back("static_" + lhs + ": .asciiz \"" + rhs.substr(1, rhs.size() - 2) + "\""); + } + } + } + + return codeList; + + +} + +// Main function for code generation that coordinates the entire process + +void codegen_main() { + mipsCode.push_back(".text"); + mipsCode.push_back(".globl main"); + data_section.push_back(".data"); + data_section.push_back("newline: .asciiz \"\\n\""); + std::vector> codeList=handle_static_code(cleaned_TAC); + pass1(codeList); + currentLiveness.clear(); + + for (int i = 0; i < codeList.size(); ++i) { + currentLiveness.push_back({ + codeList[i].second, // scope + codeList[i].first, // code + {}, {}, {}, {}, {}, i + }); + } + run_liveness(currentLiveness); + pass2(codeList); + mipsCode.push_back(" li $v0, 10"); + mipsCode.push_back(" syscall"); + + for(auto data : data_section){ + cerr << data << endl; + } + for (const string& line : mipsCode) { + cerr << line << endl; + } + return; +} \ No newline at end of file diff --git a/Assignment4/src/parser.y b/Assignment4/src/parser.y new file mode 100644 index 0000000..7db2e2a --- /dev/null +++ b/Assignment4/src/parser.y @@ -0,0 +1,2263 @@ +%{ + #include + using namespace std; + + #define MAX_ARGS 100 + + void yyerror(const char *s); + void print_errors(); + void codegen_main(); + + extern int yylex(); + extern int yylineno; + extern char *yytext; + + vector> cleaned_TAC; + vector> static_variables; + vector> static_variables_code; + + std::stack parsing_stack; + std::stack pointer_info; + std::map type_def_mapping; + + scoped_symtab* curr_scope = new scoped_symtab(); + std::vector all_scopes={curr_scope}; + + std::vector error_list; + vector scope_list; + vector type_list = {}; + vector var_name={}; + map goto_list; + stack>> case_list; + + struct ArgList { + char *args[MAX_ARGS]; + int count_arg; + } argList; + +%} + +%union { + char* str; // For type_specifier, declarator + struct symbol_info* symbol_info; // For expressions and constants +} + +%token DECIMAL_LITERAL HEXA_LITERAL OCTAL_LITERAL EXP_LITERAL REAL_LITERAL FLOAT_LITERAL STRING_LITERAL CHARACTER_LITERAL +%token ID INVALID_ID INCLUDE +%token AUTO STRUCT BOOL BREAK CASE CONTINUE GOTO DO DEFAULT IF ELSE FOR CONST TRUE FALSE STATIC SWITCH WHILE UNTIL VOID RETURN SIZEOF FLOAT INT DOUBLE EXTERN SHORT LONG CHAR ENUM REGISTER SIGNED TYPEDEF UNION UNSIGNED VOLATILE +%token CLASS PUBLIC PRIVATE PROTECTED NULLPTR NAMESPACE VIRTUAL CATCH +%token RBRACE LBRACE LBRACKET RBRACKET LPARENTHESES RPARENTHESES DOT COMMA COLON SEMICOLON PLUS MINUS STAR DIVIDE MODULO AMPERSAND OR XOR EXCLAMATION TILDE EQUALS LESS_THAN GREATER_THAN QUESTION_MARK INCREMENT DECREMENT REL_AND REL_OR REL_EQUALS REL_NOT_EQ LESS_EQUALS GREATER_EQUALS ASSIGN_PLUS ASSIGN_MINUS ASSIGN_STAR ASSIGN_DIV ASSIGN_MOD ASSIGN_AND ASSIGN_OR ASSIGN_XOR LEFT_SHIFT LEFT_SHIFT_EQ RIGHT_SHIFT RIGHT_SHIFT_EQ LAMBDA_ARROW VARIABLE_ARGS + +%type primary_expression postfix_expression argument_expression_list unary_expression +%type unary_operator cast_expression multiplicative_expression additive_expression +%type shift_expression relational_expression equality_expression and_expression +%type exclusive_or_expression inclusive_or_expression logical_and_expression +%type logical_or_expression conditional_expression assignment_expression +%type assignment_operator expression constant_expression declaration +%type constant + +%type init_declarator init_declarator_list + +%type struct_declaration_list struct_declaration +%type struct_declarator_list struct_declarator +%type enumerator_list enumerator declarator +%type direct_declarator pointer type_qualifier_list parameter_type_list +%type parameter_list parameter_declaration identifier_list type_name +%type abstract_declarator direct_abstract_declarator initializer +%type initializer_list statement labeled_statement compound_statement +%type declaration_list statement_list expression_statement statement_declaration_list +%type selection_statement iteration_statement jump_statement +%type translation_unit external_declaration function_definition start_symbol + +%type declaration_specifiers storage_class_specifier type_qualifier type_specifier enum_specifier specifier_qualifier_list +%type struct_or_union struct_or_union_specifier + +%start start_symbol + +%% + +constant: + DECIMAL_LITERAL + { + $$= new symbol_info("", "int", $1->ptr, $1->symbol_size); + $$->place=qid(std::to_string(*(int*)($1->ptr)),nullptr); + $$->code=std::to_string(*(int*)($1->ptr)); + } + | FLOAT_LITERAL + { + $$= new symbol_info("", "float", $1->ptr, $1->symbol_size); + $$->place=qid(std::to_string(*(float*)($1->ptr)),nullptr); + $$->code=std::to_string(*(float*)($1->ptr)); + } + | EXP_LITERAL {$$ = new symbol_info("", "exp", $1->ptr, $1->symbol_size);} + | HEXA_LITERAL {$$ = new symbol_info("", "hexa", $1->ptr, $1->symbol_size);} + | REAL_LITERAL {$$ = new symbol_info("", "real", $1->ptr, $1->symbol_size);} + | STRING_LITERAL + { + $$ = new symbol_info("", "char*", $1->ptr, $1->symbol_size); + $$->str_val=$1->str_val; + $$->place=qid($1->str_val,nullptr); + $$->code=$1->str_val; + } + | OCTAL_LITERAL {$$ = new symbol_info("", "octal", $1->ptr, $1->symbol_size);} + | CHARACTER_LITERAL + { + $$ = new symbol_info("", "char", $1->ptr, $1->symbol_size); + string tempp = "'"; + tempp+=(*(char*)($1->ptr)); + tempp+='\''; + $$->place=qid(tempp,nullptr); + $$->code=tempp; + } + + +primary_expression + : ID + { + symbol_info* new_symbol = new symbol_info($1); + $$ = new_symbol; + + //3AC code + symbol_info* find_symbol = lookup_symbol_global($1, curr_scope); + if(find_symbol==nullptr){ + error_list.push_back("Line "+to_string(yylineno)+" : Undeclared variable "+$1); + } + else{ + $$->place=qid($1,find_symbol); + $$->code=""; + $$->type=find_symbol->type; + $$->is_array=find_symbol->is_array; + } + } + | constant + { + $$ = $1; + } + | STRING_LITERAL + | LPARENTHESES expression RPARENTHESES + { + symbol_info* new_symbol = new symbol_info(); + new_symbol->place=newtemp($2->type,curr_scope); + new_symbol->type=$2->type; + // debug("here ",new_symbol->place.first); + string temp=new_symbol->place.first+" := ( "+$2->place.first+" )"; + new_symbol->final_code = $2->final_code; + new_symbol->final_code.push_back({temp,curr_scope}); + new_symbol->code=$2->code+"\n"+temp; + $$=new_symbol; + } + ; + +postfix_expression + : primary_expression + { + $$=$1; + } + | postfix_expression LBRACKET expression RBRACKET + { + string array_name=$1->name; + symbol_info* find_symbol = lookup_symbol_global(array_name, curr_scope); + if(find_symbol == nullptr) { + error_list.push_back("Line "+to_string(yylineno)+" : Undeclared variable "+array_name); + } + else{ + if(find_symbol->is_array==false){ + error_list.push_back("Line "+to_string(yylineno)+" : Not an array "+array_name); + } + else{ + string code=$3->code; + qid temp=newtemp("int",curr_scope); + + string add_str=""; + if(find_symbol->type=="int"){ + add_str=temp.first+" := "+"4 * "+$3->place.first; + // code=code+"\n"+temp.first+":= "+"4 * "+$3->place.first; + } + else if(find_symbol->type=="float"){ + add_str=temp.first+" := "+"4 * "+$3->place.first; + // code=code+"\n"+temp.first+":= "+"4 * "+$3->place.first; + } + else if(find_symbol->type=="char"){ + add_str=temp.first+" := "+"2 * "+$3->place.first; + // code=code+"\n"+temp.first+":= "+"2 * "+$3->place.first; + } + + qid temp2=newtemp(find_symbol->type,curr_scope); + $$->final_code = $3->final_code; + $$->final_code.push_back({add_str,curr_scope}); + code = code + "\n" + add_str; + add_str = temp2.first+" := *( "+$1->place.first+" + "+temp.first+" )"; + $$->final_code.push_back({add_str,curr_scope}); + code=code+"\n"+add_str; + $$->code=code; + $$->place.first=temp2.first; + } + + } + } + | postfix_expression LPARENTHESES RPARENTHESES + { + symbol_info* find_symbol = lookup_symbol_global($1->name, curr_scope); + if(find_symbol == nullptr) { + error_list.push_back("Line "+to_string(yylineno)+" : Undeclared function "+$1->name); + } + else{ + std::vector original_list=find_symbol->param_types; + if($1->name=="printf"){ + error_list.push_back("Line "+to_string(yylineno)+" : Empty printf statement"); + } + else if( $1->name=="scanf"){error_list.push_back("Line "+to_string(yylineno)+" : Empty scanf statement");} + else if($1->name=="sizeof"){error_list.push_back("Line "+to_string(yylineno)+" : Sizeof operator cannot be used with function call");} + else if(original_list.size()>0) + { + error_list.push_back("Line "+to_string(yylineno)+" : Size of actual and formal parameter list does not match"); + } + } + qid temp=newtemp($1->type,curr_scope); + if(find_symbol->type!="void"){ + $$->final_code = $1->final_code; + string add_str=$1->code + temp.first+" := CALL "+$1->place.first; + $$->code=add_str + "\n"; + $$->final_code.push_back({add_str,curr_scope}); + $$->place=temp; + $$->type=find_symbol->type; + } + else{ + $$->final_code = $1->final_code; + string add_str=$1->code + "CALL "+$1->place.first; + $$->code=add_str + "\n"; + $$->final_code.push_back({add_str,curr_scope}); + $$->type=find_symbol->type; + } + + } + | postfix_expression LPARENTHESES argument_expression_list RPARENTHESES + { + $$ = new symbol_info(); + symbol_info* find_symbol = lookup_symbol_global($1->name, curr_scope); + if(find_symbol == nullptr) { + error_list.push_back("Line "+to_string(yylineno)+" : Undeclared function "+$1->name); + } + else{ + std::vector original_list=find_symbol->param_types; + std::vector new_list=$3->param_types; + + if($1->name!="printf" && $1->name!="scanf" && original_list.size()!=new_list.size()){ + error_list.push_back("Line "+to_string(yylineno)+" : Size of actual and formal parameter list does not match"); + } + else{ + for(int i=0;itype,curr_scope); + string middle=""; + vector> temp_list; + for(int i=0;i<$3->param_list.size();i++){ + middle=middle+"PARAM "+$3->param_list[i]+"\n"; + int star=0; + string temp_str=""; + if($3->param_list[i][0]=='*') + { + while($3->param_list[i][0]=='*') + { + star++; + $3->param_list[i]=$3->param_list[i].substr(1); + } + temp_str=$3->param_list[i]; + while(star) + { + qid temp2=newtemp("int",curr_scope); + temp_list.push_back({temp2.first+" := *"+temp_str,curr_scope}); + temp_str=temp2.first; + star--; + } + temp_list.push_back({"PARAM "+temp_str,curr_scope}); + } + + else temp_list.push_back({"PARAM "+$3->param_list[i],curr_scope}); + } + if(find_symbol->type!="void"){ + // debug("idhar",$1->code); + $$->final_code = $1->final_code; + $$->final_code.insert($$->final_code.end(), $3->final_code.begin(), $3->final_code.end()); + string add_str = middle + temp.first+" := CALL "+$1->place.first + ","+to_string($3->param_list.size()); + $$->code=$1->code + "\n"+ $3->code + "\n"+ add_str + "\n"; + $$->final_code.insert($$->final_code.end(), temp_list.begin(), temp_list.end()); + $$->final_code.push_back({temp.first+" := CALL "+$1->place.first + ","+to_string($3->param_list.size()),curr_scope}); + $$->place=temp; + $$->type=find_symbol->type; + }else{ + $$->final_code = $1->final_code; + $$->final_code.insert($$->final_code.end(), $3->final_code.begin(), $3->final_code.end()); + string add_str = middle + "CALL "+$1->place.first + ","+to_string($3->param_list.size()); + $$->final_code.insert($$->final_code.end(), temp_list.begin(), temp_list.end()); + $$->final_code.push_back({"CALL "+$1->place.first + ","+to_string($3->param_list.size()),curr_scope}); + $$->code=$1->code + "\n"+ $3->code + "\n"+add_str + "\n"; + $$->type=find_symbol->type; + } + } + | postfix_expression DOT ID + { + symbol_info* find_symbol = lookup_symbol_global($1->name, curr_scope); + if(find_symbol == nullptr) { + error_list.push_back("Line "+to_string(yylineno)+" : Undeclared variable "+$1->name); + } + else{ + if((find_symbol->type).substr(0,6)=="struct"){ + symbol_info* find_struct; + if((find_symbol->type).substr(0,6)=="struct") find_struct=lookup_symbol_global((find_symbol->type).substr(7), curr_scope); + int flag=0; + string var_type=""; + int offset=0; + for(int i=0;iparam_list.size();i++){ + if(find_struct->param_list[i]==$3){ + var_type=find_struct->param_types[i]; + flag=1; + break; + } + offset+=get_size(find_struct->param_types[i]); + + } + if(flag==0){ + error_list.push_back("Line "+to_string(yylineno)+" : No such attribute found in struct or union "+$1->name); + } + else{ + parsing_stack.push($1->name); + parsing_stack.push($3); + parsing_stack.push(to_string(offset)); + parsing_stack.push(var_type); + + find_symbol->name=$1->name; + $$=find_symbol; + } + + } + else if((find_symbol->type).substr(0,5)=="union") + { + symbol_info* find_struct; + if((find_symbol->type).substr(0,5)=="union") find_struct=lookup_symbol_global((find_symbol->type).substr(6), curr_scope); + int flag=0; + string var_type=""; + int offset=0; + for(int i=0;iparam_list.size();i++){ + if(find_struct->param_list[i]==$3){ + var_type=find_struct->param_types[i]; + flag=1; + break; + } + // offset=max(offset,get_size(find_struct->param_types[i])); + + } + if(flag==0){ + error_list.push_back("Line "+to_string(yylineno)+" : No such attribute found in struct or union "+$1->name); + } + else{ + parsing_stack.push($1->name); + parsing_stack.push($3); + parsing_stack.push(to_string(offset)); + parsing_stack.push(var_type); + + find_symbol->name=$1->name; + $$=find_symbol; + } + } + else{ + error_list.push_back("Line "+to_string(yylineno)+" : Not a struct or union "+$1->name); + } + + } + } + | postfix_expression LAMBDA_ARROW ID + | postfix_expression INCREMENT + { + if($1->is_array==true){ + string code = get_last_line($1->code); + + string add_str=code+" := "+code+" + 1"; + $$->code=$1->code + "\n" + add_str + "\n"; + $$->final_code = $1->final_code; + $$->final_code.push_back({add_str,curr_scope}); + } + else { + $$->final_code = $1->final_code; + string add_str= $1->place.first+" := "+$1->place.first+" + 1 "; + $$->code=$1->code + "\n" + add_str + "\n"; + $$->final_code.push_back({add_str,curr_scope}); + } + + } + | postfix_expression DECREMENT + { + if($1->is_array==true){ + string code = get_last_line($1->code); + string add_str=code + " := "+code+" - 1 "; + $$->code=$1->code + "\n" + add_str+"\n"; + $$->final_code = $1->final_code; + $$->final_code.push_back({add_str,curr_scope}); + } + else { + string add_str= $1->place.first+" := "+$1->place.first+" - 1 "; + $$->final_code = $1->final_code; + $$->code=$1->code + "\n" + add_str + "\n"; + $$->final_code.push_back({add_str,curr_scope}); + } + } + ; + +argument_expression_list + : assignment_expression + { + if($1->place.first!=""){ + // debug("herrrr ", $1->code); + $$->code=$1->code; + $$->final_code = $1->final_code; + $$->param_types.push_back($1->type); + $$->param_list.push_back($1->place.first); + } + else{ + if($1->name==""){ + $$=new symbol_info($1); + $$->param_types.push_back($1->type); + if($1->type=="int")$$->param_list.push_back(std::to_string(*(int*)($1->ptr))); + else if($1->type=="float")$$->param_list.push_back(std::to_string(*(float*)($1->ptr))); + else if($1->type=="char")$$->param_list.push_back(std::to_string(*(char*)($1->ptr))); + else if($1->type=="char*")$$->param_list.push_back($1->str_val); + } + else{ + symbol_info* find_symbol = lookup_symbol_global($1->name, curr_scope); + if(find_symbol == nullptr) { + error_list.push_back("Line "+to_string(yylineno)+" : Undeclared variable "+$1->name); + } + else{ + $$=new symbol_info(find_symbol); + $$->param_types.push_back(find_symbol->type); + $$->param_list.push_back(find_symbol->name); + } + } + } + + } + | argument_expression_list COMMA assignment_expression + + { + if($3->place.first!=""){ + $$->final_code = $1->final_code; + $$->final_code.insert($$->final_code.end(), $3->final_code.begin(), $3->final_code.end()); + $$->code=$1->code + "\n" + $3->code; + //debug("herrrrrrrrrrr ", $3->place.first); + $$->param_types.push_back($1->type); + $$->param_list.push_back($3->place.first); + } + else{ + if($3->name==""){ + $$=new symbol_info($1); + //check 1 or 3 + $$->param_types.push_back($3->type); + if($3->type=="int")$$->param_list.push_back(std::to_string(*(int*)($3->ptr))); + else if($3->type=="float")$$->param_list.push_back(std::to_string(*(float*)($3->ptr))); + else if($3->type=="char")$$->param_list.push_back(std::to_string(*(char*)($3->ptr))); + else if($3->type=="char*")$$->param_list.push_back($3->str_val); + } + else{ + symbol_info* find_symbol = lookup_symbol_global($3->name, curr_scope); + if(find_symbol == nullptr) { + error_list.push_back("Line "+to_string(yylineno)+" : Undeclared variable "+$3->name); + } + else{ + $$=new symbol_info($1); + $$->param_types.push_back(find_symbol->type); + $$->param_list.push_back(find_symbol->name); + } + } + } + + } + ; + +unary_expression + : postfix_expression + { + $$=$1; + } + | INCREMENT unary_expression + | DECREMENT unary_expression + | unary_operator cast_expression + { + symbol_info* new_symbol=new symbol_info(); + string original_type=$2->type; + $$=new_symbol; + + if($1->code=="&"){ + $$->type=original_type+"*"; + } + if($1->code=="*"){ + if(original_type.back()!='*') error_list.push_back("Line "+to_string(yylineno)+" : Trying to dereference non pointer "+$2->name); + else{ + $$->type=original_type; + $$->type.pop_back(); + } + } + + $$->name=$2->name; + string add_str=$1->code+$2->place.first; + $$->final_code = $2->final_code; + $$->final_code.push_back({add_str,curr_scope}); + $$->code=$2->code+"\n"+add_str+"\n"; + $$->place.first=$1->code+$2->place.first; + } + | SIZEOF unary_expression + | SIZEOF LPARENTHESES type_name RPARENTHESES + ; + +unary_operator + : AMPERSAND { + symbol_info* new_symbol=new symbol_info(); + $$=new_symbol; + $$->name="ampersand"; + $$->code="&"; + $$->pointer_depth++; + } + | STAR + { + symbol_info* new_symbol=new symbol_info(); + $$=new_symbol; + $$->name="star"; + $$->code="*"; + } + | PLUS + { + symbol_info* new_symbol=new symbol_info(); + $$=new_symbol; + $$->name="plus"; + $$->code="+"; + } + | MINUS + { + symbol_info* new_symbol=new symbol_info(); + $$=new_symbol; + $$->name="minus"; + $$->code="-"; + } + | TILDE + { + symbol_info* new_symbol=new symbol_info(); + $$=new_symbol; + $$->name="tilde"; + $$->code="~"; + } + | EXCLAMATION + { + symbol_info* new_symbol=new symbol_info(); + $$=new_symbol; + $$->name="exclamation"; + $$->code="!"; + } + ; + +cast_expression + : unary_expression + { + $$=$1; + } + | LPARENTHESES type_name RPARENTHESES cast_expression + { + $$ = $4; + $$->type = $2->type; + } + ; + +multiplicative_expression + : cast_expression {$$=$1;} + | multiplicative_expression STAR cast_expression + { + $$ = $1; + $$->type = priority_to_type[max(type_priority[$1->type],type_priority[$3->type])]; + qid var=newtemp($1->type,curr_scope); + string add_str=var.first+" := "+$1->place.first+" * "+$3->place.first; + $$->final_code = $1->final_code; + $$->final_code.insert($$->final_code.end(), $3->final_code.begin(), $3->final_code.end()); + $$->final_code.push_back({add_str,curr_scope}); + $$->code=$1->code + "\n" + $3->code +"\n" + add_str + "\n"; + $$->place=var; + } + | multiplicative_expression DIVIDE cast_expression + { + $$ = $1; + $$->type = priority_to_type[max(type_priority[$1->type],type_priority[$3->type])]; + qid var=newtemp($1->type,curr_scope); + string add_str=var.first+" := "+$1->place.first+" / "+$3->place.first; + $$->final_code = $1->final_code; + $$->final_code.insert($$->final_code.end(), $3->final_code.begin(), $3->final_code.end()); + $$->final_code.push_back({add_str,curr_scope}); + $$->code=$1->code + "\n" + $3->code +"\n" + add_str + "\n"; + $$->place=var; + } + | multiplicative_expression MODULO cast_expression + { + $$ = $1; + $$->type = priority_to_type[max(type_priority[$1->type],type_priority[$3->type])]; + if($$->type!="int"){ + error_list.push_back("Line "+to_string(yylineno)+" : Modulo operator can only be used with int type"); + } + qid var=newtemp($1->type,curr_scope); + string add_str=var.first+" := "+$1->place.first+" % "+$3->place.first; + $$->final_code = $1->final_code; + $$->final_code.insert($$->final_code.end(), $3->final_code.begin(), $3->final_code.end()); + $$->final_code.push_back({add_str,curr_scope}); + $$->code=$1->code + "\n" + $3->code +"\n" + add_str + "\n"; + $$->place=var; + } + ; + +additive_expression + : multiplicative_expression {$$=$1;} + | additive_expression PLUS multiplicative_expression + { + $$ = $1; + $$->type = priority_to_type[max(type_priority[$1->type],type_priority[$3->type])]; + qid var=newtemp($1->type,curr_scope); + $$->final_code = $1->final_code; + $$->final_code.insert($$->final_code.end(), $3->final_code.begin(), $3->final_code.end()); + string add_str=var.first+" := "+$1->place.first+" + "+$3->place.first + "\n"; + $$->final_code.push_back({add_str,curr_scope}); + $$->code=$1->code + "\n" + $3->code +"\n" + add_str; + $$->place=var; + } + | additive_expression MINUS multiplicative_expression + { + $$ = $1; + $$->type = priority_to_type[max(type_priority[$1->type],type_priority[$3->type])]; + qid var=newtemp($1->type,curr_scope); + $$->final_code = $1->final_code; + $$->final_code.insert($$->final_code.end(), $3->final_code.begin(), $3->final_code.end()); + string add_str=var.first+" := "+$1->place.first+" - "+$3->place.first + "\n"; + $$->final_code.push_back({add_str,curr_scope}); + $$->code=$1->code + "\n" + $3->code +"\n" + add_str; + $$->place=var; + } + ; + +shift_expression + : additive_expression {$$=$1;} + | shift_expression LEFT_SHIFT additive_expression + { + $$ = $1; + $$->type = priority_to_type[max(type_priority[$1->type],type_priority[$3->type])]; + if($$->type!="int"){ + error_list.push_back("Line "+to_string(yylineno)+" : Left shift operator can only be used with int type"); + } + qid var=newtemp($1->type,curr_scope); + $$->final_code.insert($$->final_code.end(), $3->final_code.begin(), $3->final_code.end()); + string add_str=var.first+" := "+$1->place.first+" << "+$3->place.first; + $$->final_code.push_back({add_str,curr_scope}); + $$->code=$1->code + "\n" + $3->code +"\n" + add_str + "\n"; + $$->place=var; + } + | shift_expression RIGHT_SHIFT additive_expression + { + $$ = $1; + $$->type = priority_to_type[max(type_priority[$1->type],type_priority[$3->type])]; + if($$->type!="int"){ + error_list.push_back("Line "+to_string(yylineno)+" : Right shift operator can only be used with int type"); + } + qid var=newtemp($1->type,curr_scope); + $$->final_code.insert($$->final_code.end(), $3->final_code.begin(), $3->final_code.end()); + string add_str=var.first+" := "+$1->place.first+" >> "+$3->place.first; + $$->final_code.push_back({add_str,curr_scope}); + $$->code=$1->code + "\n" + $3->code +"\n" + add_str + "\n"; + $$->place=var; + } + ; + +relational_expression + : shift_expression {$$=$1;} + | relational_expression LESS_THAN shift_expression + { + $$ = $1; + $$->type = priority_to_type[max(type_priority[$1->type],type_priority[$3->type])]; + qid var=newtemp($1->type,curr_scope); + $$->final_code = $1->final_code; + $$->final_code.insert($$->final_code.end(), $3->final_code.begin(), $3->final_code.end()); + string add_str=var.first+" := "+$1->place.first+" < "+$3->place.first; + $$->final_code.push_back({add_str,curr_scope}); + $$->code=$1->code + "\n" + $3->code +"\n" + add_str + "\n"; + $$->place=var; + } + | relational_expression GREATER_THAN shift_expression + { + $$ = $1; + $$->type = priority_to_type[max(type_priority[$1->type],type_priority[$3->type])]; + qid var=newtemp($1->type,curr_scope); + $$->final_code = $1->final_code; + $$->final_code.insert($$->final_code.end(), $3->final_code.begin(), $3->final_code.end()); + string add_str=var.first+" := "+$1->place.first+" > "+$3->place.first; + $$->final_code.push_back({add_str,curr_scope}); + $$->code=$1->code + "\n" + $3->code +"\n" + add_str + "\n"; + $$->place=var; + } + | relational_expression LESS_EQUALS shift_expression + { + $$ = $1; + $$->type = priority_to_type[max(type_priority[$1->type],type_priority[$3->type])]; + qid var=newtemp($1->type,curr_scope); + $$->final_code = $1->final_code; + $$->final_code.insert($$->final_code.end(), $3->final_code.begin(), $3->final_code.end()); + string add_str=var.first+" := "+$1->place.first+" <= "+$3->place.first; + $$->final_code.push_back({add_str,curr_scope}); + $$->code=$1->code + "\n" + $3->code +"\n" + add_str + "\n"; + $$->place=var; + + } + | relational_expression GREATER_EQUALS shift_expression + { + $$ = $1; + $$->type = priority_to_type[max(type_priority[$1->type],type_priority[$3->type])]; + qid var=newtemp($1->type,curr_scope); + $$->final_code = $1->final_code; + $$->final_code.insert($$->final_code.end(), $3->final_code.begin(), $3->final_code.end()); + string add_str=var.first+" := "+$1->place.first+" >= "+$3->place.first; + $$->final_code.push_back({add_str,curr_scope}); + $$->code=$1->code + "\n" + $3->code +"\n" + add_str + "\n"; + $$->place=var; + } + ; + +equality_expression + : relational_expression {$$=$1;} + | equality_expression REL_EQUALS relational_expression + { + $$ = $1; + $$->type = priority_to_type[max(type_priority[$1->type],type_priority[$3->type])]; + qid var=newtemp($1->type,curr_scope); + $$->final_code = $1->final_code; + $$->final_code.insert($$->final_code.end(), $3->final_code.begin(), $3->final_code.end()); + string add_str=var.first+" := "+$1->place.first+" == "+$3->place.first; + $$->final_code.push_back({add_str,curr_scope}); + $$->code=$1->code + "\n" + $3->code +"\n" + add_str + "\n"; + $$->place=var; + } + | equality_expression REL_NOT_EQ relational_expression + { + $$ = $1; + $$->type = priority_to_type[max(type_priority[$1->type],type_priority[$3->type])]; + qid var=newtemp($1->type,curr_scope); + $$->final_code = $1->final_code; + $$->final_code.insert($$->final_code.end(), $3->final_code.begin(), $3->final_code.end()); + string add_str=var.first+" := "+$1->place.first+" != "+$3->place.first; + $$->final_code.push_back({add_str,curr_scope}); + $$->code=$1->code + "\n" + $3->code +"\n" + add_str + "\n"; + $$->place=var; + } + ; + +and_expression + : equality_expression {$$=$1;} + | and_expression AMPERSAND equality_expression + { + $$ = $1; + $$->type = priority_to_type[max(type_priority[$1->type],type_priority[$3->type])]; + if($$->type!="int"){ + error_list.push_back("Line "+to_string(yylineno)+" : And operator can only be used with int type"); + } + } + ; + +exclusive_or_expression + : and_expression {$$=$1;} + | exclusive_or_expression XOR and_expression + { + $$ = $1; + $$->type = priority_to_type[max(type_priority[$1->type],type_priority[$3->type])]; + if($$->type!="int"){ + error_list.push_back("Line "+to_string(yylineno)+" : XOR operator can only be used with int type"); + } + qid var=newtemp($1->type,curr_scope); + $$->final_code = $1->final_code; + $$->final_code.insert($$->final_code.end(), $3->final_code.begin(), $3->final_code.end()); + string add_str=var.first+" := "+$1->place.first+" ^ "+$3->place.first; + $$->final_code.push_back({add_str,curr_scope}); + $$->code=$1->code + "\n" + $3->code +"\n" + add_str + "\n"; + $$->place=var; + } + ; + +inclusive_or_expression + : exclusive_or_expression {$$=$1;} + | inclusive_or_expression OR exclusive_or_expression + { + $$ = $1; + $$->type = priority_to_type[max(type_priority[$1->type],type_priority[$3->type])]; + if($$->type!="int"){ + error_list.push_back("Line "+to_string(yylineno)+" : OR operator can only be used with int type"); + } + qid var=newtemp($1->type,curr_scope); + $$->final_code = $1->final_code; + $$->final_code.insert($$->final_code.end(), $3->final_code.begin(), $3->final_code.end()); + string add_str=var.first+" := "+$1->place.first+" | "+$3->place.first; + $$->final_code.push_back({add_str,curr_scope}); + $$->code=$1->code + "\n" + $3->code +"\n" + add_str + "\n"; + $$->place=var; + } + ; + +logical_and_expression + : inclusive_or_expression {$$=$1;} + | logical_and_expression REL_AND inclusive_or_expression + { + $$ = $1; + $$->type = priority_to_type[max(type_priority[$1->type],type_priority[$3->type])]; + if($$->type!="int"){ + error_list.push_back("Line "+to_string(yylineno)+" : AND operator can only be used with int type"); + } + + } + ; + +logical_or_expression + : logical_and_expression {$$=$1;} + | logical_or_expression REL_OR logical_and_expression + { + $$ = $1; + $$->type = priority_to_type[max(type_priority[$1->type],type_priority[$3->type])]; + if($$->type!="int"){ + error_list.push_back("Line "+to_string(yylineno)+" : OR operator can only be used with int type"); + } + } + ; + +conditional_expression + : logical_or_expression {$$=$1;} + | logical_or_expression QUESTION_MARK expression COLON conditional_expression + ; + +assignment_expression + : conditional_expression {$$=$1;} + | unary_expression assignment_operator assignment_expression + { + $$ = new symbol_info(); + symbol_info* find_symbol = lookup_symbol_global($1->name, curr_scope); + if(find_symbol != nullptr) { + if((find_symbol->type).substr(0,6)=="struct" || (find_symbol->type).substr(0,5)=="union"){ + if(parsing_stack.top()==$3->type){ + //Semantic Analysis + parsing_stack.pop(); + string offset = parsing_stack.top(); + parsing_stack.pop(); + string attr=parsing_stack.top(); + parsing_stack.pop(); + string struct_inst_name=parsing_stack.top(); + parsing_stack.pop(); + symbol_info* find_struct=lookup_symbol_global(struct_inst_name, curr_scope); + find_struct->param_list.push_back(attr); + find_struct->struct_attr_values.push_back($3); + //checkerror + //3AC code kabhi toh karenge + qid var=newtemp(find_symbol->type,curr_scope); + $$->final_code = $1->final_code; + $$->final_code.insert($$->final_code.end(), $3->final_code.begin(), $3->final_code.end()); + string add_str=var.first+" := "+$1->place.first+" + "+offset; + string tempo=""; + tempo=tempo+$1->code; + tempo=tempo+"\n"+$3->code; + tempo=tempo+"\n"+add_str; + $$->final_code.push_back({add_str,curr_scope}); + add_str="*"+var.first+" := "+$3->place.first; + tempo=tempo+"\n"+add_str + "\n"; + $$->final_code.push_back({add_str,curr_scope}); + $$->code=$$->code + tempo; + $$->place=var; + } + else{ + error_list.push_back("Line "+to_string(yylineno)+" : Type mismatch in assignment of struct or union attributes"); + } + } + else{ + if(find_symbol->type=="char*"){ + error_list.push_back("Line "+to_string(yylineno)+" : char* is not modifiable"); + } + if(min(type_priority[$1->type],type_priority[$3->type])==0 && $1->type!=$3->type){ + error_list.push_back("Line "+to_string(yylineno)+" : Type mismatch in assignment"); + } + if(type_priority[$1->type]type]){ + error_list.push_back("Line "+to_string(yylineno)+" : Type mismatch in assignment"); + } + string third_code=$3->code; + string first_code=$1->code; + if(min(type_priority[$1->type],type_priority[find_symbol->type])>0) find_symbol->type=priority_to_type[max(type_priority[find_symbol->type],type_priority[$3->type])]; + + find_symbol->name=$1->name; + find_symbol->place=$1->place; + find_symbol->final_code=$1->final_code; + find_symbol->final_code.insert(find_symbol->final_code.end(), $3->final_code.begin(), $3->final_code.end()); + string add_str=$1->place.first + ":= " + $3->place.first; + find_symbol->final_code.push_back({add_str,curr_scope}); + find_symbol->code=$1->code + "\n" + $3->code + "\n" + add_str + "\n"; + + //3AC code + if($3->place.first[0]!='t' && $3->place.first[0]!='&' && $3->place.first[0]!='*' && $3->place.first[0]!='+' && $3->place.first[0]!='-' && $3->place.first[0]!='~' && $3->place.first[0]!='!') + { + $3->code=""; + } + int flag=0; + if($1->place.first[0]=='*'){ + int count_init_starr=count_init_star($1->place.first); + if(count_init_starr>1){ + flag=1; + string code=""; + qid temp=newtemp($1->type,curr_scope); + string prev=($1->place.first).erase(0,count_init_starr); + $$->final_code = $1->final_code; + $$->final_code.insert($$->final_code.end(), $3->final_code.begin(), $3->final_code.end()); + string add_str; + for(int i=0;ifinal_code.push_back({add_str,curr_scope}); + prev=temp.first; + temp=newtemp($1->type,curr_scope); + } + add_str="*"+prev+" := "+$3->place.first; + code=code+"\n"+add_str+"\n"; + $$->final_code.push_back({add_str,curr_scope}); + $$->code=$1->code+"\n"+$3->code+"\n"+code; + $$->place=temp; + } + } + if($3->place.first[0]=='*'){ + int count_init_starr=count_init_star($3->place.first); + if(count_init_starr>1){ + flag=1; + string code="",add_str=""; + qid temp=newtemp($3->type,curr_scope); + string prev=($3->place.first).erase(0,count_init_starr); + $$->final_code = $1->final_code; + $$->final_code.insert($$->final_code.end(), $3->final_code.begin(), $3->final_code.end()); + for(int i=0;ifinal_code.push_back({add_str,curr_scope}); + code=code+"\n"+add_str; + prev=temp.first; + temp=newtemp($3->type,curr_scope); + } + add_str=$1->place.first+" := *"+temp.first; + code=code+"\n"+add_str+"\n"; + $$->final_code.push_back({add_str,curr_scope}); + $$->code=$1->code+"\n"+$3->code+"\n"+code; + $$->place=$1->place; + } + } + if(flag==0){ + if(find_symbol->is_array==true){ + string code=remove_equal(first_code); + $$->final_code = $3->final_code; + $$->final_code.push_back({add_str,curr_scope}); + add_str = code + " := " + $3->place.first; + int index=0; + string temp=""; + while(indexfinal_code.push_back({temp,curr_scope}); + temp=""; + } + $$->code=$3->code+"\n"+add_str+"\n"; + } + else{ + string op=$2->code; + string tcode=get_assignment_statement($1->place.first,op,$3->place.first); + + if(tcode=="error"){ + error_list.push_back("Line "+to_string(yylineno)+" : Invalid assignment operator"); + } + $$->final_code = $1->final_code; + $$->final_code.insert($$->final_code.end(), $3->final_code.begin(), $3->final_code.end()); + $$->final_code.push_back({tcode,curr_scope}); + $$->code=$1->code + "\n" + third_code + "\n" + tcode+"\n"; + $$->place=$1->place; + } + } + } + + } + else{ + error_list.push_back("Line "+to_string(yylineno)+" : Undeclared symbol "+$1->name); + } + } + ; + +assignment_operator + : EQUALS {$$=new symbol_info("","equals",nullptr,0); $$->code="=";} + | ASSIGN_STAR {$$=new symbol_info("","assign_star",nullptr,0); $$->code="*=";} + | ASSIGN_DIV {$$=new symbol_info("","assign_div",nullptr,0); $$->code="/=";} + | ASSIGN_MOD {$$=new symbol_info("","assign_mod",nullptr,0); $$->code="%=";} + | ASSIGN_PLUS {$$=new symbol_info("","assign_plus",nullptr,0); $$->code="+=";} + | ASSIGN_MINUS {$$=new symbol_info("","assign_minus",nullptr,0); $$->code="-=";} + | LEFT_SHIFT_EQ {$$=new symbol_info("","left_shift_eq",nullptr,0); $$->code="<<=";} + | RIGHT_SHIFT_EQ {$$=new symbol_info("","right_shift_eq",nullptr,0); $$->code=">>=";} + | ASSIGN_AND {$$=new symbol_info("","assign_and",nullptr,0); $$->code="&=";} + | ASSIGN_XOR {$$=new symbol_info("","assign_xor",nullptr,0); $$->code="^=";} + | ASSIGN_OR {$$=new symbol_info("","assign_or",nullptr,0); $$->code="|=";} + ; + +expression + : assignment_expression + { + $$=$1; + } + | expression COMMA assignment_expression + { + $$->final_code = $1->final_code; + $$->final_code.insert($$->final_code.end(), $3->final_code.begin(), $3->final_code.end()); + $$->code=$1->code + "\n" + $3->code; + } + ; + +constant_expression + : conditional_expression{$$=$1;} + ; + +declaration + : declaration_specifiers SEMICOLON + | declaration_specifiers init_declarator_list SEMICOLON + { + if(std::string($1).substr(0, 7) == "typedef"){ + string new_type=parsing_stack.top(); + parsing_stack.pop(); + string old_type=std::string($1).substr(8); + type_def_mapping[new_type]=old_type; + } + + + int flag=0; + string code=""; + symbol_info* nsss=new symbol_info(); + $$=nsss; + while (!parsing_stack.empty()) { + std::string top_symbol = parsing_stack.top(); + + int depth = pointer_info.top(); + + parsing_stack.pop(); + pointer_info.pop(); + if (curr_scope->symbol_map[top_symbol]->type!= ""){ + if(depth!=count_star(curr_scope->symbol_map[top_symbol]->type)){ + error_list.push_back("Line "+to_string(yylineno)+" : Pointer depth mismatch"); + flag = 1; + } + + if (type_priority[$1] < type_priority[curr_scope->symbol_map[top_symbol]->type]) { + string left=$1; + if(curr_scope->symbol_map[top_symbol]->type=="int" && left=="static,int"){ + static_variables.push_back({curr_scope,top_symbol}); + } + else if (curr_scope->symbol_map[top_symbol]->type=="float" && left=="static,float"){ + static_variables.push_back({curr_scope,top_symbol}); + } + else{ + error_list.push_back("Line "+to_string(yylineno)+" : Type mismatch in declaration"); + flag = 1; + } + + } + + curr_scope->symbol_map[top_symbol]->name = top_symbol; + if(type_priority[$1]>0 && type_priority[curr_scope->symbol_map[top_symbol]->type]>0) curr_scope->symbol_map[top_symbol]->type = priority_to_type[max(type_priority[$1], type_priority[curr_scope->symbol_map[top_symbol]->type])]; + + // debug("declaration specifiers121 ", $2->code); + + + code=$2->code; + + } else { + curr_scope->symbol_map[top_symbol]->type = $1; + if(curr_scope->symbol_map[top_symbol]->type.substr(0,6)=="static"){ + static_variables.push_back({curr_scope,top_symbol}); + if(curr_scope->symbol_map[top_symbol]->type=="static,int"){ + static_variables_code.push_back({top_symbol+":= 0",curr_scope}); + } + else if(curr_scope->symbol_map[top_symbol]->type=="static,float"){ + static_variables_code.push_back({top_symbol+":= 0.0",curr_scope}); + } + + + } + for(int i=0;isymbol_map[top_symbol]->type+="*"; + } + curr_scope->symbol_map[top_symbol]->name = top_symbol; + curr_scope->symbol_map[top_symbol]->pointer_depth = depth; + + if((curr_scope->symbol_map[top_symbol]->type).substr(0,6)=="struct") + { + string struct_name=(curr_scope->symbol_map[top_symbol]->type).substr(7); + symbol_info* find_struct=lookup_symbol_global(struct_name, curr_scope); + int size=0; + for(int i=0;iparam_list.size();i++){ + size+=get_size(find_struct->param_types[i]); + } + //debug("Struct size: ",to_string(size)); + code=code+top_symbol+":= alloc " +to_string(size)+"\n"; + + + } + else if((curr_scope->symbol_map[top_symbol]->type).substr(0,5)=="union") + { + string struct_name=(curr_scope->symbol_map[top_symbol]->type).substr(6); + symbol_info* find_struct=lookup_symbol_global(struct_name, curr_scope); + int size=0; + for(int i=0;iparam_list.size();i++){ + size=max(size,get_size(find_struct->param_types[i])); + } + //debug("Struct size: ",to_string(size)); + code=code+top_symbol+":= alloc " +to_string(size)+"\n"; + + + } + symbol_info* new_symbol = new symbol_info(); + new_symbol = new symbol_info($2); + $$=new_symbol; + + } + + } + // debug("declaration specifiers ", to_string(parsing_stack.size())); + $$->code=code; + $$->final_code = {}; + int index=0; + string temp=""; + while(index<$$->code.size()){ + while(index<$$->code.size() && $$->code[index]!='\n'){ + temp+=$$->code[index]; + index++; + } + int fla=0; + for(auto x:static_variables){ + //cout<final_code.push_back({temp,curr_scope}); + temp=""; + index++; + } + //debug("Declaration: ",curr_scope->symbol_map["p"]->code); + } + ; + + +declaration_specifiers + : storage_class_specifier + | storage_class_specifier declaration_specifiers + { + // debug("storage class specifier ", $1); + // debug("storage class specifier ", $2); + char* buf = (char*)malloc(strlen($1) + strlen($2) + 2); // 1 for comma, 1 for null terminator + sprintf(buf, "%s,%s", $1, $2); + $$ = buf; + // debug("storage class specifier ", $$); + + } + | type_specifier {$$=$1;} + | type_qualifier + | type_qualifier declaration_specifiers + ; + +init_declarator_list + : init_declarator { + $$ = $1; + } + | init_declarator_list COMMA init_declarator { + $$=$3; + $$->final_code = $1->final_code; + $$->final_code.insert($$->final_code.end(), $3->final_code.begin(), $3->final_code.end()); + $$->code = $1->code + "\n" + $3->code; + } + ; + +init_declarator + : declarator { + if(lookup_symbol_global($1->name, curr_scope)!=nullptr){ + error_list.push_back("Line "+to_string(yylineno)+" : Redeclaration error "+$1->name); + } + symbol_info* new_symbol = new symbol_info(); + new_symbol=$1; + curr_scope->symbol_map[$1->name]=new_symbol; + curr_scope->symbol_map[$1->name]->name=$1->name; + if($1->is_array==true){ + curr_scope->symbol_map[$1->name]->is_array=true; + curr_scope->symbol_map[$1->name]->array_length=$1->array_length; + if($1->type=="int" || $1->type=="float"){ + string code=$1->name+" := alloc " +to_string(4*$1->array_length); + $$->code=code; + $$->final_code.push_back({code,curr_scope}); + } + else if($1->type=="char"){ + string code=$1->name+" := alloc " +to_string(2*$1->array_length); + $$->final_code.push_back({code,curr_scope}); + $$->code=code; + } + } + + curr_scope->symbol_map[$1->name]->type=$1->type; + + $$ =new_symbol; + + parsing_stack.push($1->name.c_str()); + pointer_info.push($1->pointer_depth); + } + | declarator EQUALS initializer { + if(lookup_symbol_local($1->name, curr_scope)!=nullptr){ + error_list.push_back("Line "+to_string(yylineno)+" : Redeclaration error "+$1->name); + } + + curr_scope->symbol_map[$1->name]=$3; + parsing_stack.push($1->name.c_str()); + pointer_info.push($1->pointer_depth); + + if($1->is_array){ + if($3->int_array.size() > $1->array_length){ + error_list.push_back("Line "+to_string(yylineno)+" : Array size mismatch "+$1->name); + } + else{ + $1->int_array = $3->int_array; + $1->type = $3->type; + curr_scope->symbol_map[$1->name]->is_array=true; + string code=$1->name+" := alloc "; + if($1->type=="int" || $1->type=="float"){ + code=code+to_string(4*$1->array_length); + } + else if($1->type=="char"){ + code=code+to_string(2*$1->array_length); + } + for(int i=0;i<$1->array_length;i++){ + qid temp=newtemp("int",curr_scope); + code=code+"\n"+temp.first+":= "+to_string(i)+" * "; + if($1->type=="int") code=code+"4\n"+"*( "+$1->name+" + "+temp.first+" ) := "+to_string(*(int*)($1->int_array[i]->ptr)); + else if($1->type=="float") code=code+"4\n"+"*( "+$1->name+" + "+temp.first+" ) := "+to_string(*(float*)($1->int_array[i]->ptr)); + else if($1->type=="char") code=code+"2\n"+"*( "+$1->name+" + "+temp.first+" ) := "+char(*(char*)($1->int_array[i]->ptr)); + else if($1->type=="char*") code=code+"2\n"+"*( "+$1->name+" + "+temp.first+" ) := "+$1->int_array[i]->str_val; + } + $$->code=code; + int index=0; + string temp=""; + while(indexfinal_code.push_back({temp,curr_scope}); + temp=""; + index++; + } + + } + } + if(!$1->is_array){ + $$ = $1; + if($3->place.first[0]!='t' && $3->place.first[0]!='&' && $3->place.first[0]!='*' && $3->place.first[0]!='-' && $3->place.first[0]!='!'){ + $3->code=""; + } + + $$->code=$3->code+"\n"+$1->place.first+":= "+$3->place.first; + int index=0; + string temp=""; + while(index<$$->code.size()){ + while(index<$$->code.size() && $$->code[index]!='\n'){ + temp+=$$->code[index]; + index++; + } + $$->final_code.push_back({temp,curr_scope}); + temp=""; + index++; + } + $$->place=$1->place; + } + } + ; + +storage_class_specifier + : TYPEDEF + | EXTERN + | STATIC + | AUTO + | REGISTER + ; + +type_specifier + : VOID {$$=strdup("void");} + | CHAR {$$=strdup("char");} + | SHORT {$$=strdup("short");} + | INT {$$=strdup("int");} + | LONG {$$=strdup("long");} + | FLOAT {$$=strdup("float");} + | DOUBLE {$$=strdup("double");} + | SIGNED {$$=strdup("signed");} + | UNSIGNED {$$=strdup("unsigned");} + | struct_or_union_specifier {$$=$1;} + | enum_specifier + | ID { + if(type_def_mapping.find($1) != type_def_mapping.end()){ + $$=strdup(type_def_mapping[$1].c_str()); + } + else{ + error_list.push_back("Line "+to_string(yylineno)+" : Typedef error "+$1); + } + } + ; + +struct_or_union_specifier + : struct_or_union ID LBRACE struct_declaration_list RBRACE + { + symbol_info* new_symbol=new symbol_info(); + new_symbol->type = $1; + new_symbol->param_list = $4->param_list; + new_symbol->param_types = $4->param_types; + curr_scope->symbol_map[$2]=new_symbol; + } + | struct_or_union LBRACE struct_declaration_list RBRACE + | struct_or_union ID + { + symbol_info* find_symbol = lookup_symbol_global($2, curr_scope); + if (find_symbol != nullptr) { + if (find_symbol->type == "struct" || find_symbol->type == "union") { + std::string temp = std::string($1) + " " + std::string($2); + $$ = strdup(temp.c_str()); + } else { + error_list.push_back("Line "+to_string(yylineno)+" : Variable not of type struct or union"); + } + } else { + error_list.push_back("Line "+to_string(yylineno)+" : Struct or Union not declared "+$2); + } + } + ; + +struct_or_union + : STRUCT {$$=strdup("struct");} + | UNION {$$=strdup("union");} + ; + +struct_declaration_list + : struct_declaration {$$=$1;} + | struct_declaration_list struct_declaration + { + $$=$1; + for(int i=0;i<$2->param_list.size();i++){ + $$->param_list.push_back($2->param_list[i]); + $$->param_types.push_back($2->param_types[i]); + } + + } + ; + +struct_declaration + : specifier_qualifier_list struct_declarator_list SEMICOLON + { + $$=$2; + for(auto it: $2->param_list) + { + //cerr<type = $1; + + curr_scope->symbol_map[it]=x; + $$->param_types.push_back($1); + } + + + + } + ; + +specifier_qualifier_list + : type_specifier + | type_qualifier + ; + +struct_declarator_list + : struct_declarator + { + $$=$1; + $$->param_list.push_back($1->name); + } + | struct_declarator_list COMMA struct_declarator + { + $$=$1; + $$->param_list.push_back($3->name); + } + ; + +struct_declarator + : declarator {$$=$1;} + | COLON constant_expression + | declarator COLON constant_expression + ; + +enum_specifier + : ENUM LBRACE enumerator_list RBRACE + | ENUM ID LBRACE enumerator_list RBRACE + | ENUM ID + ; + +enumerator_list + : enumerator + | enumerator_list COMMA enumerator + ; + +enumerator + : ID + | ID EQUALS constant_expression + ; + +type_qualifier + : CONST + | VOLATILE + ; + +declarator + : pointer direct_declarator { + $$=$2; + $$->pointer_depth=$1->pointer_depth; + } + | direct_declarator { + $$=$1; + } + ; + +direct_declarator + : ID + { + symbol_info* x=new symbol_info(); + x->name = $1; + x->place.first=$1; + $$=x; + } + | LPARENTHESES declarator RPARENTHESES + | direct_declarator LBRACKET constant_expression RBRACKET + { + $$->is_array = true; + if($3->type=="int"){ + $$->array_length = *(int*)($3->ptr); + } + else{ + error_list.push_back("Line "+to_string(yylineno)+" : Array size not an integer "+$1->name); + $$->array_length=100; + } + } + | direct_declarator LBRACKET RBRACKET + { + $$->is_array = true, $$->array_length = 100; + } + | direct_declarator LPARENTHESES parameter_type_list RPARENTHESES + { + symbol_info* new_symbol=new symbol_info(); + new_symbol->type=$1->type; + new_symbol->parameter_no=$3->parameter_no; + new_symbol->param_types=$3->param_types; + new_symbol->param_list=$3->param_list; + new_symbol->is_param_list=$3->is_param_list; + new_symbol->name=$1->name; + curr_scope->symbol_map[$1->name]=new_symbol; + + $$=new_symbol; + } + | direct_declarator LPARENTHESES identifier_list RPARENTHESES + | direct_declarator LPARENTHESES RPARENTHESES + { + symbol_info* new_symbol=new symbol_info(); + new_symbol->type=$1->type; + new_symbol->parameter_no=0; + new_symbol->param_types={}; + new_symbol->param_list={}; + new_symbol->name=$1->name; + new_symbol->is_param_list=false; + curr_scope->symbol_map[$1->name]=new_symbol; + $$=new_symbol; + } + ; + +pointer + : STAR {$$=new symbol_info(); $$->pointer_depth=1;} + | STAR type_qualifier_list + | STAR pointer {$$=$2; $$->pointer_depth++;} + | STAR type_qualifier_list pointer + ; + +type_qualifier_list + : type_qualifier + | type_qualifier_list type_qualifier + ; + + +parameter_type_list + : parameter_list + { + symbol_info* new_symbol=new symbol_info(); + $$->parameter_no=$1->parameter_no; + $$->is_param_list=$1->is_param_list; + $$->param_types=$1->param_types; + $$->param_list=$1->param_list; + $$=$1; + + } + | parameter_list COMMA VARIABLE_ARGS + ; + +parameter_list + : parameter_declaration + { + $$->is_param_list=true; + $$->parameter_no=1; + $$->param_types.push_back($1->type); + $$->param_list.push_back($1->name); + } + | parameter_list COMMA parameter_declaration + { + $$->is_param_list=true; + $$->parameter_no=$1->parameter_no+$3->parameter_no; + $$->param_types.push_back($3->type); + $$->param_list.push_back($3->name); + } + + ; + +parameter_declaration + : declaration_specifiers declarator + { + symbol_info* new_symbol=new symbol_info(); + $$=new_symbol; + $$->type=$1; + $$->name=$2->name; + $$->parameter_no=1; + } + | declaration_specifiers abstract_declarator{ + symbol_info* new_symbol=new symbol_info(); + $$=new_symbol; + $$->type=$1; + $$->name=$2->name; + } + | declaration_specifiers{ + symbol_info* new_symbol=new symbol_info(); + $$=new_symbol; + $$->type=$1; + $$->name=""; + } + ; + +identifier_list + : ID + | identifier_list COMMA ID + ; + +type_name + : specifier_qualifier_list + | specifier_qualifier_list abstract_declarator + ; + +abstract_declarator + : pointer + | direct_abstract_declarator + | pointer direct_abstract_declarator + ; + +direct_abstract_declarator + : LPARENTHESES abstract_declarator RPARENTHESES + | LBRACKET RBRACKET + | LBRACKET constant_expression RBRACKET + | direct_abstract_declarator LBRACKET RBRACKET + | direct_abstract_declarator LBRACKET constant_expression RBRACKET + | LPARENTHESES RPARENTHESES + | LPARENTHESES parameter_type_list RPARENTHESES + | direct_abstract_declarator LPARENTHESES RPARENTHESES + | direct_abstract_declarator LPARENTHESES parameter_type_list RPARENTHESES + ; + +initializer + : assignment_expression { + $1->int_array.push_back($1); + $$=$1; + } + | LBRACE initializer_list RBRACE {$$ = $2;} + | LBRACE initializer_list COMMA RBRACE {$$ = $2;} + ; + +initializer_list + : initializer {$$ = $1;} + | initializer_list COMMA initializer { + if($1->type != $3->type){ + error_list.push_back("Line "+to_string(yylineno)+" : Type mismatch in initializer list"); + } + else{ + $1->int_array.push_back($3); + } + $$ = $1; + } + ; + +statement + : labeled_statement + { + $$=$1; + + } + | compound_statement + { + $$=$1; + } + | expression_statement + { + $$=$1; + } + | selection_statement{$$=$1;} + | iteration_statement{$$=$1;} + | jump_statement{$$=$1;} + + ; + +labeled_statement + : ID COLON statement + { + if(lookup_symbol_global($1, curr_scope)!=nullptr){ + error_list.push_back("Line "+to_string(yylineno)+" : Label Redeclaration error "+$1); + } + else{ + symbol_info* new_symbol=new symbol_info(); + $$=new_symbol; + if(goto_list.find($1)!=goto_list.end()){ + + string label=goto_list[$1]; + // debug("labellllll", $3->code); + $$->final_code.push_back({label + ":",curr_scope}); + $$->code=label+":\n"+$3->code; + $$->final_code.insert($$->final_code.end(), $3->final_code.begin(), $3->final_code.end()); + // debug("label", $$->code); + } + else{ + //debug("labellllll", $3->code); + string label=newlabel(); + $$->final_code.push_back({label + ":",curr_scope}); + $$->code=label+":\n"+$3->code; + $$->final_code.insert($$->final_code.end(), $3->final_code.begin(), $3->final_code.end()); + goto_list[$1]=label; + } + curr_scope->symbol_map[$1]=new symbol_info(); + curr_scope->symbol_map[$1]->name=$1; + curr_scope->symbol_map[$1]->type="label"; + } + } + | ID COLON declaration + { + + if(lookup_symbol_global($1, curr_scope)!=nullptr){ + error_list.push_back("Line "+to_string(yylineno)+" : Label Redeclaration error "+$1); + } + else{ + symbol_info* new_symbol=new symbol_info(); + $$=new_symbol; + if(goto_list.find($1)!=goto_list.end()){ + + string label=goto_list[$1]; + // debug("labellllll", $3->code); + $$->final_code.push_back({label + ":",curr_scope}); + $$->code=label+":\n"+$3->code; + $$->final_code.insert($$->final_code.end(), $3->final_code.begin(), $3->final_code.end()); + // debug("label", $$->code); + } + else{ + //debug("labellllll", $3->code); + string label=newlabel(); + $$->final_code.push_back({label + ":",curr_scope}); + $$->code=label+":\n"+$3->code; + $$->final_code.insert($$->final_code.end(), $3->final_code.begin(), $3->final_code.end()); + goto_list[$1]=label; + } + curr_scope->symbol_map[$1]=new symbol_info(); + curr_scope->symbol_map[$1]->name=$1; + curr_scope->symbol_map[$1]->type="label"; + } + } + | ID COLON + | CASE constant_expression COLON statement + { + string label=newlabel(); + $$->final_code.push_back({label + ":",curr_scope}); + $$->code = label +":\n"+ $4->code; + $$->final_code.insert($$->final_code.end(), $4->final_code.begin(), $4->final_code.end()); + case_list.top().push({$2->code,label}); + + } + | DEFAULT COLON statement + { + string label=newlabel(); + case_list.top().push({"default",label}); + $$->final_code.push_back({label + ":",curr_scope}); + $$->code = label+":\n"+ $3->code; + $$->final_code.insert($$->final_code.end(), $3->final_code.begin(), $3->final_code.end()); + + } + ; + +compound_statement + : LBRACE RBRACE + | LBRACE + { + curr_scope = new scoped_symtab(curr_scope); + for(int i=0;isymbol_map[var_name[i]]=new symbol_info(); + curr_scope->symbol_map[var_name[i]]->type=type_list[i]; + curr_scope->symbol_map[var_name[i]]->name=var_name[i]; + } + var_name={}; + type_list={}; + } + statement_declaration_list RBRACE + + { + symbol_info* new_symbol=new symbol_info(); + $$=new_symbol; + $$->code=$3->code; + $$->final_code = $3->final_code; + $$->is_return=$3->is_return; + $$->return_type=$3->return_type; + all_scopes.push_back(curr_scope);scope_list.push_back(curr_scope); curr_scope = curr_scope->parent; + } + | LBRACE {curr_scope = new scoped_symtab(curr_scope);} statement_list RBRACE {symbol_info* new_symbol=new symbol_info(); + $$=new_symbol; + $$->code=$3->code; + $$->final_code = $3->final_code; + all_scopes.push_back(curr_scope); curr_scope = curr_scope->parent;} + | LBRACE {curr_scope = new scoped_symtab(curr_scope);} declaration_list RBRACE {symbol_info* new_symbol=new symbol_info(); + $$=new_symbol; + $$->code=$3->code; + $$->final_code = $3->final_code; + all_scopes.push_back(curr_scope); curr_scope = curr_scope->parent;} + | LBRACE {curr_scope = new scoped_symtab(curr_scope);} declaration_list statement_list RBRACE + { + symbol_info* new_symbol=new symbol_info(); + $$=new_symbol; + $$->code=$3->code+"\n"+$4->code; + $$->final_code = $3->final_code; + $$->final_code.insert($$->final_code.end(), $4->final_code.begin(), $4->final_code.end()); + all_scopes.push_back(curr_scope); curr_scope = curr_scope->parent; + } + ; + +statement_declaration_list + : statement_list statement_declaration_list + { + symbol_info* new_symbol=new symbol_info(); + $$=new_symbol; + $$->final_code = $1->final_code; + $$->final_code.insert($$->final_code.end(), $2->final_code.begin(), $2->final_code.end()); + $$->code=$1->code + "\n" + $2->code; + $$->is_return=($1->is_return)|($2->is_return); + // if($1->return_type!="") $$->return_type=$1->return_type; + // else $$->return_type=$2->return_type; + + + + } + | declaration_list statement_declaration_list + { + symbol_info* new_symbol=new symbol_info(); + $$=new_symbol; + $$->final_code = $1->final_code; + $$->final_code.insert($$->final_code.end(), $2->final_code.begin(), $2->final_code.end()); + $$->code=$1->code + "\n" + $2->code; + $$->is_return=$2->is_return; + // $$->return_type=$2->return_type; + + + + } + | statement_list + { + symbol_info* new_symbol=new symbol_info(); + $$=new_symbol; + $$->code=$1->code; + $$->final_code = $1->final_code; + $$->is_return=$1->is_return; + //dikkat badi hai + // $$->return_type=$1->return_type; + } + | declaration_list + { + $$=$1; + } + ; + +declaration_list + : declaration + { + symbol_info* new_symbol=new symbol_info(); + $$=new_symbol; + $$->code=$1->code; + $$->final_code = $1->final_code; + //debug("declaration_list", $$->code); + } + | declaration_list declaration + { + $$->code=$1->code + "\n" + $2->code; + $$->final_code = $1->final_code; + $$->final_code.insert($$->final_code.end(), $2->final_code.begin(), $2->final_code.end()); + } + | error SEMICOLON {yyerrok;} + ; + +statement_list + : statement { + $$=$1; + } + | statement_list statement + { + $$->is_return=($1->is_return)|($2->is_return); + // if($1->return_type!="") $$->return_type=$1->return_type; + // else $$->return_type=$2->return_type; + $$->code=$1->code + "\n" + $2->code; + $$->final_code = $1->final_code; + $$->final_code.insert($$->final_code.end(), $2->final_code.begin(), $2->final_code.end()); + } + | error SEMICOLON {yyerrok;} + ; + +expression_statement + : SEMICOLON + | expression SEMICOLON {$$=$1;} + ; + +selection_statement + : IF LPARENTHESES expression RPARENTHESES statement + { + string truelabel=newlabel(); + string falselabel=newlabel(); + symbol_info* new_symbol=new symbol_info(); + $$=new_symbol; + $$->code=$3->code+"\n"+"if ("+ $3->place.first +") goto "+truelabel+"\n"+"goto "+falselabel+"\n"+truelabel+":\n"+$5->code+"\n"+falselabel+":\n"; + $$->final_code = $3->final_code; + $$->final_code.push_back({"if ("+ $3->place.first +") goto "+truelabel,curr_scope}); + $$->final_code.push_back({"goto "+falselabel,curr_scope}); + $$->final_code.push_back({truelabel+":",curr_scope}); + $$->final_code.insert($$->final_code.end(), $5->final_code.begin(), $5->final_code.end()); + $$->final_code.push_back({falselabel+":",curr_scope}); + } + | IF LPARENTHESES expression RPARENTHESES statement ELSE statement + { + string truelabel=newlabel(); + string falselabel=newlabel(); + string endlabel=newlabel(); + symbol_info* new_symbol=new symbol_info(); + $$=new_symbol; + $$->code=$3->code+"\n"+"if ("+ $3->place.first +") goto "+truelabel+"\n"+"goto "+falselabel+"\n"+truelabel+":\n"+$5->code+"\n"+"goto "+endlabel+"\n"+falselabel+":\n"+$7->code+"\n"+endlabel+":\n"; + $$->final_code = $3->final_code; + $$->final_code.push_back({"if ("+ $3->place.first +") goto "+truelabel,curr_scope}); + $$->final_code.push_back({"goto "+falselabel,curr_scope}); + $$->final_code.push_back({truelabel+":",curr_scope}); + $$->final_code.insert($$->final_code.end(), $5->final_code.begin(), $5->final_code.end()); + $$->final_code.push_back({"goto "+endlabel,curr_scope}); + $$->final_code.push_back({falselabel+":",curr_scope}); + $$->final_code.insert($$->final_code.end(), $7->final_code.begin(), $7->final_code.end()); + $$->final_code.push_back({endlabel+":",curr_scope}); + } + | SWITCH{queue> q; + case_list.push(q); + }LPARENTHESES expression RPARENTHESES statement + { + string str=""; + vector> temp; + while(!case_list.top().empty()){ + string label=case_list.top().front().second; + string case_value=case_list.top().front().first; + case_list.top().pop(); + if(case_value=="default") + { + str+="goto "+label+"\n"; + temp.push_back({"goto "+label,curr_scope}); + } + else{ + qid var=newtemp("int",curr_scope); + str+=var.first+" := "+$4->place.first+" == "+case_value; + //str+="if ( "+$4->place.first+" == "+case_value+") goto "+label+"\n"; + str+="if ( "+var.first+" ) goto "+label+"\n"; + //temp.push_back({"if ( "+$4->place.first+" == "+case_value+") goto "+label,curr_scope}); + temp.push_back({var.first+" := "+$4->place.first+" == "+case_value,curr_scope}); + temp.push_back({"if ( "+var.first+" ) goto "+label,curr_scope}); + + } + } + string endlabel=newlabel(); + $$=new symbol_info(); + $$->code= $4->code+"\n"+str+"\n"+$6->code+"\n"+endlabel+":\n"; + $$->final_code = $4->final_code; + $$->final_code.insert($$->final_code.end(), temp.begin(), temp.end()); + $$->final_code.insert($$->final_code.end(), $6->final_code.begin(), $6->final_code.end()); + $$->final_code.push_back({endlabel+":",curr_scope}); + $$->code=replace_break_continue($$->code,endlabel," ",1); + $$->final_code=replace_break_continue_final($$->final_code,endlabel," ",1); + case_list.pop(); + } + ; + +iteration_statement + : WHILE LPARENTHESES expression RPARENTHESES statement + { + string startlabel=newlabel(); + string endlabel=newlabel(); + string truelabel=newlabel(); + symbol_info* new_symbol=new symbol_info(); + $$=new_symbol; + $$->code=startlabel+":\n"+$3->code+"\n"+"if ("+$3->place.first+") goto "+truelabel+"\n"+"goto "+endlabel+"\n"+truelabel+":\n"+$5->code+"\n"+"goto "+startlabel+"\n"+endlabel+":\n"; + $$->final_code.push_back({startlabel+":",curr_scope}); + $$->final_code.insert($$->final_code.end(), $3->final_code.begin(), $3->final_code.end()); + $$->final_code.push_back({"if ("+$3->place.first+") goto "+truelabel,curr_scope}); + $$->final_code.push_back({"goto "+endlabel,curr_scope}); + $$->final_code.push_back({truelabel+":",curr_scope}); + $$->final_code.insert($$->final_code.end(), $5->final_code.begin(), $5->final_code.end()); + $$->final_code.push_back({"goto "+startlabel,curr_scope}); + $$->final_code.push_back({endlabel+":",curr_scope}); + + $$->code=replace_break_continue($$->code,endlabel,startlabel,1); + $$->final_code=replace_break_continue_final($$->final_code,endlabel,startlabel,1); + } + | UNTIL LPARENTHESES expression RPARENTHESES statement + { + string startlabel=newlabel(); + string endlabel=newlabel(); + string truelabel=newlabel(); + symbol_info* new_symbol=new symbol_info(); + $$=new_symbol; + $$->code=$3->code+"\n"+startlabel+":\n"+"if ("+$3->place.first+") goto "+endlabel+"\n"+" goto "+truelabel+"\n"+truelabel+":\n"+$5->code+"\n"+"\n"+" goto "+startlabel+"\n"+endlabel+":\n"; + $$->final_code.push_back({startlabel+":",curr_scope}); + $$->final_code.insert($$->final_code.end(), $3->final_code.begin(), $3->final_code.end()); + $$->final_code.push_back({"if ("+$3->place.first+") goto "+endlabel,curr_scope}); + $$->final_code.push_back({"goto "+truelabel,curr_scope}); + $$->final_code.push_back({truelabel+":",curr_scope}); + $$->final_code.insert($$->final_code.end(), $5->final_code.begin(), $5->final_code.end()); + $$->final_code.push_back({"goto "+startlabel,curr_scope}); + $$->final_code.push_back({endlabel+":",curr_scope}); + $$->code=replace_break_continue($$->code,endlabel,startlabel,1); + $$->final_code=replace_break_continue_final($$->final_code,endlabel,startlabel,1); + } + | DO statement WHILE LPARENTHESES expression RPARENTHESES SEMICOLON + { + string startlabel=newlabel(); + string endlabel=newlabel(); + string truelabel=newlabel(); + symbol_info* new_symbol=new symbol_info(); + $$=new_symbol; + $$->final_code.push_back({startlabel+":",curr_scope}); + $$->final_code.insert($$->final_code.end(), $2->final_code.begin(), $2->final_code.end()); + $$->final_code.push_back({truelabel+":",curr_scope}); + $$->final_code.insert($$->final_code.end(), $5->final_code.begin(), $5->final_code.end()); + $$->final_code.push_back({"if ("+$5->place.first+") goto "+startlabel,curr_scope}); + $$->final_code.push_back({"goto "+endlabel,curr_scope}); + $$->final_code.push_back({endlabel+":",curr_scope}); + $$->code=startlabel+":\n"+$2->code+"\n"+truelabel+":\n"+$5->code+"\n"+"\n"+"if ("+$5->place.first+") goto "+startlabel+"\n"+"goto "+endlabel+"\n"+endlabel+":\n"; + $$->code=replace_break_continue($$->code,endlabel,startlabel,1); + $$->final_code=replace_break_continue_final($$->final_code,endlabel,startlabel,1); + } + | FOR LPARENTHESES expression_statement expression_statement RPARENTHESES statement + { + string startlabel=newlabel(); + string endlabel=newlabel(); + string truelabel=newlabel(); + symbol_info* new_symbol=new symbol_info(); + $$=new_symbol; + $$->final_code = $3->final_code; + $$->final_code.push_back({startlabel+":",curr_scope}); + $$->final_code.insert($$->final_code.end(), $4->final_code.begin(), $4->final_code.end()); + $$->final_code.push_back({"if ("+$4->place.first+") goto "+truelabel,curr_scope}); + $$->final_code.push_back({"goto "+endlabel,curr_scope}); + $$->final_code.push_back({truelabel+":",curr_scope}); + $$->final_code.insert($$->final_code.end(), $6->final_code.begin(), $6->final_code.end()); + $$->final_code.push_back({"goto "+startlabel,curr_scope}); + $$->final_code.push_back({endlabel+":",curr_scope}); + $$->code=$3->code+"\n"+startlabel+":\n"+$4->code+"\n"+"if ("+$4->place.first+") goto "+truelabel+"\n"+"goto "+endlabel+"\n"+truelabel+":\n"+$6->code+"\n"+"\n"+"goto "+startlabel+"\n"+endlabel+":\n"; + $$->code=replace_break_continue($$->code,endlabel,startlabel,1); + $$->final_code=replace_break_continue_final($$->final_code,endlabel,startlabel,1); + } + | FOR LPARENTHESES expression_statement expression_statement expression RPARENTHESES statement + { + string startlabel=newlabel(); + string endlabel=newlabel(); + string truelabel=newlabel(); + string updatelabel=newlabel(); + symbol_info* new_symbol=new symbol_info(); + $$=new_symbol; + $$->final_code = $3->final_code; + $$->final_code.push_back({startlabel+":",curr_scope}); + $$->final_code.insert($$->final_code.end(), $4->final_code.begin(), $4->final_code.end()); + $$->final_code.push_back({"if ("+$4->place.first+") goto "+truelabel,curr_scope}); + $$->final_code.push_back({"goto "+endlabel,curr_scope}); + $$->final_code.push_back({truelabel+":",curr_scope}); + $$->final_code.insert($$->final_code.end(), $7->final_code.begin(), $7->final_code.end()); + $$->final_code.push_back({updatelabel+":",curr_scope}); + $$->final_code.insert($$->final_code.end(), $5->final_code.begin(), $5->final_code.end()); + $$->final_code.push_back({"goto "+startlabel,curr_scope}); + $$->final_code.push_back({endlabel+":",curr_scope}); + $$->code=$3->code+"\n"+startlabel+":\n"+$4->code+"\n"+"if ("+$4->place.first+") goto "+truelabel+"\n"+"goto "+endlabel+"\n"+truelabel+":\n"+$7->code+"\n"+updatelabel+":\n"+$5->code+"\n"+"goto "+startlabel+"\n"+endlabel+":\n"; + $$->code=replace_break_continue($$->code,endlabel,updatelabel,0); + $$->final_code=replace_break_continue_final($$->final_code,endlabel,updatelabel,0); + } + ; + +jump_statement + : GOTO ID SEMICOLON + { + //idhar ID ko symtab me insert karna he + if(goto_list.find($2)==goto_list.end()){ + string label=newlabel(); + goto_list[$2]=label; + symbol_info* new_symbol=new symbol_info(); + new_symbol->final_code.push_back({"goto "+label,curr_scope}); + new_symbol->code="goto "+label+"\n"; + $$=new_symbol; + } + else{ + symbol_info* new_symbol=new symbol_info(); + $$=new_symbol; + string label=goto_list[$2]; + $$->final_code.push_back({"goto "+label,curr_scope}); + $$->code="goto "+label+"\n"; + // debug("goto", $$->code); + } + + // debug("goto1111 ",new_symbol->code); + + + // cerr << "goto\n"; + } + | CONTINUE SEMICOLON + { + symbol_info* new_symbol=new symbol_info(); + $$=new_symbol; + $$->is_continue=true; + $$->final_code.push_back({"continue",curr_scope}); + $$->code="\n continue \n"; + } + | BREAK SEMICOLON + { + symbol_info* new_symbol=new symbol_info(); + $$=new_symbol; + $$->is_break=true; + $$->final_code.push_back({"break",curr_scope}); + $$->code="\n break \n"; + } + | RETURN SEMICOLON + { + symbol_info* new_symbol=new symbol_info(); + $$=new_symbol; + $$->is_return=true; + $$->return_type="void"; + $$->final_code.push_back({"RETURN",curr_scope}); + $$->code="\nRETURN\n"; + } + | RETURN expression SEMICOLON + { + symbol_info* new_symbol=new symbol_info(); + $$=new_symbol; + $$->is_return=true; + $$->return_type=$2->type; + $$->final_code = $2->final_code; + $$->final_code.push_back({"RETURN "+$2->place.first,curr_scope}); + $$->code=$2->code + "\nRETURN "+$2->place.first+"\n"; + //debug("return ",$$->code); + } + ; + +start_symbol: translation_unit +{ + //cerr<<"-----------------"<code<<"----------------"<code); + // cerr<> temp=$1->final_code; + static_variables_code.insert(static_variables_code.end(), temp.begin(), temp.end()); + cleaned_TAC=clean_vector_TAC(static_variables_code); + // print_vector($1->final_code); + // print_vector(cleaned_TAC); +} +; +translation_unit + : external_declaration + { + $$->code=$1->code; + $$->final_code = $1->final_code; + } + | translation_unit external_declaration + { + $$->code=$1->code+$2->code; + $$->final_code = $1->final_code; + $$->final_code.insert($$->final_code.end(), $2->final_code.begin(), $2->final_code.end()); + } + | + ; + +external_declaration + : function_definition + { + $$=$1; + } + | declaration + ; + +function_definition + : declaration_specifiers declarator declaration_list compound_statement + | declaration_specifiers declarator + { + var_name=$2->param_list; + type_list=$2->param_types; + curr_scope->symbol_map[$2->name]->type=$1; + } + compound_statement + { + if(strcmp($1,"void")==0){ + + // if($4->return_type!="void"){ + // error_list.push_back("Line "+to_string(yylineno)+" : Return type not matched"); + // } + } + else{ + if($4->is_return==0){ + error_list.push_back("Line "+to_string(yylineno)+" : Missing return statement"); + } + else{ + // if($4->return_type!=$1){ + // error_list.push_back("Line "+to_string(yylineno)+" : Return type not matched"); + // } + } + } + symbol_info* new_symbol=new symbol_info(); + $$=new_symbol; + $$->code="\nFUNC_BEGIN "+$2->name+"\n"; + $$->final_code.push_back({"FUNC_BEGIN "+$2->name,curr_scope}); + for(int i=0;i<$2->param_list.size();i++){ + $$->final_code.push_back({"param"+std::to_string(i)+" := PARAM",scope_list[0]}); + $$->code=$$->code+"param"+std::to_string(i)+" := PARAM\n"; + } + for(int i=0;i<$2->param_list.size();i++){ + $$->final_code.push_back({$2->param_list[i]+" := param"+std::to_string(i),scope_list[0]}); + $$->code=$$->code+$2->param_list[i]+" := param"+std::to_string(i)+"\n"; + } + $$->final_code.insert($$->final_code.end(), $4->final_code.begin(), $4->final_code.end()); + $$->final_code.push_back({"FUNC_END "+$2->name,curr_scope}); + $$->code=$$->code+$4->code+"\nFUNC_END "+$2->name+"\n"; + scope_list.pop_back(); + + } + | declarator declaration_list compound_statement + | declarator compound_statement + ; +%% + +void yyerror(const char *s) { + fprintf(stderr, "Error at line %d: %s\n", yylineno, s); +} + +void print_errors() { + if(error_list.size()==0){ + cerr<<"# ======================================================================"<symbol_map) { + if (!it.second) { // Check if symbol_info* is null (shouldn't happen after your fix) + printf("| %-15s | %-20s | %-7s | %-10s |\n", + it.first.c_str(), "uninitialized", "N/A", "N/A"); + continue; + } + + std::string valueStr = "N/A"; // Default value + int size = 0; // Default size + + // Assign size based on type + if (it.second->type == "int") { + size = 4; + if (it.second->ptr) valueStr = std::to_string(*(int*)(it.second->ptr)); + } else if (it.second->type == "float") { + size = 4; + if (it.second->ptr) valueStr = std::to_string(*(float*)(it.second->ptr)); + } else if (it.second->type == "char") { + size = 2; + valueStr = it.second->str_val; + } else if (it.second->type == "long") { + size = 8; + if (it.second->ptr) valueStr = std::to_string(*(long*)(it.second->ptr)); + } else { + size = 0; // Unknown type + } + + printf("| %-15s | %-20s | %-7d | %-10s |\n", + it.first.c_str(), // Identifier + it.second->type.c_str(), // Type + size, // Size + valueStr.c_str()); // Value + + if((it.second->type).substr(0,6)=="struct"){ + for(int i=0;istruct_attr_values.size();i++){ + printf("| %-15s | %-20s | %-7d | %-10s |\n", + (it.first+"."+it.second->param_list[i]).c_str(), // Identifier + it.second->struct_attr_values[i]->type.c_str(), // Type + 4, // Size + std::to_string(*(int*)(it.second->struct_attr_values[i]->ptr)).c_str()); // Value + } + } + if((it.second->type).substr(0,5)=="union"){ + for(int i=0;istruct_attr_values.size();i++){ + printf("| %-15s | %-20s | %-7d | %-10s |\n", + (it.first+"."+it.second->param_list[i]).c_str(), // Identifier + it.second->struct_attr_values[i]->type.c_str(), // Type + 4, // Size + std::to_string(*(int*)(it.second->struct_attr_values[i]->ptr)).c_str()); // Value + } + } + } + printf("-----------------------------------------------------------------\n"); + // cerr<<"Scope is here"<symbol_map["printf"]=new_symbol; + curr_scope->symbol_map["scanf"]=new_symbol; + yyparse(); + /* print_scope_table(); */ + codegen_main(); + +} diff --git a/Assignment4/src/scanner.l b/Assignment4/src/scanner.l new file mode 100644 index 0000000..ab36018 --- /dev/null +++ b/Assignment4/src/scanner.l @@ -0,0 +1,290 @@ +%option noyywrap +%{ + #include "parser.tab.h" + #include "include/utility.h" + #include + #include + #include + + extern int yylineno; + extern int yylex(); + extern YYSTYPE yylval; + + #define MAX_ERRORS 100 + + char *errors[MAX_ERRORS]; + int error_count = 0; + + void error_call(const char *s, int t) { + if (error_count >= MAX_ERRORS) { + fprintf(stderr, "Error buffer full!\n"); + return; + } + + char buffer[256]; + if (t == 0) { + snprintf(buffer, sizeof(buffer), "Invalid identifier: %s in line no. %d", s, yylineno); + } else { + snprintf(buffer, sizeof(buffer), "Invalid token: %s in line no. %d", s, yylineno); + } + + errors[error_count] = strdup(buffer); + error_count++; + } +%} + +%option yylineno + +DELIM [ \t\n\r] +WS {DELIM}+ + +INCLUDE "#include"[ \t]*("<"[^">"]+">"|"\""[^\"]+"\"") +AUTO "auto" +STRUCT "struct" +BOOL "bool" +BREAK "break" +CASE "case" +CONTINUE "continue" +GOTO "goto" +DO "do" +DEFAULT "default" +IF "if" +ELSE "else" +FOR "for" +CONST "const" +TRUE "true" +FALSE "false" +STATIC "static" +SWITCH "switch" +WHILE "while" +UNTIL "until" +VOID "void" +RETURN "return" +SIZEOF "sizeof" +FLOAT "float" +INT "int" +DOUBLE "double" +EXTERN "extern" +SHORT "short" +LONG "long" +CHAR "char" +ENUM "enum" +REGISTER "register" +SIGNED "signed" +TYPEDEF "typedef" +UNION "union" +UNSIGNED "unsigned" +VOLATILE "volatile" + +CLASS "class" +PUBLIC "public" +PRIVATE "private" +PROTECTED "protected" +NULLPTR "nullptr" +NAMESPACE "namespace" +VIRTUAL "virtual" +CATCH "catch" + +NOTLETTER [^A-Za-z_] +LETTER [A-Za-z] +DIGIT [0-9] +HEXA_DIGIT [a-fA-F0-9] +EXP [Ee][+-]?{DIGIT}+ +FS (f|F|l|L) +IS (u|U|l|L)* + + +ID ({LETTER}|_)({LETTER}|_|{DIGIT})* +HEXA_LITERAL 0[xX]{HEXA_DIGIT}+{IS}? +OCTAL_LITERAL 0[0-7]+{IS}? +DECIMAL_LITERAL {DIGIT}+{IS}? +EXP_LITERAL {DIGIT}+[Ee][+-]?{DIGIT}+{FS}? +FLOAT_LITERAL {DIGIT}*"."{DIGIT}+({EXP})?{FS}? + +STRING_LITERAL L?\"(\\.|[^\\"])*\" +CHARACTER_LITERAL (L|u8|u|U)?'((\\.)|[^'\\])' +SINCMNT \/\/.* +MULCMNT "/*"([^*]|\*+[^*/])*\*+"/" + + +RBRACE "\}" +LBRACE "\{" +LBRACKET "\[" +RBRACKET "\]" +LPARENTHESES "\(" +RPARENTHESES "\)" +DOT "\." +COMMA "," +COLON ":" +SEMICOLON ";" +PLUS "\+" +MINUS "-" +STAR "\*" +DIVIDE "\/" +MODULO "%" +AMPERSAND "&" +OR "\|" +XOR "\^" +EXCLAMATION "!" +TILDE "~" +EQUALS "=" +LESS_THAN "<" +GREATER_THAN ">" +QUESTION_MARK "\?" +INCREMENT "\+\+" +DECREMENT "--" +REL_AND "&&" +REL_OR "\|\|" +REL_EQUALS "==" +REL_NOT_EQ "!=" +LESS_EQUALS "<=" +GREATER_EQUALS ">=" +ASSIGN_PLUS "\+=" +ASSIGN_MINUS "-=" +ASSIGN_STAR "\*=" +ASSIGN_DIV "\/=" +ASSIGN_MOD "%=" +ASSIGN_AND "&=" +ASSIGN_OR "\|=" +ASSIGN_XOR "\^=" +LEFT_SHIFT "<<" +LEFT_SHIFT_EQ "<<=" +RIGHT_SHIFT ">>" +RIGHT_SHIFT_EQ "\>>=" +LAMBDA_ARROW "->" +VARIABLE_ARGS "..." + +INVALID_ID (({DIGIT})+({LETTER}|_)*|{DIGIT}+{LETTER}+(\.{DIGIT}*)?) + +%% +{WS} {} +{INCLUDE} {yylval.str = strdup(yytext); return INCLUDE; } +{AUTO} { yylval.str = strdup(yytext); return AUTO; } +{STRUCT} { yylval.str = strdup(yytext); return STRUCT; } +{BOOL} { yylval.str = strdup(yytext); return BOOL; } +{BREAK} { yylval.str = strdup(yytext); return BREAK; } +{CASE} { yylval.str = strdup(yytext); return CASE; } +{CONTINUE} { yylval.str = strdup(yytext); return CONTINUE; } +{GOTO} { yylval.str = strdup(yytext); return GOTO; } +{DO} { yylval.str = strdup(yytext); return DO; } +{DEFAULT} { yylval.str = strdup(yytext); return DEFAULT; } +{IF} { yylval.str = strdup(yytext); return IF; } +{ELSE} { yylval.str = strdup(yytext); return ELSE; } +{FOR} { yylval.str = strdup(yytext); return FOR; } +{CONST} { yylval.str = strdup(yytext); return CONST; } +{TRUE} { yylval.str = strdup(yytext); return TRUE; } +{FALSE} { yylval.str = strdup(yytext); return FALSE; } +{STATIC} { yylval.str = strdup(yytext); return STATIC; } +{SWITCH} { yylval.str = strdup(yytext); return SWITCH; } +{WHILE} { yylval.str = strdup(yytext); return WHILE; } +{UNTIL} { yylval.str = strdup(yytext); return UNTIL; } +{VOID} { yylval.str = strdup(yytext); return VOID; } +{RETURN} { yylval.str = strdup(yytext); return RETURN; } +{SIZEOF} { yylval.str = strdup(yytext); return SIZEOF; } +{FLOAT} { yylval.str = strdup(yytext); return FLOAT; } +{INT} { yylval.str = strdup(yytext); return INT; } +{DOUBLE} { yylval.str = strdup(yytext); return DOUBLE; } +{EXTERN} { yylval.str = strdup(yytext); return EXTERN; } +{SHORT} { yylval.str = strdup(yytext); return SHORT; } +{LONG} { yylval.str = strdup(yytext); return LONG; } +{CHAR} { yylval.str = strdup(yytext); return CHAR; } +{ENUM} { yylval.str = strdup(yytext); return ENUM; } +{REGISTER} { yylval.str = strdup(yytext); return REGISTER; } +{SIGNED} { yylval.str = strdup(yytext); return SIGNED; } +{TYPEDEF} { yylval.str = strdup(yytext); return TYPEDEF; } +{UNION} { yylval.str = strdup(yytext); return UNION; } +{UNSIGNED} { yylval.str = strdup(yytext); return UNSIGNED; } +{VOLATILE} { yylval.str = strdup(yytext); return VOLATILE; } +{CLASS} { yylval.str = strdup(yytext); return CLASS; } +{PUBLIC} { yylval.str = strdup(yytext); return PUBLIC; } +{PRIVATE} { yylval.str = strdup(yytext); return PRIVATE; } +{PROTECTED} { yylval.str = strdup(yytext); return PROTECTED; } +{NULLPTR} { yylval.str = strdup(yytext); return NULLPTR; } +{NAMESPACE} { yylval.str = strdup(yytext); return NAMESPACE; } +{VIRTUAL} { yylval.str = strdup(yytext); return VIRTUAL; } +{CATCH} { yylval.str = strdup(yytext); return CATCH; } + + + +{ID} { yylval.str = strdup(yytext); return ID; } +{HEXA_LITERAL} { yylval.str = strdup(yytext); return HEXA_LITERAL; } +{OCTAL_LITERAL} { yylval.str = strdup(yytext); return OCTAL_LITERAL; } +{DECIMAL_LITERAL} { yylval.symbol_info = new symbol_info(); + yylval.symbol_info->type = "int"; + yylval.symbol_info->ptr = new int(atoi(yytext)); + yylval.symbol_info->symbol_size=4; + return DECIMAL_LITERAL; } +{EXP_LITERAL} { yylval.str = strdup(yytext); return EXP_LITERAL; } +{FLOAT_LITERAL} { yylval.symbol_info = new symbol_info(); + yylval.symbol_info->type = "float"; + yylval.symbol_info->ptr = new float(atof(yytext)); + yylval.symbol_info->symbol_size=4; + return FLOAT_LITERAL; } +{STRING_LITERAL} { yylval.symbol_info = new symbol_info(); + yylval.symbol_info->type = "string"; + yylval.symbol_info->str_val= strdup(yytext); + yylval.symbol_info->symbol_size=strlen(yytext); + return STRING_LITERAL; } +{CHARACTER_LITERAL} { yylval.symbol_info = new symbol_info(); + yylval.symbol_info->type = "char"; + char* temp = strdup(yytext); + yylval.symbol_info->ptr = new char(temp[1]); + yylval.symbol_info->str_val = std::string(temp + 1); + yylval.symbol_info->symbol_size=1; return CHARACTER_LITERAL; free(temp);} +{SINCMNT} { /* ignore single-line comment */ } +{MULCMNT} { /* ignore multi-line comment */ } + + +{RBRACE} { return RBRACE; } +{LBRACE} { return LBRACE; } +{LBRACKET} { return LBRACKET; } +{RBRACKET} { return RBRACKET; } +{LPARENTHESES} { return LPARENTHESES; } +{RPARENTHESES} { return RPARENTHESES; } +{DOT} { return DOT; } +{COMMA} { return COMMA; } +{COLON} { return COLON; } +{SEMICOLON} { return SEMICOLON; } +{PLUS} { return PLUS; } +{MINUS} { return MINUS; } +{STAR} { return STAR; } +{DIVIDE} { return DIVIDE; } +{MODULO} { return MODULO; } +{AMPERSAND} { return AMPERSAND; } +{OR} { return OR; } +{XOR} { return XOR; } +{EXCLAMATION} { return EXCLAMATION; } +{TILDE} { return TILDE; } +{EQUALS} { return EQUALS; } +{LESS_THAN} { return LESS_THAN; } +{GREATER_THAN} { return GREATER_THAN; } +{QUESTION_MARK} { return QUESTION_MARK; } +{INCREMENT} { return INCREMENT; } +{DECREMENT} { return DECREMENT; } +{REL_AND} { return REL_AND; } +{REL_OR} { return REL_OR; } +{REL_EQUALS} { return REL_EQUALS; } +{REL_NOT_EQ} { return REL_NOT_EQ; } +{LESS_EQUALS} { return LESS_EQUALS; } +{GREATER_EQUALS} { return GREATER_EQUALS; } +{ASSIGN_PLUS} { return ASSIGN_PLUS; } +{ASSIGN_MINUS} { return ASSIGN_MINUS; } +{ASSIGN_STAR} { return ASSIGN_STAR; } +{ASSIGN_DIV} { return ASSIGN_DIV; } +{ASSIGN_MOD} { return ASSIGN_MOD; } +{ASSIGN_AND} { return ASSIGN_AND; } +{ASSIGN_OR} { return ASSIGN_OR; } +{ASSIGN_XOR} { return ASSIGN_XOR; } +{LEFT_SHIFT} { return LEFT_SHIFT; } +{LEFT_SHIFT_EQ} { return LEFT_SHIFT_EQ; } +{RIGHT_SHIFT} { return RIGHT_SHIFT; } +{RIGHT_SHIFT_EQ} { return RIGHT_SHIFT_EQ; } +{LAMBDA_ARROW} { return LAMBDA_ARROW; } +{VARIABLE_ARGS} { return VARIABLE_ARGS; } + +{INVALID_ID} { fprintf(stderr, "Invalid identifier: %s at line %d\n", yytext, yylineno); return INVALID_ID; } + +. { fprintf(stderr, "Invalid token: %s at line %d\n", yytext, yylineno); return yytext[0]; } + +%% + diff --git a/Assignment4/static.c b/Assignment4/static.c new file mode 100644 index 0000000..1de589c --- /dev/null +++ b/Assignment4/static.c @@ -0,0 +1,32 @@ +void count_with_static() { + static int counter = 0; + counter++; + printf("Static counter = %d\n", counter); +} + +int main() { + int i = 0; + +start_loop: + for (i = 0; i < 10; i++) { + // if (i == 2) { + // continue; + // } + if (i == 5) { + break; + } + + printf("i = %d\n", i); + // count_with_static(); + } + + // static int repeat = 0; + if (repeat == 0) { + repeat = 1; + printf("Repeating the loop using goto!\n\n"); + goto start_loop; + } + + printf("Program finished.\n"); + return 0; +} diff --git a/Assignment4/test/input1.c b/Assignment4/test/input1.c new file mode 100644 index 0000000..cf3c250 --- /dev/null +++ b/Assignment4/test/input1.c @@ -0,0 +1,74 @@ +//basic.c +// #include + +int addx(int a, int b) { + return a + b; +} + +int factorial(int n) { + if (n <= 1) return 1; + else return n * factorial(n - 1); +} + +// int array_sum(int arr[5], int size) { + +// } + +struct Point { + int x; + int y; +}; + +// float point_sum(struct Point *p) { +// return p->x / p->y; +// } + +int main() { + int a = 5, b = 10; + + int result = addx(a, b); + if (result != 15) { + printf("Arithmetic test failed: %d\n", result); + return 1; + } + + int fact = factorial(5); + if (fact != 120) { + printf("Recursion test failed: %d\n", fact); + return 1; + } + + int arr[5] = {1, 2, 3, 4, 5}; + // int arr_sum = array_sum(arr, 5); + int array_sum = 0; + int i = 0; + for (i = 0; i < 5; i++) { + array_sum = array_sum + arr[i]; + } + // return sum; + if (array_sum != 15) { + printf("Array sum test failed: %d\n", array_sum); + return 1; + } + + // struct Point p = {3, 4}; + // // int p_sum = point_sum(&p); + // // if (p_sum != 7) { + // // printf("Struct test failed: %d\n", p_sum); + // // return 1; + // // } + + int value = 0; + if (a < b) { + value = 1; + } else { + value = 2; + } + if (value != 1) { + printf("Branching test failed: %d\n", value); + return 1; + } + + printf("All tests passed successfully!\n"); + return 0; +} \ No newline at end of file diff --git a/Assignment4/test/input2.c b/Assignment4/test/input2.c new file mode 100644 index 0000000..f5fe193 --- /dev/null +++ b/Assignment4/test/input2.c @@ -0,0 +1,55 @@ +//funcall.c +int add_all(int a1, int a2, int a3, int a4, int a5, int a6, int a7, int a8, int a9, int a10, + int a11, int a12, int a13, int a14, int a15, int a16, int a17, int a18, int a19, int a20, + int a21, int a22, int a23, int a24, int a25, int a26, int a27, int a28, int a29, int a30, + int a31, int a32, int a33, int a34, int a35, int a36, int a37, int a38, int a39, int a40, + int a41, int a42, int a43, int a44, int a45, int a46, int a47, int a48, int a49, int a50, + int a51, int a52, int a53, int a54, int a55, int a56, int a57, int a58, int a59, int a60, + int a61, int a62, int a63, int a64, int a65, int a66, int a67, int a68, int a69, int a70, + int a71, int a72, int a73, int a74, int a75, int a76, int a77, int a78, int a79, int a80, + int a81, int a82, int a83, int a84, int a85, int a86, int a87, int a88, int a89, int a90, + int a91, int a92, int a93, int a94, int a95, int a96, int a97, int a98, int a99, int a100) +{ +return a1 + a2 + a3 + a4 + a5 + a6 + a7 + a8 + a9 + a10 + + a11 + a12 + a13 + a14 + a15 + a16 + a17 + a18 + a19 + a20 + + a21 + a22 + a23 + a24 + a25 + a26 + a27 + a28 + a29 + a30 + + a31 + a32 + a33 + a34 + a35 + a36 + a37 + a38 + a39 + a40 + + a41 + a42 + a43 + a44 + a45 + a46 + a47 + a48 + a49 + a50 + + a51 + a52 + a53 + a54 + a55 + a56 + a57 + a58 + a59 + a60 + + a61 + a62 + a63 + a64 + a65 + a66 + a67 + a68 + a69 + a70 + + a71 + a72 + a73 + a74 + a75 + a76 + a77 + a78 + a79 + a80 + + a81 + a82 + a83 + a84 + a85 + a86 + a87 + a88 + a89 + a90 + + a91 + a92 + a93 + a94 + a95 + a96 + a97 + a98 + a99 + a100; +} + +int main() { +// Declare and initialize 100 variables +int a1 = 10, a2 = 10, a3 = 10, a4 = 10, a5 = 10, a6 = 10, a7 = 10, a8 = 10, a9 = 10, a10 = 10; +int a11 = 10, a12 = 10, a13 = 10, a14 = 10, a15 = 10, a16 = 10, a17 = 10, a18 = 10, a19 = 10, a20 = 10; +int a21 = 10, a22 = 10, a23 = 10, a24 = 10, a25 = 10, a26 = 10, a27 = 10, a28 = 10, a29 = 10, a30 = 10; +int a31 = 10, a32 = 10, a33 = 10, a34 = 10, a35 = 10, a36 = 10, a37 = 10, a38 = 10, a39 = 10, a40 = 10; +int a41 = 10, a42 = 10, a43 = 10, a44 = 10, a45 = 10, a46 = 10, a47 = 10, a48 = 10, a49 = 10, a50 = 10; +int a51 = 10, a52 = 10, a53 = 10, a54 = 10, a55 = 10, a56 = 10, a57 = 10, a58 = 10, a59 = 10, a60 = 10; +int a61 = 10, a62 = 10, a63 = 10, a64 = 10, a65 = 10, a66 = 10, a67 = 10, a68 = 10, a69 = 10, a70 = 10; +int a71 = 10, a72 = 10, a73 = 10, a74 = 10, a75 = 10, a76 = 10, a77 = 10, a78 = 10, a79 = 10, a80 = 10; +int a81 = 10, a82 = 10, a83 = 10, a84 = 10, a85 = 10, a86 = 10, a87 = 10, a88 = 10, a89 = 10, a90 = 10; +int a91 = 10, a92 = 10, a93 = 10, a94 = 10, a95 = 10, a96 = 10, a97 = 10, a98 = 10, a99 = 10, a100 = 10; + +// Call the function with 100 arguments +int sum = add_all(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, + a11, a12, a13, a14, a15, a16, a17, a18, a19, a20, + a21, a22, a23, a24, a25, a26, a27, a28, a29, a30, + a31, a32, a33, a34, a35, a36, a37, a38, a39, a40, + a41, a42, a43, a44, a45, a46, a47, a48, a49, a50, + a51, a52, a53, a54, a55, a56, a57, a58, a59, a60, + a61, a62, a63, a64, a65, a66, a67, a68, a69, a70, + a71, a72, a73, a74, a75, a76, a77, a78, a79, a80, + a81, a82, a83, a84, a85, a86, a87, a88, a89, a90, + a91, a92, a93, a94, a95, a96, a97, a98, a99, a100); + +printf("Sum of all variables = %d\n", sum); + +return 0; +} + + diff --git a/Assignment4/test/input3.c b/Assignment4/test/input3.c new file mode 100644 index 0000000..6f4d557 --- /dev/null +++ b/Assignment4/test/input3.c @@ -0,0 +1,38 @@ +//peep.c +int main() { + int a = 5, b = 10, c = 15, d = 20; + + // Redundant calculation + int x = a * 2; + int y = a + a; + + // Constant folding + int z = 4 * 5; + float w = 30.0 / 5.0; + + // Strength reduction + int u = d * 8; + + // Dead code (if optimization is enabled) + int unused = 100; + + // Combine multiple increments + int counter = 0; + counter = counter + 1; + counter = counter + 1; + counter = counter + 1; + + int temp = b; + temp = temp;// Useless assignment + + if (1) { + printf("This branch is always taken.\n"); + } else { + printf("This branch is never taken.\n"); + } + + printf("Results: x=%d, y=%d, z=%d, w=%f\n", x, y, z, w); + printf("Counter: %d%d\n", u,counter); + + return 0; +} \ No newline at end of file diff --git a/Assignment4/test/input4.c b/Assignment4/test/input4.c new file mode 100644 index 0000000..5e013be --- /dev/null +++ b/Assignment4/test/input4.c @@ -0,0 +1,30 @@ +//var100.c +int main() { + // Declare and initialize 100 variables + int a1 = 10, a2 = 10, a3 = 10, a4 = 10, a5 = 10, a6 = 10, a7 = 10, a8 = 10, a9 = 10, a10 = 10; + int a11 = 10, a12 = 10, a13 = 10, a14 = 10, a15 = 10, a16 = 10, a17 = 10, a18 = 10, a19 = 10, a20 = 10; + int a21 = 10, a22 = 10, a23 = 10, a24 = 10, a25 = 10, a26 = 10, a27 = 10, a28 = 10, a29 = 10, a30 = 10; + int a31 = 10, a32 = 10, a33 = 10, a34 = 10, a35 = 10, a36 = 10, a37 = 10, a38 = 10, a39 = 10, a40 = 10; + int a41 = 10, a42 = 10, a43 = 10, a44 = 10, a45 = 10, a46 = 10, a47 = 10, a48 = 10, a49 = 10, a50 = 10; + int a51 = 10, a52 = 10, a53 = 10, a54 = 10, a55 = 10, a56 = 10, a57 = 10, a58 = 10, a59 = 10, a60 = 10; + int a61 = 10, a62 = 10, a63 = 10, a64 = 10, a65 = 10, a66 = 10, a67 = 10, a68 = 10, a69 = 10, a70 = 10; + int a71 = 10, a72 = 10, a73 = 10, a74 = 10, a75 = 10, a76 = 10, a77 = 10, a78 = 10, a79 = 10, a80 = 10; + int a81 = 10, a82 = 10, a83 = 10, a84 = 10, a85 = 10, a86 = 10, a87 = 10, a88 = 10, a89 = 10, a90 = 10; + int a91 = 10, a92 = 10, a93 = 10, a94 = 10, a95 = 10, a96 = 10, a97 = 10, a98 = 10, a99 = 10, a100 = 10; + + // Sum all variables + int sum = a1 + a2 + a3 + a4 + a5 + a6 + a7 + a8 + a9 + a10 + + a11 + a12 + a13 + a14 + a15 + a16 + a17 + a18 + a19 + a20 + + a21 + a22 + a23 + a24 + a25 + a26 + a27 + a28 + a29 + a30 + + a31 + a32 + a33 + a34 + a35 + a36 + a37 + a38 + a39 + a40 + + a41 + a42 + a43 + a44 + a45 + a46 + a47 + a48 + a49 + a50 + + a51 + a52 + a53 + a54 + a55 + a56 + a57 + a58 + a59 + a60 + + a61 + a62 + a63 + a64 + a65 + a66 + a67 + a68 + a69 + a70 + + a71 + a72 + a73 + a74 + a75 + a76 + a77 + a78 + a79 + a80 + + a81 + a82 + a83 + a84 + a85 + a86 + a87 + a88 + a89 + a90 + + a91 + a92 + a93 - a94 + a95 + a96 + a97 + a98 + a99 + a100; + + printf("Sum of all variables = %d\n", sum); + + return 0; +} diff --git a/Assignment4/test/input5.c b/Assignment4/test/input5.c new file mode 100644 index 0000000..67b73bc --- /dev/null +++ b/Assignment4/test/input5.c @@ -0,0 +1,34 @@ +//static.c +int count_with_static() { + int counter = 0; + counter++; + printf("Static counter = %d\n", counter); + return 1; +} + +int main() { + int i = 0; +start_loop: + for (i = 0; i < 10; i++) { + if (i == 2) { + continue; + } + if (i == 5) { + break; + } + + printf("i = %d\n", i); + int r=count_with_static(); + } + + static int repeat = 0; + if (repeat == 0) { + repeat = 1; + printf("Repeating the loop using goto!\n\n"); + goto start_loop; + } + + + printf("Program finished.\n"); + return 0; +} diff --git a/Assignment4/test/input6.c b/Assignment4/test/input6.c new file mode 100644 index 0000000..9158655 --- /dev/null +++ b/Assignment4/test/input6.c @@ -0,0 +1,13 @@ +struct A{ + int a; + int b; +}; +int main() { + struct A str; + str.a = 7; + str.b = 8; + int a[3]={5,4,5}; + int c=a[0]; + printf("%d\n", c); + return 0; +} \ No newline at end of file diff --git a/Assignment4/test/input7.c b/Assignment4/test/input7.c new file mode 100644 index 0000000..d7813c3 --- /dev/null +++ b/Assignment4/test/input7.c @@ -0,0 +1,15 @@ + +int main(){ + int i=0; + int *ptr = &i; + i+=1; + printf("%d\n", *ptr); + int y = 50; + { + y--; + } + int* p1 = &y; + + printf("Single level pointer value: %d\n", *p1); + return 0; +} \ No newline at end of file diff --git a/Assignment4/test/input8.c b/Assignment4/test/input8.c new file mode 100644 index 0000000..da8a9de --- /dev/null +++ b/Assignment4/test/input8.c @@ -0,0 +1,31 @@ +typedef int Integer; +int main() { + Integer a = 3; + Integer b = 10; + Integer c; + switch(a) + { + case 1: + c = a + b; + printf("c is %d\n", c); + break; + case 2: + c = a - b; + printf("c is%d\n", c); + break; + case 3: + c = a * b; + printf("c is%d\n", c); + break; + default: + c = a / b; + printf("c is %d\n", c); + } + int i=2; + until(i<0) + { + printf("i is %d\n", i); + i--; + } + return 0; +} \ No newline at end of file diff --git a/Assignment4/var100.c b/Assignment4/var100.c new file mode 100644 index 0000000..667fac4 --- /dev/null +++ b/Assignment4/var100.c @@ -0,0 +1,29 @@ +int main() { + // Declare and initialize 100 variables + int a1 = 10, a2 = 10, a3 = 10, a4 = 10, a5 = 10, a6 = 10, a7 = 10, a8 = 10, a9 = 10, a10 = 10; + int a11 = 10, a12 = 10, a13 = 10, a14 = 10, a15 = 10, a16 = 10, a17 = 10, a18 = 10, a19 = 10, a20 = 10; + int a21 = 10, a22 = 10, a23 = 10, a24 = 10, a25 = 10, a26 = 10, a27 = 10, a28 = 10, a29 = 10, a30 = 10; + int a31 = 10, a32 = 10, a33 = 10, a34 = 10, a35 = 10, a36 = 10, a37 = 10, a38 = 10, a39 = 10, a40 = 10; + int a41 = 10, a42 = 10, a43 = 10, a44 = 10, a45 = 10, a46 = 10, a47 = 10, a48 = 10, a49 = 10, a50 = 10; + int a51 = 10, a52 = 10, a53 = 10, a54 = 10, a55 = 10, a56 = 10, a57 = 10, a58 = 10, a59 = 10, a60 = 10; + int a61 = 10, a62 = 10, a63 = 10, a64 = 10, a65 = 10, a66 = 10, a67 = 10, a68 = 10, a69 = 10, a70 = 10; + int a71 = 10, a72 = 10, a73 = 10, a74 = 10, a75 = 10, a76 = 10, a77 = 10, a78 = 10, a79 = 10, a80 = 10; + int a81 = 10, a82 = 10, a83 = 10, a84 = 10, a85 = 10, a86 = 10, a87 = 10, a88 = 10, a89 = 10, a90 = 10; + int a91 = 10, a92 = 10, a93 = 10, a94 = 10, a95 = 10, a96 = 10, a97 = 10, a98 = 10, a99 = 10, a100 = 10; + + // Sum all variables + int sum = a1 + a2 + a3 + a4 + a5 + a6 + a7 + a8 + a9 + a10 + + a11 + a12 + a13 + a14 + a15 + a16 + a17 + a18 + a19 + a20 + + a21 + a22 + a23 + a24 + a25 + a26 + a27 + a28 + a29 + a30 + + a31 + a32 + a33 + a34 + a35 + a36 + a37 + a38 + a39 + a40 + + a41 + a42 + a43 + a44 + a45 + a46 + a47 + a48 + a49 + a50 + + a51 + a52 + a53 + a54 + a55 + a56 + a57 + a58 + a59 + a60 + + a61 + a62 + a63 + a64 + a65 + a66 + a67 + a68 + a69 + a70 + + a71 + a72 + a73 + a74 + a75 + a76 + a77 + a78 + a79 + a80 + + a81 + a82 + a83 + a84 + a85 + a86 + a87 + a88 + a89 + a90 + + a91 + a92 + a93 + a94 + a95 + a96 + a97 + a98 + a99 + a100; + + printf("Sum of all variables = %d\n", sum); + + return 0; +}