Example #1
0
 public void Visit(SubFuncCallNode n)
 {
     PrintDOTIDLabel(n);
     PrintDOTParentChild(n);
     foreach (var child in n.GetChildren())
     {
         child.Accept(this);
     }
 }
Example #2
0
        public void Visit(SubFuncCallNode n)
        {
            var children = n.GetChildren();

            foreach (var child in children)
            {
                child.SymTable = n.SymTable;
                child.Accept(this);
            }
        }
        public void Visit(SubFuncCallNode n)
        {
            var children = n.GetChildren();

            foreach (var child in children)
            {
                child.Accept(this);
            }

            var returnValSize = Utils.GetTypeFullSize(_globalSymbolTable, n.ExprType);
            var table         = (FunctionSymbolTableEntry)n.CallerTable;

            n.TemporaryVariableName = table.MemoryLayout.AddTemporaryVariable(returnValSize);
        }
Example #4
0
        public void Visit(SubFuncCallNode n)
        {
            var children = n.GetChildren();

            foreach (var child in children)
            {
                child.Accept(this);
            }

            var callerTable       = (FunctionSymbolTableEntry)n.CallerTable;
            var funcTable         = (FunctionSymbolTableEntry)n.SecondarySymTable;
            var funcReturnValSize = Utils.GetTypeFullSize(_globalSymbolTable, (funcTable.ReturnType.Lexeme, new List <int>()));
            var tag = Utils.GetTag(funcTable);

            var frameSize = funcTable.MemoryLayout.TotalSize;
            var oldFSPReg = PopRegister();

            var localReturnValVar    = n.TemporaryVariableName;
            var localReturnValOffset = callerTable.MemoryLayout.GetOffset(localReturnValVar);

            var r0  = Registers.R0;
            var r12 = Registers.R12;
            var r13 = Registers.R13;
            var r15 = Registers.R15;

            _writer.WriteComment("SUB FUNC CALL");

            // Set the new FSP reg and set self addr
            _writer.WriteComment("- create frame");
            _writer.WriteInstruction(Instructions.Add, oldFSPReg, r0, FSPReg);
            _writer.WriteInstruction(Instructions.Addi, FSPReg, FSPReg, $"{frameSize}");

            //TODO(AFL) setSelfAddr
            var selfAddrOffset = -8;

            _writer.WriteInstruction(Instructions.Sw, $"{selfAddrOffset}({FSPReg})", r12);

            // Copy arguments
            _writer.WriteComment("- copy args");

            var givenParamTempVarNames = ((FuncCallParamsNode)children.Last()).ParamTempVarNames; // Params given
            var funcParamNames         = funcTable.Params.Select(x => x.Name).ToList();           // variables used in the function

            for (int i = 0; i < funcParamNames.Count; ++i)
            {
                var givenParamAddrReg = PopRegister();
                var funcParamAddrReg  = PopRegister();
                var paramSizeReg      = PopRegister();

                var givenParamSize   = callerTable.MemoryLayout.GetTypeSize(givenParamTempVarNames[i]);
                var givenParamOffset = callerTable.MemoryLayout.GetOffset(givenParamTempVarNames[i]);
                var funcParamOffset  = funcTable.MemoryLayout.GetOffset(funcParamNames[i]);

                _writer.WriteInstruction(Instructions.Addi, paramSizeReg, paramSizeReg, $"{givenParamSize}");
                _writer.WriteInstruction(Instructions.Add, givenParamAddrReg, givenParamAddrReg, oldFSPReg);
                _writer.WriteInstruction(Instructions.Addi, givenParamAddrReg, givenParamAddrReg, $"{givenParamOffset}");
                _writer.WriteInstruction(Instructions.Add, funcParamAddrReg, funcParamAddrReg, FSPReg);
                _writer.WriteInstruction(Instructions.Addi, funcParamAddrReg, funcParamAddrReg, $"{funcParamOffset}");

                WriteMultiByteCopy(givenParamAddrReg, funcParamAddrReg, paramSizeReg);

                PushRegister(paramSizeReg);
                PushRegister(funcParamAddrReg);
                PushRegister(givenParamAddrReg);
            }


            // JUMP!
            _writer.WriteComment("- jump to func");
            _writer.WriteInstruction(Instructions.Jl, r15, tag);

            // Ok we're back, unset FSP
            _writer.WriteComment("- unset FSP");
            _writer.WriteInstruction(Instructions.Subi, FSPReg, FSPReg, $"{frameSize}");

            // set r12 to absolute address of result
            _writer.WriteComment("- set r12 (callchain ptr)");
            _writer.WriteInstruction(Instructions.Sub, r12, r12, r12);
            _writer.WriteInstruction(Instructions.Add, r12, r0, FSPReg);
            _writer.WriteInstruction(Instructions.Addi, r12, r12, $"{localReturnValOffset}");

            // Copy result from other frame to this frame
            var valSizeReg = PopRegister();

            _writer.WriteComment("- copy result");
            _writer.WriteInstruction(Instructions.Addi, valSizeReg, r0, $"{funcReturnValSize}");
            WriteMultiByteCopy(r13, r12, valSizeReg);

            PushRegister(valSizeReg);
            PushRegister(oldFSPReg);
        }
