public static void FRAME(string a, string b) { MOV(registers[(int)Register.OP1], registers[(int)Register.SP]); //get stack pointer ADI(registers[(int)Register.OP1], ((12 + SymbolTable.GetValue(a).size) * -1).ToString()); //move pointer equal to size of function CMP(registers[(int)Register.OP1], registers[(int)Register.SL]); //if the pointer passes the stack limit BLT(registers[(int)Register.OP1], OVERFLOW); //jump to label overflow MOV(registers[(int)Register.PFP], registers[(int)Register.FP]); //save current frame pointer in register (will be PFP for next frame) MOV(registers[(int)Register.FP], registers[(int)Register.SP]); //set frame pointer = stack pointer ADI(registers[(int)Register.SP], (VAR_SIZE * -1).ToString()); //move stack pointer up one (passed new frame's return address) STR(registers[(int)Register.PFP], registers[(int)Register.SP]); //store PFP at location contained in stack pointer ADI(registers[(int)Register.SP], (VAR_SIZE * -1).ToString()); //move stack pointer up one (passed new frame's PFP) if (b == "this") { ADI(registers[(int)Register.PFP], (VAR_SIZE * -2).ToString()); LDR(registers[(int)Register.OP1], registers[(int)Register.PFP]); //load value at address b (which is an address to the object on the heap) STR(registers[(int)Register.OP1], registers[(int)Register.SP]); //store "this" pointer at location contained in stack pointer } else if (a != "MAIN") { //ADI(registers[(int)Register.PFP], (-1*(12+SymbolTable.GetValue(b).offset)).ToString()); ADI(registers[(int)Register.PFP], (-1 * getOffset(b)).ToString()); LDR(registers[(int)Register.OP1], registers[(int)Register.PFP]); //load value at address b (which is an address to the object on the heap) STR(registers[(int)Register.OP1], registers[(int)Register.SP]); //store "this" pointer at location contained in stack pointer } ADI(registers[(int)Register.SP], (VAR_SIZE * -1).ToString()); //move stack pointer up one (passed new frame's "this" pointer) }
public static void new_arr() { SAR exp = SAS.Pop(); SAR type = SAS.Pop(); if (exp.dataType != "int") { SemanticArrError(type, exp); } if (type.value == "null") { SemanticArrError(type, exp); } string[] data1 = { "returnType:int", "accessMod:private" }; Symbol size = new Symbol("t", "t" + uniqueCounter++, "t" + type.value, "tvar", data1); SymbolTable.Add(size); string[] data = { "returnType:" + "@" + type.value, "accessMod:private" }; Symbol temp = new Symbol("t", "t" + uniqueCounter++, "t" + type.value, "tvar", data); SymbolTable.Add(temp); type.symid = temp.symid; int classSize = SymbolTable.GetValue(type.symid).size; string[] sizeData = { "returnType:int", "accessMod:public" }; Symbol sizeLiteral = new Symbol("g", "N4", "4", "ilit", sizeData); SymbolTable.Add(sizeLiteral); ICode.MUL(sizeLiteral.symid, exp.symid, size.symid); ICode.NEW(size.symid, type.symid); type.dataType = "@" + type.value; SAS.Push(type); }
public static void REF(string a, string b, string c) { LDR(registers[(int)Register.OP1], GetLocation(a)); //load address of a ADI(registers[(int)Register.OP1], SymbolTable.GetValue(b).offset.ToString()); //load value at address of b (address of object on heap) //string type = SymbolTable.GetValue(a).data[0].Split(':')[1];//get type c = "=" + c; STR(registers[(int)Register.OP1], GetLocation(c));//store value at address of c }
private static string GetLocation(string operand) { bool refDeclaration = false; if (operand[0] == '=') { refDeclaration = true; operand = operand.Substring(1, operand.Length - 1); } if (operand == "this") { Output(OpCode.MOV, registers[(int)Register.VAR_ADDRESS], registers[(int)Register.FP]); //load current fp address Output(OpCode.ADI, registers[(int)Register.VAR_ADDRESS], (-1 * getOffset("this")).ToString()); //get frame's object.this address return(registers[(int)Register.VAR_ADDRESS]); //return register containing address of operand } /*if (operand[0] == 't' || operand[1] == 'a')//is an array index (every non-array ref symid is a single char followed by numbers) * { * Output(OpCode.MOV, registers[(int)Register.VAR_ADDRESS], registers[(int)Register.FP]);//get current frame pointer * Output(OpCode.ADI, registers[(int)Register.VAR_ADDRESS], (-1 * getOffset(operand)).ToString());//decrement by offset to get location of address of array * //Output(OpCode.LDR, registers[(int)Register.VAR_ADDRESS], registers[(int)Register.VAR_ADDRESS]);//load this heap address of array index from stack * return registers[(int)Register.VAR_ADDRESS];//return register containing address of operand * }*/ else if (operand[0] == 'M' || operand[0] == 'X' || operand[0] == 'Y') { MOV(registers[(int)Register.VAR_ADDRESS], registers[(int)Register.SP]); return(registers[(int)Register.VAR_ADDRESS]); //return register containing address of operand } else if ((operand[0] == 'P' && operand != "PC") || operand[0] == 'L' || operand[0] == 't') //parameter or local or temp variable so it must be in a func call (on stack) { Output(OpCode.MOV, registers[(int)Register.VAR_ADDRESS], registers[(int)Register.FP]); //get current frame pointer Output(OpCode.ADI, registers[(int)Register.VAR_ADDRESS], (-1 * getOffset(operand)).ToString()); //decrement by offset to get operand address if (operand[operand.Length - 1] == 'r' && !refDeclaration) //if a is a ref (temp holding address of actual object in memory and we want to get address of value { LDR(registers[(int)Register.VAR_ADDRESS], registers[(int)Register.VAR_ADDRESS]); //get value at address of temp ref } if (operand[1] == 'A') //if array { Output(OpCode.LDR, registers[(int)Register.VAR_ADDRESS], registers[(int)Register.VAR_ADDRESS]); //load address of array/ref into register } return(registers[(int)Register.VAR_ADDRESS]); //return register containing address of operand } else if (operand[0] == 'V') //instance variable at "this" object on heap { Output(OpCode.MOV, registers[(int)Register.VAR_ADDRESS], registers[(int)Register.FP]); //load current fp address Output(OpCode.ADI, registers[(int)Register.VAR_ADDRESS], (-1 * getOffset("this")).ToString()); //get frame's object.this address Output(OpCode.LDR, registers[(int)Register.VAR_ADDRESS], registers[(int)Register.VAR_ADDRESS]); //load value at object.this into register Output(OpCode.ADI, registers[(int)Register.VAR_ADDRESS], SymbolTable.GetValue(operand).offset.ToString()); //get a's address offset in object if (operand[1] == 'A') if (operand[1] == 'A') { Output(OpCode.LDR, registers[(int)Register.VAR_ADDRESS], registers[(int)Register.VAR_ADDRESS]); //load address of array into register } return(registers[(int)Register.VAR_ADDRESS]); //return register containing address of operand } return(operand); //if global just return symid (label) }
public static void iExist() { SAR top_sar = SAS.Pop(); if (top_sar.value == "this") { SAS.Push(top_sar); return; } string args = ""; if (top_sar.argList.Count != 0) { args = top_sar.argList[0]; for (int i = 1; i < top_sar.argList.Count; ++i) { args += "," + top_sar.argList[i]; } } top_sar.paramType = args; string symid = SymbolTable.iExists(top_sar); if (symid == null || !SymbolTable.ContainsSymid(symid)) { SemanticError(top_sar); } Symbol symbol = SymbolTable.GetValue(symid); if (symbol.data != null) { top_sar.dataType = symbol.data[0].Split(':')[1]; top_sar.dataType.Trim(); } top_sar.paramType = symbol.parameters; top_sar.symid = symbol.symid; if (symbol.kind == "method") { ICode.FRAME(symbol.symid, "this"); if (symbol.parameters != null && symbol.parameters != "") { for (int i = 0; i < top_sar.argList.Count; ++i) { ICode.PUSH(top_sar.argList[i]); } } ICode.CALL(symbol.symid); Symbol temp = new Symbol("t", "t" + uniqueCounter++, "t_" + symbol.value + "_ReturnValue", "tvar", symbol.data); SymbolTable.Add(temp); top_sar.symid = temp.symid; if (symbol.data[0].Split(':')[1] != "void" && symbol.data[0].Split(':')[1] != "null") { ICode.PEEK(temp.symid); } } SAS.Push(top_sar); }
private static int getOffset(string symid) { if (symid == "this") { return(THIS_OFFSET); } int offset = (12 + SymbolTable.GetValue(symid).offset); return(offset); }
private static void LDB(string a, string b) { if (!IsRegister(b) && SymbolTable.GetValue(b).data[0].Split(':')[1] != "char") { LDR(a, b); } else { Output(OpCode.LDB, a, b); } }
public static void WRITE(string a) { string type = SymbolTable.GetValue(a).data[0].Split(':')[1]; LDR(registers[(int)Register.OP2], GetLocation(a));//load value at label address of a if (type == "char") { Output(OpCode.TRP, "3"); } else { Output(OpCode.TRP, "1"); } }
public static void READ(string a) { string type = SymbolTable.GetValue(a).data[0].Split(':')[1]; if (type == "char") { Output(OpCode.TRP, "4"); } else { Output(OpCode.TRP, "2"); } MOV(registers[(int)Register.OP1], GetLocation(a)); STR(registers[(int)Register.OP2], registers[(int)Register.OP1]); }
public static void CONVERT(string a) { string type = SymbolTable.GetValue(a).data[0].Split(':')[1]; LDR(registers[(int)Register.OP2], GetLocation(a)); //load value at label address of a if (type == "char") //itoa { Output(OpCode.TRP, "11"); } else//atoi { Output(OpCode.TRP, "10"); } MOV(registers[(int)Register.OP1], GetLocation(a)); STR(registers[(int)Register.OP2], registers[(int)Register.OP1]); }
public static void NewObj() { SAR al = SAS.Pop(); SAR type = SAS.Pop(); if (!SymbolTable.NewObj(type, al.argList.ToArray())) { SemanticError(type); } string functionSymid = type.symid; type.sarType = SAR.SARtype.Ref; type.symid = "t" + uniqueCounter++; string[] data = { "returnType:" + type.dataType, "accessMod:private" }; Symbol instance = new Symbol("t", type.symid, "t" + type.value, "tvar", data); SymbolTable.Add(instance); string[] data2 = { "returnType:" + type.dataType, "accessMod:private" }; Symbol peekTemp = new Symbol("t", "t" + uniqueCounter++, "t" + type.value + "ReturnValue", "tvar", data2); SymbolTable.Add(peekTemp); Symbol staticInit = SymbolTable.GetValue(("Y" + functionSymid.Substring(1))); ICode.NEWI(type.size.ToString(), type.symid); //call constructor ICode.FRAME(functionSymid, type.symid); if (al.argList != null && al.argList.Count > 0 && al.argList[0] != "") { for (int i = 0; i < al.argList.Count; ++i) { ICode.PUSH(al.argList[i]); } } ICode.CALL(functionSymid); ICode.PEEK(peekTemp.symid); type.symid = peekTemp.symid; SAS.Push(type); }
public static Symbol rExists(SAR s) { Symbol temp = null; string args = ""; string scope = "g"; bool func = false; bool match = false; string[] parameters = { }; for (int i = 0; i < ScopeTable[scope].Count; ++i) { if (ScopeTable[scope][i].value.Equals(s.classType)) { scope += "." + s.classType; for (int j = 0; j < ScopeTable[scope].Count; ++j) { temp = ScopeTable[scope][j]; if (temp.kind == "Param") { continue; } if (temp.value == s.value) { match = true; s.symid = temp.symid; } else { continue; } if ((temp.kind == "method" || temp.kind == "constructor")) { func = true; match = false; if (temp.parameters == "") { if (s.argList.Count == 0) { s.symid = temp.symid; match = true; break; } continue; } args = ""; for (int q = 0; q < s.argList.Count; ++q) { if (q != 0) { args += ","; } args += symbolTable[s.argList[q]].data[0].Split(':')[1]; } parameters = temp.parameters.Split(','); if (s.argList.Count != parameters.Length)//method need to have matching number of parameters { continue; } Symbol definitionArg; Symbol passedArg; bool error = false; for (int p = 0; p < parameters.Length; ++p) { definitionArg = SymbolTable.GetValue(parameters[p]); passedArg = SymbolTable.GetValue(s.argList[p]); if (definitionArg.data[0] != passedArg.data[0]) { error = true; break; } } if (error) { continue; } s.symid = temp.symid; match = true; break; } else if (match == true) { break; } } if (!match) { if (func) { s.value += "(" + args + ")"; } s.scope = "class " + s.classType; return(null); } /*string symid = "t" + SemanticActions.uniqueCounter++; * Symbol ref_sar = new Symbol(s.scope, symid, s.value, "ref_sar", temp.data); * ref_sar.parameters = args; * symbolTable.Add(symid, ref_sar);*/ return(temp); } } s.scope = "class " + s.classType; if (func) { s.value += "("; for (int i = 0; i < s.argList.Count; ++i) { if (i != 0) { s.value += ","; } s.value += symbolTable[s.argList[i]].data[0].Split(':')[1]; } s.value += ")"; } s.value += " is"; return(null); }
public static void FUNC(string a) { ADI(registers[(int)Register.SP], (-1 * SymbolTable.GetValue(a).size).ToString());//get size of a and allocate space on stack (move sp up size amount) }