Beispiel #1
0
        public override void Visit(FunctionProtoAST functionProto)
        {
            var functionIden = _symTableManager.LookupFunctionInfo(_currentFileName, functionProto.Name, _currentScopeId, functionProto.GetFunctionType().ArgumentTypes);

            if (functionIden.valueRef.Pointer == IntPtr.Zero)
            {
                var fnType = IRTypesConverter.GetFunctionType(functionProto.GetFunctionType());

                functionIden.valueRef = LLVM.AddFunction(_module, functionProto.Name, fnType);
            }

            _currentFunction = functionIden.valueRef;
        }
Beispiel #2
0
        public TypeAST GetReturnType(FunctionCallAST functionCallAst)
        {
            List <TypeAST> argsType = null;

            if (functionCallAst.ExpressionList.Count != 0)
            {
                if (functionCallAst.argTypes == null)
                {
                    argsType = new List <TypeAST>();

                    foreach (var expression in functionCallAst.ExpressionList)
                    {
                        expression.Accept(this);

                        argsType.Add(_stateInfo.currentType);
                    }

                    functionCallAst.argTypes = argsType;
                }
                else
                {
                    argsType = functionCallAst.argTypes;
                }
            }

            FunctionTypeAST functionType;

            var arrayFunctionCall = functionCallAst.Name as ArrayAccessAST;

            if (arrayFunctionCall != null)
            {
                var arrayType = GetArrayType(arrayFunctionCall);

                var accessDimensions = arrayFunctionCall.AccessExprList.Count;

                functionType = GetArrayContainedType(arrayType, accessDimensions) as FunctionTypeAST;

                string invalidArgsMessage = string.Format("Invalid function arguments expected '{0}' got '{1}'",
                                                          string.Join(",", functionType.ArgumentTypes), argsType == null ? "no argument" : string.Join(",", argsType));

                if (argsType != null &&
                    ((!functionType.IsVarArgsFn && functionType.ArgumentTypes.Count != argsType.Count) ||
                     (functionType.IsVarArgsFn && functionType.ArgumentTypes.Count > argsType.Count)))
                {
                    throw new Exception(invalidArgsMessage);
                }

                if (argsType == null && functionType.ArgumentTypes.Count != 0)
                {
                    throw new Exception(invalidArgsMessage);
                }

                for (var i = 0; i < functionType.ArgumentTypes.Count; i++)
                {
                    if (functionType.ArgumentTypes[i].ToString() != argsType[i].ToString() && !functionType.ArgumentTypes[i].GetType().IsAssignableFrom(argsType[i].GetType()))
                    {
                        throw new Exception(invalidArgsMessage);
                    }
                }
            }
            else
            {
                var functionCallInfo = _symTableManager.
                                       LookupFunctionInfo(_stateInfo.currentFile, functionCallAst.Name.ToString(),
                                                          _stateInfo.scopeId, argsType);

                if (functionCallInfo == null)
                {
                    throw new Exception(string.Format("Undefined function {0}({1})",
                                                      functionCallAst.Name,
                                                      argsType != null ? string.Join(",", argsType) : ""));
                }

                functionType = functionCallInfo.typeAST as FunctionTypeAST;
            }

            return(functionType.ReturnType);
        }