Esempio n. 1
0
        public void GenerateBitcode(List <Stmt> statements)
        {
            foreach (var funcdecl in statements)
            {
                Stmt.FunctionDeclaration func = (Stmt.FunctionDeclaration)funcdecl;

                FunctionPrototype(func);
            }

            foreach (var funcdecl in statements)
            {
                Visit(funcdecl);
            }

            LLVM.VerifyModule(_module, LLVMVerifierFailureAction.LLVMPrintMessageAction, out string error);
            if (error != null)
            {
                Console.WriteLine(error);
            }

            //LLVM.LinkInMCJIT();
            LLVM.WriteBitcodeToFile(_module, "test.bc");

            LLVM.DumpModule(_module);
            LLVM.DisposeBuilder(_builder);
        }
Esempio n. 2
0
        public void ExecuteTypeCheck()
        {
            foreach (var functionDeclaration in Declarations)
            {
                Stmt.FunctionDeclaration func = (Stmt.FunctionDeclaration)functionDeclaration;

                if (FunctionTable.ContainsKey(func.Identifier.Source))
                {
                    Console.WriteLine($"There already exists a '{func.Identifier.Source}' function declaration");
                }
                else
                {
                    FunctionTable.Add(func.Identifier.Source, new FunctionSymbol {
                        ReturnType = func.ReturnType, Parameters = func.Parameters
                    });
                }
            }

            foreach (var statement in Declarations)
            {
                var success = Examine(statement);

                if (!success)
                {
                    Failed = true;
                }
            }
        }
Esempio n. 3
0
        public bool VisitFunctionDeclaration(Stmt.FunctionDeclaration statement)
        {
            LocalTypes.Clear();
            foreach (var parameter in statement.Parameters)
            {
                LocalTypes.Add(parameter.Identifier, parameter.Type);
            }

            CurrentFunction = FunctionTable[statement.Identifier.Source];

            return(Examine(statement.FunctionBody));
        }
Esempio n. 4
0
        public void FunctionPrototype(Stmt.FunctionDeclaration func)
        {
            uint argc = (uint)func.Parameters.Count;
            var  argv = new LLVMTypeRef[argc];

            var function = LLVM.GetNamedFunction(_module, func.Identifier.Source);

            if (function.Pointer != IntPtr.Zero)
            {
                if (LLVM.CountBasicBlocks(function) != 0)
                {
                    throw new Exception("redefinition of function.");
                }

                if (LLVM.CountParams(function) != argc)
                {
                    throw new Exception("redefinition of function with different # args");
                }
            }
            else
            {
                for (int i = 0; i < argc; i++)
                {
                    argv[i] = GetParameterType(func.Parameters[i].Type);
                }

                function = LLVM.AddFunction(_module, func.Identifier.Source, LLVM.FunctionType(GetParameterType(func.ReturnType), argv, false));
                LLVM.SetLinkage(function, LLVMLinkage.LLVMExternalLinkage);
            }

            for (int i = 0; i < argc; i++)
            {
                string argName = func.Parameters[i].Identifier;

                LLVMValueRef param = LLVM.GetParam(function, (uint)i);
                LLVM.SetValueName(param, argName);

                //_namedValues[argName] = new LLVMSymbol { Binding = null, IsFunction = false, KtsType = stmt.Parameters[i].Type, Value = param };
            }

            _functions.Add(func.Identifier.Source, new FunctionSymbol {
                ReturnType = func.ReturnType, Parameters = func.Parameters
            });
        }
Esempio n. 5
0
        public Stmt VisitFunctionDeclaration(Stmt.FunctionDeclaration stmt)
        {
            currentFunction = new FunctionSymbol {
                Parameters = stmt.Parameters, ReturnType = stmt.ReturnType
            };

            uint argc = (uint)stmt.Parameters.Count;
            //var argv = new LLVMTypeRef[argc];
            var function = LLVM.GetNamedFunction(_module, stmt.Identifier.Source);

            if (function.Pointer != IntPtr.Zero)
            {
                if (LLVM.CountBasicBlocks(function) != 0)
                {
                    throw new Exception("redefinition of function.");
                }

                if (LLVM.CountParams(function) != argc)
                {
                    throw new Exception("redefinition of function with different # args");
                }
            }

            #region FunctionBody

            _namedValues.Clear();
            LLVM.PositionBuilderAtEnd(_builder, LLVM.AppendBasicBlock(function, "entry"));
            var args = LLVM.GetParams(function);
            for (int i = 0; i < args.Length; i++)
            {
                var name = stmt.Parameters[i].Identifier;
                var type = stmt.Parameters[i].Type;

                var alloca = EntryAllocation(function, type, name);
                LLVM.BuildStore(_builder, args[i], alloca);
                bool decayed = false;

                if (type.Dimensions != 0)
                {
                    decayed = true;
                }

                _namedValues.Add(name, new LLVMSymbol {
                    Binding = null, IsDecayed = decayed, KtsType = type, Value = alloca
                });
            }

            try
            {
                Visit(stmt.FunctionBody);

                if (stmt.ReturnType.Type == TypeEnum.VOID)
                {
                    Stmt.BlockStatement block = (Stmt.BlockStatement)stmt.FunctionBody;

                    var length = block.Statements.Count;
                    if (block.Statements[length - 1] is not Stmt.Return)
                    {
                        LLVM.BuildRetVoid(_builder);
                    }
                }
            }
            catch
            {
                LLVM.DeleteFunction(function);
                throw;
            }

            LLVM.VerifyFunction(function, LLVMVerifierFailureAction.LLVMPrintMessageAction);
            _valueStack.Push(function);

            #endregion

            return(stmt);
        }