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)); } }
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)); }
/// <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)); }
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)); }