Exemple #1
0
        public override AST.Node ToAST(Env env)
        {
            /// A return statement with an expression shall not appear in a function whose return type is void.
            /// A return statement without an expression shall only appear in a function whose return type is void.
            TFunc  f           = env.GetFuncType();
            string returnLabel = env.GetReturnLabel();

            if (expr != null)
            {
                if (f.ret.IsVoid)
                {
                    throw new Error(Pos, "a return statement with an expression shall not appear a function whose return type is void");
                }
                AST.Expr e = expr.ToASTExpr(env).ValueTransform();
                if (!Assign.SimpleAssignable(f.ret, e))
                {
                    throw new ETypeError(Pos, string.Format("cannot assign {0} to {1}", e.Type, f.ret));
                }
                return(new AST.Return(returnLabel, e.ImplicitConvert(f.ret)));
            }
            else
            {
                if (!f.ret.IsVoid)
                {
                    throw new Error(Pos, "a return statement without an expression shall only appear in a function whose return type is void");
                }
                return(new AST.Return(returnLabel, null));
            }
        }
Exemple #2
0
        public override AST.Node ToAST(Env env)
        {
            /// An iteration statement is a block.
            env.PushBlockScope();

            /// The controlling expression should have scalar type.
            AST.Expr e = expr.ToASTExpr(env);
            if (!e.Type.IsScalar)
            {
                throw new ETypeError(Pos, "the controlling expression of iteration statement should have scalar type");
            }

            /// The loop body is also a block.
            env.PushBlockScope();

            /// Add this loop to the environemnt.
            env.PushLoop(this);

            var b = body.ToASTCompoundStmt(env);

            env.PopBreakable();

            env.PopScope();
            env.PopScope();

            return(new AST.While(breakLabel, continueLabel, secondPlusLabel, firstLabel, e, b));
        }
Exemple #3
0
        /// <summary>
        /// A selection statement is a block whose scope is a strict subset
        /// of the scope of its enclosing block.
        ///
        /// The controlling expression of an if statement shall have scalar type.
        /// </summary>
        /// <param name="env"></param>
        /// <returns></returns>
        public override AST.Node ToAST(Env env)
        {
            env.PushBlockScope();
            AST.Expr e = expr.ToASTExpr(env);
            if (!e.Type.IsScalar)
            {
                throw new ETypeError(Pos, string.Format("expecting scalar type, given {0}", e.Type));
            }

            AST.Node t = then.ToAST(env);
            AST.Node o = other != null?other.ToAST(env) : null;

            env.PopScope();

            var labels = env.AllocIfLabel();

            return(new AST.If(e, t, o, labels.Item1, labels.Item2));
        }
Exemple #4
0
        public override AST.Node ToAST(Env env)
        {
            env.PushBlockScope();
            env.PushBlockScope();
            env.PushLoop(this);

            var b = body.ToASTCompoundStmt(env);

            env.PopBreakable();
            env.PopScope();

            AST.Expr e = expr.ToASTExpr(env);
            if (!e.Type.IsScalar)
            {
                throw new ETypeError(Pos, "the controlling expression of iteration statement should be have scalar type");
            }

            env.PopScope();
            return(new AST.Do(breakLabel, continueLabel, secondPlusLabel, firstLabel, e, b));
        }