예제 #1
0
파일: ThirdPass.cs 프로젝트: goric/cflat
        /// <summary>
        /// Checks if the variable already exists. This does not allow for shadowing of variables, maybe as an
        /// enhancement, cause it wouldn't be that hard.
        ///
        /// Cflat also allows for declarations and assignments on the same line, so this will process the InitialValue sub tree
        /// as well.
        /// </summary>
        /// <param name="n"></param>
        public override void VisitDeclLocal(ASTDeclarationLocal n)
        {
            if (!_scopeMgr.HasSymbol(n.ID))
            {
                CFlatType lhs = CheckSubTree(n.Type);

                //Check if the code is also assigning a value on the same line
                bool valid = true;

                if (n.InitialValue != null)
                {
                    CFlatType rhs = CheckSubTree(n.InitialValue);
                    if (rhs is TypeFunction && ((TypeFunction)rhs).IsConstructor)
                    {
                        rhs = new TypeClass(((TypeFunction)rhs).Name);
                    }
                    if (!IsValidAssignment(lhs, rhs))
                    {
                        valid = false;
                        ReportError(n.Location, "Invalid assignment, type mismatch. Expected: {0} Got: {1}", TypeToFriendlyName(lhs), TypeToFriendlyName(rhs));
                    }
                }
                if (valid)
                {
                    _scopeMgr.AddLocal(n.ID, lhs, _currentMethod);
                }
            }
            else
            {
                ReportError(n.Location, "The identifier '{0}' already exists", n.ID);
            }
        }
예제 #2
0
        public override void VisitDeclLocal(ASTDeclarationLocal n)
        {
            //Get type
            n.Type.Visit(this);
            LocalBuilder builder = _gen.DeclareLocal(_lastWalkedType);
            //keep track of the LocalBuilder
            LocalBuilderInfo info = _currentMethodBuilder.AddLocal(n.ID, builder);

            //set value if needed
            if (n.InitialValue != null)
            {
                n.InitialValue.Visit(this);
                //store it to the local
                _gen.Emit(OpCodes.Stloc, info.Index);
            }
        }