1 // Copyright (c) 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #ifndef TOOLS_GN_PARSE_TREE_H_
6 #define TOOLS_GN_PARSE_TREE_H_
10 #include "base/basictypes.h"
11 #include "base/compiler_specific.h"
12 #include "base/memory/scoped_ptr.h"
13 #include "tools/gn/err.h"
14 #include "tools/gn/token.h"
15 #include "tools/gn/value.h"
21 class FunctionCallNode
;
28 // ParseNode -------------------------------------------------------------------
36 virtual const AccessorNode
* AsAccessor() const;
37 virtual const BinaryOpNode
* AsBinaryOp() const;
38 virtual const BlockNode
* AsBlock() const;
39 virtual const ConditionNode
* AsConditionNode() const;
40 virtual const FunctionCallNode
* AsFunctionCall() const;
41 virtual const IdentifierNode
* AsIdentifier() const;
42 virtual const ListNode
* AsList() const;
43 virtual const LiteralNode
* AsLiteral() const;
44 virtual const UnaryOpNode
* AsUnaryOp() const;
46 virtual Value
Execute(Scope
* scope
, Err
* err
) const = 0;
48 virtual LocationRange
GetRange() const = 0;
50 // Returns an error with the given messages and the range set to something
51 // that indicates this node.
52 virtual Err
MakeErrorDescribing(
53 const std::string
& msg
,
54 const std::string
& help
= std::string()) const = 0;
56 // Prints a representation of this node to the given string, indenting
57 // by the given number of spaces.
58 virtual void Print(std::ostream
& out
, int indent
) const = 0;
61 DISALLOW_COPY_AND_ASSIGN(ParseNode
);
64 // AccessorNode ----------------------------------------------------------------
66 // Access an array or scope element.
68 // Currently, such values are only read-only. In that you can do:
75 // In the current design where the dot operator is used only for templates, we
76 // explicitly don't want to allow you to do "invoker.foo = 5", so if we added
77 // support for accessors to be lvalues, we would also need to add some concept
78 // of a constant scope. Supporting this would also add a lot of complications
79 // to the operator= implementation, since some accessors might return values
80 // in the const root scope that shouldn't be modified. Without a strong
81 // use-case for this, it seems simpler to just disallow it.
83 // Additionally, the left-hand-side of the accessor must currently be an
84 // identifier. So you can't do things like:
87 // These are easier to implement if we needed them but given the very limited
88 // use cases for this, it hasn't seemed worth the bother.
89 class AccessorNode
: public ParseNode
{
92 virtual ~AccessorNode();
94 virtual const AccessorNode
* AsAccessor() const OVERRIDE
;
95 virtual Value
Execute(Scope
* scope
, Err
* err
) const OVERRIDE
;
96 virtual LocationRange
GetRange() const OVERRIDE
;
97 virtual Err
MakeErrorDescribing(
98 const std::string
& msg
,
99 const std::string
& help
= std::string()) const OVERRIDE
;
100 virtual void Print(std::ostream
& out
, int indent
) const OVERRIDE
;
102 // Base is the thing on the left of the [] or dot, currently always required
103 // to be an identifier token.
104 const Token
& base() const { return base_
; }
105 void set_base(const Token
& b
) { base_
= b
; }
107 // Index is the expression inside the []. Will be null if member is set.
108 const ParseNode
* index() const { return index_
.get(); }
109 void set_index(scoped_ptr
<ParseNode
> i
) { index_
= i
.Pass(); }
111 // The member is the identifier on the right hand side of the dot. Will be
112 // null if the index is set.
113 const IdentifierNode
* member() const { return member_
.get(); }
114 void set_member(scoped_ptr
<IdentifierNode
> i
) { member_
= i
.Pass(); }
117 Value
ExecuteArrayAccess(Scope
* scope
, Err
* err
) const;
118 Value
ExecuteScopeAccess(Scope
* scope
, Err
* err
) const;
122 // Either index or member will be set according to what type of access this
124 scoped_ptr
<ParseNode
> index_
;
125 scoped_ptr
<IdentifierNode
> member_
;
127 DISALLOW_COPY_AND_ASSIGN(AccessorNode
);
130 // BinaryOpNode ----------------------------------------------------------------
132 class BinaryOpNode
: public ParseNode
{
135 virtual ~BinaryOpNode();
137 virtual const BinaryOpNode
* AsBinaryOp() const OVERRIDE
;
138 virtual Value
Execute(Scope
* scope
, Err
* err
) const OVERRIDE
;
139 virtual LocationRange
GetRange() const OVERRIDE
;
140 virtual Err
MakeErrorDescribing(
141 const std::string
& msg
,
142 const std::string
& help
= std::string()) const OVERRIDE
;
143 virtual void Print(std::ostream
& out
, int indent
) const OVERRIDE
;
145 const Token
& op() const { return op_
; }
146 void set_op(const Token
& t
) { op_
= t
; }
148 const ParseNode
* left() const { return left_
.get(); }
149 void set_left(scoped_ptr
<ParseNode
> left
) {
153 const ParseNode
* right() const { return right_
.get(); }
154 void set_right(scoped_ptr
<ParseNode
> right
) {
155 right_
= right
.Pass();
159 scoped_ptr
<ParseNode
> left_
;
161 scoped_ptr
<ParseNode
> right_
;
163 DISALLOW_COPY_AND_ASSIGN(BinaryOpNode
);
166 // BlockNode -------------------------------------------------------------------
168 class BlockNode
: public ParseNode
{
170 // Set has_scope if this block introduces a nested scope.
171 explicit BlockNode(bool has_scope
);
172 virtual ~BlockNode();
174 virtual const BlockNode
* AsBlock() const OVERRIDE
;
175 virtual Value
Execute(Scope
* scope
, Err
* err
) const OVERRIDE
;
176 virtual LocationRange
GetRange() const OVERRIDE
;
177 virtual Err
MakeErrorDescribing(
178 const std::string
& msg
,
179 const std::string
& help
= std::string()) const OVERRIDE
;
180 virtual void Print(std::ostream
& out
, int indent
) const OVERRIDE
;
182 void set_begin_token(const Token
& t
) { begin_token_
= t
; }
183 void set_end_token(const Token
& t
) { end_token_
= t
; }
185 const std::vector
<ParseNode
*>& statements() const { return statements_
; }
186 void append_statement(scoped_ptr
<ParseNode
> s
) {
187 statements_
.push_back(s
.release());
190 // Doesn't create a nested scope.
191 Value
ExecuteBlockInScope(Scope
* our_scope
, Err
* err
) const;
196 // Tokens corresponding to { and }, if any (may be NULL).
200 // Owning pointers, use unique_ptr when we can use C++11.
201 std::vector
<ParseNode
*> statements_
;
203 DISALLOW_COPY_AND_ASSIGN(BlockNode
);
206 // ConditionNode ---------------------------------------------------------------
208 class ConditionNode
: public ParseNode
{
211 virtual ~ConditionNode();
213 virtual const ConditionNode
* AsConditionNode() const OVERRIDE
;
214 virtual Value
Execute(Scope
* scope
, Err
* err
) const OVERRIDE
;
215 virtual LocationRange
GetRange() const OVERRIDE
;
216 virtual Err
MakeErrorDescribing(
217 const std::string
& msg
,
218 const std::string
& help
= std::string()) const OVERRIDE
;
219 virtual void Print(std::ostream
& out
, int indent
) const OVERRIDE
;
221 void set_if_token(const Token
& token
) { if_token_
= token
; }
223 const ParseNode
* condition() const { return condition_
.get(); }
224 void set_condition(scoped_ptr
<ParseNode
> c
) {
225 condition_
= c
.Pass();
228 const BlockNode
* if_true() const { return if_true_
.get(); }
229 void set_if_true(scoped_ptr
<BlockNode
> t
) {
233 // This is either empty, a block (for the else clause), or another
235 const ParseNode
* if_false() const { return if_false_
.get(); }
236 void set_if_false(scoped_ptr
<ParseNode
> f
) {
237 if_false_
= f
.Pass();
241 // Token corresponding to the "if" string.
244 scoped_ptr
<ParseNode
> condition_
; // Always non-null.
245 scoped_ptr
<BlockNode
> if_true_
; // Always non-null.
246 scoped_ptr
<ParseNode
> if_false_
; // May be null.
248 DISALLOW_COPY_AND_ASSIGN(ConditionNode
);
251 // FunctionCallNode ------------------------------------------------------------
253 class FunctionCallNode
: public ParseNode
{
256 virtual ~FunctionCallNode();
258 virtual const FunctionCallNode
* AsFunctionCall() const OVERRIDE
;
259 virtual Value
Execute(Scope
* scope
, Err
* err
) const OVERRIDE
;
260 virtual LocationRange
GetRange() const OVERRIDE
;
261 virtual Err
MakeErrorDescribing(
262 const std::string
& msg
,
263 const std::string
& help
= std::string()) const OVERRIDE
;
264 virtual void Print(std::ostream
& out
, int indent
) const OVERRIDE
;
266 const Token
& function() const { return function_
; }
267 void set_function(Token t
) { function_
= t
; }
269 const ListNode
* args() const { return args_
.get(); }
270 void set_args(scoped_ptr
<ListNode
> a
) { args_
= a
.Pass(); }
272 const BlockNode
* block() const { return block_
.get(); }
273 void set_block(scoped_ptr
<BlockNode
> b
) { block_
= b
.Pass(); }
277 scoped_ptr
<ListNode
> args_
;
278 scoped_ptr
<BlockNode
> block_
; // May be null.
280 DISALLOW_COPY_AND_ASSIGN(FunctionCallNode
);
283 // IdentifierNode --------------------------------------------------------------
285 class IdentifierNode
: public ParseNode
{
288 IdentifierNode(const Token
& token
);
289 virtual ~IdentifierNode();
291 virtual const IdentifierNode
* AsIdentifier() const OVERRIDE
;
292 virtual Value
Execute(Scope
* scope
, Err
* err
) const OVERRIDE
;
293 virtual LocationRange
GetRange() const OVERRIDE
;
294 virtual Err
MakeErrorDescribing(
295 const std::string
& msg
,
296 const std::string
& help
= std::string()) const OVERRIDE
;
297 virtual void Print(std::ostream
& out
, int indent
) const OVERRIDE
;
299 const Token
& value() const { return value_
; }
300 void set_value(const Token
& t
) { value_
= t
; }
305 DISALLOW_COPY_AND_ASSIGN(IdentifierNode
);
308 // ListNode --------------------------------------------------------------------
310 class ListNode
: public ParseNode
{
315 virtual const ListNode
* AsList() const OVERRIDE
;
316 virtual Value
Execute(Scope
* scope
, Err
* err
) const OVERRIDE
;
317 virtual LocationRange
GetRange() const OVERRIDE
;
318 virtual Err
MakeErrorDescribing(
319 const std::string
& msg
,
320 const std::string
& help
= std::string()) const OVERRIDE
;
321 virtual void Print(std::ostream
& out
, int indent
) const OVERRIDE
;
323 void set_begin_token(const Token
& t
) { begin_token_
= t
; }
324 void set_end_token(const Token
& t
) { end_token_
= t
; }
326 void append_item(scoped_ptr
<ParseNode
> s
) {
327 contents_
.push_back(s
.release());
329 const std::vector
<const ParseNode
*>& contents() const { return contents_
; }
332 // Tokens corresponding to the [ and ].
336 // Owning pointers, use unique_ptr when we can use C++11.
337 std::vector
<const ParseNode
*> contents_
;
339 DISALLOW_COPY_AND_ASSIGN(ListNode
);
342 // LiteralNode -----------------------------------------------------------------
344 class LiteralNode
: public ParseNode
{
347 LiteralNode(const Token
& token
);
348 virtual ~LiteralNode();
350 virtual const LiteralNode
* AsLiteral() const OVERRIDE
;
351 virtual Value
Execute(Scope
* scope
, Err
* err
) const OVERRIDE
;
352 virtual LocationRange
GetRange() const OVERRIDE
;
353 virtual Err
MakeErrorDescribing(
354 const std::string
& msg
,
355 const std::string
& help
= std::string()) const OVERRIDE
;
356 virtual void Print(std::ostream
& out
, int indent
) const OVERRIDE
;
358 const Token
& value() const { return value_
; }
359 void set_value(const Token
& t
) { value_
= t
; }
364 DISALLOW_COPY_AND_ASSIGN(LiteralNode
);
367 // UnaryOpNode -----------------------------------------------------------------
369 class UnaryOpNode
: public ParseNode
{
372 virtual ~UnaryOpNode();
374 virtual const UnaryOpNode
* AsUnaryOp() const OVERRIDE
;
375 virtual Value
Execute(Scope
* scope
, Err
* err
) const OVERRIDE
;
376 virtual LocationRange
GetRange() const OVERRIDE
;
377 virtual Err
MakeErrorDescribing(
378 const std::string
& msg
,
379 const std::string
& help
= std::string()) const OVERRIDE
;
380 virtual void Print(std::ostream
& out
, int indent
) const OVERRIDE
;
382 const Token
& op() const { return op_
; }
383 void set_op(const Token
& t
) { op_
= t
; }
385 const ParseNode
* operand() const { return operand_
.get(); }
386 void set_operand(scoped_ptr
<ParseNode
> operand
) {
387 operand_
= operand
.Pass();
392 scoped_ptr
<ParseNode
> operand_
;
394 DISALLOW_COPY_AND_ASSIGN(UnaryOpNode
);
397 #endif // TOOLS_GN_PARSE_TREE_H_