Example #5
0
        public void Visit(SubFuncCallNode n)
        {
            var children = n.GetChildren();

            var token = ((IdentifierNode)children[0]).Token;

            n.FuncName = token.Lexeme;

            List <FunctionSymbolTableEntry> candidateFuncsInScope;

            switch (n.SymTable)
            {
            case FunctionSymbolTableEntry f:
            {
                candidateFuncsInScope = new List <FunctionSymbolTableEntry>();
                if (!string.IsNullOrEmpty(f.ScopeSpec))
                {
                    ClassSymbolTable s = _globalTable.GetClassSymbolTableByName(f.ScopeSpec);
                    var funcsInClass   = s.GetFunctions().Where(x => string.Equals(x.Name, n.FuncName)).ToList();
                    candidateFuncsInScope = candidateFuncsInScope.Concat(funcsInClass).ToList();
                }

                var candidateFuncsInGlobalScope = _globalTable.FunctionSymbolTable.Entries
                                                  .Cast <FunctionSymbolTableEntry>()
                                                  .Where(x => string.Equals(x.Name, n.FuncName) && string.IsNullOrEmpty(x.ScopeSpec)).ToList();

                // Same name, in class or free function
                //candidateFuncsInScope = s.GetFunctions().Where(x => string.Equals(x.Name, n.FuncName)).ToList();
                candidateFuncsInScope = candidateFuncsInScope.Concat(candidateFuncsInGlobalScope).ToList();
            }
            break;

            case ClassSymbolTable s:
            {
                // Same name, in class
                candidateFuncsInScope = s.GetFunctions().Where(x => string.Equals(x.Name, n.FuncName)).ToList();
            }
            break;

            default:
                throw new InvalidOperationException("Unknown table entry type found");
            }

            if (candidateFuncsInScope.Count == 0)
            {
                _errorStream.WriteLine($"Use of undefined function: \"{n.FuncName}\" ({token.StartLine}:{token.StartColumn})");
                Console.WriteLine($"Error: Use of undefined function: \"{n.FuncName}\" ({token.StartLine}:{token.StartColumn})");
            }

            // Visit FuncCallParamsNode to get parameter types used
            var funcParams = (FuncCallParamsNode)children[1];

            funcParams.CallerTable = n.CallerTable;
            funcParams.Accept(this);
            var funcParamTypes = funcParams.ParamsTypes;

            FunctionSymbolTableEntry matchingFunc = null;

            foreach (var candidateFunc in candidateFuncsInScope)
            {
                if (candidateFunc.Params.Count != funcParamTypes.Count)
                {
                    continue;
                }

                bool matches = true;
                for (int i = 0; i < candidateFunc.Params.Count; ++i)
                {
                    (string type, List <int> dims)unpacked = funcParamTypes[i];

                    if (!string.Equals(candidateFunc.Params[i].Type.type, unpacked.type))
                    {
                        matches = false;
                        break;
                    }

                    if (candidateFunc.Params[i].Type.dims.Count == unpacked.dims.Count && candidateFunc.Params[i].Type.dims.All(x => x == 0))
                    {
                        matches = true;
                        break;
                    }

                    if (!candidateFunc.Params[i].Type.dims.SequenceEqual(unpacked.dims))
                    {
                        matches = false;
                        break;
                    }
                }

                if (matches)
                {
                    matchingFunc = candidateFunc;
                    break;
                }
            }

            if (matchingFunc == null)
            {
                _errorStream.WriteLine($"Use of function: \"{n.FuncName}\" ({token.StartLine}:{token.StartColumn}) with invalid parameters (no matching overload was found)");
                Console.WriteLine($"Error: Use of function: \"{n.FuncName}\" ({token.StartLine}:{token.StartColumn}) with invalid parameters (no matching overload was found)");
            }
            else
            {
                n.CallerTable       = n.SecondarySymTable;
                n.SecondarySymTable = matchingFunc;
                n.ScopeSpec         = matchingFunc.ReturnType.Lexeme;
                n.ExprType          = (matchingFunc.ReturnType.Lexeme, new List <int>());
            }
        }