コード例 #1
0
 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)
 }
コード例 #2
0
        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);
        }
コード例 #3
0
 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
 }
コード例 #4
0
        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)
        }
コード例 #5
0
        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);
        }
コード例 #6
0
        private static int getOffset(string symid)
        {
            if (symid == "this")
            {
                return(THIS_OFFSET);
            }
            int offset = (12 + SymbolTable.GetValue(symid).offset);

            return(offset);
        }
コード例 #7
0
 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);
     }
 }
コード例 #8
0
        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");
            }
        }
コード例 #9
0
        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]);
        }
コード例 #10
0
        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]);
        }
コード例 #11
0
        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);
        }
コード例 #12
0
ファイル: SymbolTable.cs プロジェクト: Metallicruz/CompVM
        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);
        }
コード例 #13
0
 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)
 }