Improve performance for loop and insertion
[scilab.git] / scilab / modules / ast / includes / exps / functiondec.hxx
1 /*
2  *  Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
3  *  Copyright (C) 2008-2008 - DIGITEO - Bruno JOFRET
4  *
5  *  This file must be used under the terms of the CeCILL.
6  *  This source file is licensed as described in the file COPYING, which
7  *  you should have received as part of this distribution.  The terms
8  *  are also available at
9  *  http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt
10  *
11  */
12
13 /**
14 ** \file functiondec.hxx
15 ** Define the Function Declaration class.
16 */
17
18 #ifndef AST_FUNCTIONDEC_HXX
19 #define AST_FUNCTIONDEC_HXX
20
21 #include <list>
22
23 #include "context.hxx"
24 #include "dec.hxx"
25 #include "arraylistvar.hxx"
26 #include "seqexp.hxx"
27
28 using namespace std;
29
30 namespace ast
31 {
32 /*
33 ** \brief Abstract a Function Declaration node.
34 **
35 ** \b Example: function foo(s : string) : int = (print(s); 2097)
36 */
37 class FunctionDec : public Dec
38 {
39     // \name Ctor & dtor.
40 public:
41     /*
42     ** \brief Construct a Function Declaration node.
43     ** \param location scanner position informations
44     ** \param name of function
45     ** \param list of params
46     ** \param list of returns
47     ** \param body
48     */
49     FunctionDec (const Location& location,
50                  symbol::Symbol name,
51                  Exp& args,
52                  Exp& returns,
53                  SeqExp& body)
54         : Dec (location),
55           _name (name),
56           _stack(NULL)
57     {
58         args.setParent(this);
59         returns.setParent(this);
60         body.setParent(this);
61         _exps.push_back(&args);
62         _exps.push_back(&returns);
63         _exps.push_back(body.getAs<Exp>());
64
65         body.setReturnable();
66     }
67
68     virtual ~FunctionDec ()
69     {
70         //body will be deleted by types::Macro
71         //so replace by NULL to avoir delete in ~Exp()
72         //_exps[2] = NULL;
73     }
74
75     virtual FunctionDec* clone()
76     {
77         FunctionDec* cloned = new FunctionDec(getLocation(), getSymbol(), *getArgs().clone(), *getReturns().clone(), *getBody().clone()->getAs<SeqExp>());
78         cloned->setVerbose(isVerbose());
79         return cloned;
80     }
81
82     virtual bool equal(const Exp & e) const
83     {
84         return Exp::equal(e) && _name == static_cast<const FunctionDec &>(e)._name;
85     }
86
87     // \name Visitors entry point.
88 public:
89     // \brief Accept a const visitor
90     virtual void accept (Visitor& v)
91     {
92         v.visit (*this);
93     }
94     // \brief Accept a non-const visitor
95     virtual void accept (ConstVisitor& v) const
96     {
97         v.visit (*this);
98     }
99
100
101     // \name Accessors.
102 public:
103     const symbol::Symbol & getSymbol(void) const
104     {
105         return _name;
106     }
107
108     const Exp& getBody(void) const
109     {
110         return *_exps[2];
111     }
112
113     Exp& getBody (void)
114     {
115         return *_exps[2];
116     }
117
118     inline const ArrayListVar & getArgs() const
119     {
120         return *static_cast<const ArrayListVar *>(_exps[0]);
121     }
122
123     inline ArrayListVar & getArgs()
124     {
125         return *static_cast<ArrayListVar *>(_exps[0]);
126     }
127
128     const ArrayListVar & getReturns() const
129     {
130         return *static_cast<const ArrayListVar *>(_exps[1]);
131     }
132
133     ArrayListVar & getReturns()
134     {
135         return *static_cast<ArrayListVar *>(_exps[1]);
136     }
137
138     void setBody(Exp *body)
139     {
140         _exps[2] = body;
141     }
142
143     symbol::Variable* getStack()
144     {
145         if (_stack == NULL)
146         {
147             _stack = symbol::Context::getInstance()->getOrCreate(_name);
148         }
149
150         return _stack;
151     }
152
153     virtual ExpType getType() const
154     {
155         return FUNCTIONDEC;
156     }
157     inline bool isFunctionDec() const
158     {
159         return true;
160     }
161 protected:
162     symbol::Symbol _name;
163     symbol::Variable* _stack;
164 };
165
166 } // namespace ast
167
168 #endif // !AST_FUNCTIONDEC_HXX