parse_tree.h revision effb81e5f8246d0db0270817048dc992db66e9fb
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.
4
5#ifndef TOOLS_GN_PARSE_TREE_H_
6#define TOOLS_GN_PARSE_TREE_H_
7
8#include <vector>
9
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"
16
17class AccessorNode;
18class BinaryOpNode;
19class BlockNode;
20class ConditionNode;
21class FunctionCallNode;
22class IdentifierNode;
23class ListNode;
24class LiteralNode;
25class Scope;
26class UnaryOpNode;
27
28// ParseNode -------------------------------------------------------------------
29
30// A node in the AST.
31class ParseNode {
32 public:
33  ParseNode();
34  virtual ~ParseNode();
35
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;
45
46  virtual Value Execute(Scope* scope, Err* err) const = 0;
47
48  virtual LocationRange GetRange() const = 0;
49
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;
55
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;
59
60 private:
61  DISALLOW_COPY_AND_ASSIGN(ParseNode);
62};
63
64// AccessorNode ----------------------------------------------------------------
65
66// Access an array or scope element.
67//
68// Currently, such values are only read-only. In that you can do:
69//   a = obj1.a
70//   b = obj2[0]
71// But not
72//   obj1.a = 5
73//   obj2[0] = 6
74//
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.
82//
83// Additionally, the left-hand-side of the accessor must currently be an
84// identifier. So you can't do things like:
85//   function_call()[1]
86//   a = b.c.d
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.
89class AccessorNode : public ParseNode {
90 public:
91  AccessorNode();
92  virtual ~AccessorNode();
93
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;
101
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; }
106
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(); }
110
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(); }
115
116 private:
117  Value ExecuteArrayAccess(Scope* scope, Err* err) const;
118  Value ExecuteScopeAccess(Scope* scope, Err* err) const;
119
120  Token base_;
121
122  // Either index or member will be set according to what type of access this
123  // is.
124  scoped_ptr<ParseNode> index_;
125  scoped_ptr<IdentifierNode> member_;
126
127  DISALLOW_COPY_AND_ASSIGN(AccessorNode);
128};
129
130// BinaryOpNode ----------------------------------------------------------------
131
132class BinaryOpNode : public ParseNode {
133 public:
134  BinaryOpNode();
135  virtual ~BinaryOpNode();
136
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;
144
145  const Token& op() const { return op_; }
146  void set_op(const Token& t) { op_ = t; }
147
148  const ParseNode* left() const { return left_.get(); }
149  void set_left(scoped_ptr<ParseNode> left) {
150    left_ = left.Pass();
151  }
152
153  const ParseNode* right() const { return right_.get(); }
154  void set_right(scoped_ptr<ParseNode> right) {
155    right_ = right.Pass();
156  }
157
158 private:
159  scoped_ptr<ParseNode> left_;
160  Token op_;
161  scoped_ptr<ParseNode> right_;
162
163  DISALLOW_COPY_AND_ASSIGN(BinaryOpNode);
164};
165
166// BlockNode -------------------------------------------------------------------
167
168class BlockNode : public ParseNode {
169 public:
170  // Set has_scope if this block introduces a nested scope.
171  explicit BlockNode(bool has_scope);
172  virtual ~BlockNode();
173
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;
181
182  void set_begin_token(const Token& t) { begin_token_ = t; }
183  void set_end_token(const Token& t) { end_token_ = t; }
184
185  const std::vector<ParseNode*>& statements() const { return statements_; }
186  void append_statement(scoped_ptr<ParseNode> s) {
187    statements_.push_back(s.release());
188  }
189
190  // Doesn't create a nested scope.
191  Value ExecuteBlockInScope(Scope* our_scope, Err* err) const;
192
193 private:
194  bool has_scope_;
195
196  // Tokens corresponding to { and }, if any (may be NULL).
197  Token begin_token_;
198  Token end_token_;
199
200  // Owning pointers, use unique_ptr when we can use C++11.
201  std::vector<ParseNode*> statements_;
202
203  DISALLOW_COPY_AND_ASSIGN(BlockNode);
204};
205
206// ConditionNode ---------------------------------------------------------------
207
208class ConditionNode : public ParseNode {
209 public:
210  ConditionNode();
211  virtual ~ConditionNode();
212
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;
220
221  void set_if_token(const Token& token) { if_token_ = token; }
222
223  const ParseNode* condition() const { return condition_.get(); }
224  void set_condition(scoped_ptr<ParseNode> c) {
225    condition_ = c.Pass();
226  }
227
228  const BlockNode* if_true() const { return if_true_.get(); }
229  void set_if_true(scoped_ptr<BlockNode> t) {
230    if_true_ = t.Pass();
231  }
232
233  // This is either empty, a block (for the else clause), or another
234  // condition.
235  const ParseNode* if_false() const { return if_false_.get(); }
236  void set_if_false(scoped_ptr<ParseNode> f) {
237    if_false_ = f.Pass();
238  }
239
240 private:
241  // Token corresponding to the "if" string.
242  Token if_token_;
243
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.
247
248  DISALLOW_COPY_AND_ASSIGN(ConditionNode);
249};
250
251// FunctionCallNode ------------------------------------------------------------
252
253class FunctionCallNode : public ParseNode {
254 public:
255  FunctionCallNode();
256  virtual ~FunctionCallNode();
257
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;
265
266  const Token& function() const { return function_; }
267  void set_function(Token t) { function_ = t; }
268
269  const ListNode* args() const { return args_.get(); }
270  void set_args(scoped_ptr<ListNode> a) { args_ = a.Pass(); }
271
272  const BlockNode* block() const { return block_.get(); }
273  void set_block(scoped_ptr<BlockNode> b) { block_ = b.Pass(); }
274
275 private:
276  Token function_;
277  scoped_ptr<ListNode> args_;
278  scoped_ptr<BlockNode> block_;  // May be null.
279
280  DISALLOW_COPY_AND_ASSIGN(FunctionCallNode);
281};
282
283// IdentifierNode --------------------------------------------------------------
284
285class IdentifierNode : public ParseNode {
286 public:
287  IdentifierNode();
288  IdentifierNode(const Token& token);
289  virtual ~IdentifierNode();
290
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;
298
299  const Token& value() const { return value_; }
300  void set_value(const Token& t) { value_ = t; }
301
302 private:
303  Token value_;
304
305  DISALLOW_COPY_AND_ASSIGN(IdentifierNode);
306};
307
308// ListNode --------------------------------------------------------------------
309
310class ListNode : public ParseNode {
311 public:
312  ListNode();
313  virtual ~ListNode();
314
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;
322
323  void set_begin_token(const Token& t) { begin_token_ = t; }
324  void set_end_token(const Token& t) { end_token_ = t; }
325
326  void append_item(scoped_ptr<ParseNode> s) {
327    contents_.push_back(s.release());
328  }
329  const std::vector<const ParseNode*>& contents() const { return contents_; }
330
331 private:
332  // Tokens corresponding to the [ and ].
333  Token begin_token_;
334  Token end_token_;
335
336  // Owning pointers, use unique_ptr when we can use C++11.
337  std::vector<const ParseNode*> contents_;
338
339  DISALLOW_COPY_AND_ASSIGN(ListNode);
340};
341
342// LiteralNode -----------------------------------------------------------------
343
344class LiteralNode : public ParseNode {
345 public:
346  LiteralNode();
347  LiteralNode(const Token& token);
348  virtual ~LiteralNode();
349
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;
357
358  const Token& value() const { return value_; }
359  void set_value(const Token& t) { value_ = t; }
360
361 private:
362  Token value_;
363
364  DISALLOW_COPY_AND_ASSIGN(LiteralNode);
365};
366
367// UnaryOpNode -----------------------------------------------------------------
368
369class UnaryOpNode : public ParseNode {
370 public:
371  UnaryOpNode();
372  virtual ~UnaryOpNode();
373
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;
381
382  const Token& op() const { return op_; }
383  void set_op(const Token& t) { op_ = t; }
384
385  const ParseNode* operand() const { return operand_.get(); }
386  void set_operand(scoped_ptr<ParseNode> operand) {
387    operand_ = operand.Pass();
388  }
389
390 private:
391  Token op_;
392  scoped_ptr<ParseNode> operand_;
393
394  DISALLOW_COPY_AND_ASSIGN(UnaryOpNode);
395};
396
397#endif  // TOOLS_GN_PARSE_TREE_H_
398