Beispiel #1
0
        public Stmt VisitBlockStatement(Stmt.BlockStatement statement)
        {
            foreach (var item in statement.Statements)
            {
                Visit(item);
            }

            return(null);
        }
        public bool VisitBlockStatement(Stmt.BlockStatement statement)
        {
            bool result = true;

            foreach (var stmt in statement.Statements)
            {
                var success = Examine(stmt);

                if (!success)
                {
                    result = false;
                }
            }

            return(result);
        }
Beispiel #3
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);
        }