1 ///////////////////////////////////////////////////////////////////////////
2 // Copyright (c) 2013 Academy of Motion Picture Arts and Sciences
3 // ("A.M.P.A.S."). Portions contributed by others as indicated.
4 // All rights reserved.
5 //
6 // A worldwide, royalty-free, non-exclusive right to copy, modify, create
7 // derivatives, and use, in source and binary forms, is hereby granted,
8 // subject to acceptance of this license. Performance of any of the
9 // aforementioned acts indicates acceptance to be bound by the following
10 // terms and conditions:
11 //
12 //  * Copies of source code, in whole or in part, must retain the
13 //    above copyright notice, this list of conditions and the
14 //    Disclaimer of Warranty.
15 //
16 //  * Use in binary form must retain the above copyright notice,
17 //    this list of conditions and the Disclaimer of Warranty in the
18 //    documentation and/or other materials provided with the distribution.
19 //
20 //  * Nothing in this license shall be deemed to grant any rights to
21 //    trademarks, copyrights, patents, trade secrets or any other
22 //    intellectual property of A.M.P.A.S. or any contributors, except
23 //    as expressly stated herein.
24 //
25 //  * Neither the name "A.M.P.A.S." nor the name of any other
26 //    contributors to this software may be used to endorse or promote
27 //    products derivative of or based on this software without express
28 //    prior written permission of A.M.P.A.S. or the contributors, as
29 //    appropriate.
30 //
31 // This license shall be construed pursuant to the laws of the State of
32 // California, and any disputes related thereto shall be subject to the
33 // jurisdiction of the courts therein.
34 //
35 // Disclaimer of Warranty: THIS SOFTWARE IS PROVIDED BY A.M.P.A.S. AND
36 // CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
37 // BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS
38 // FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT ARE DISCLAIMED. IN NO
39 // EVENT SHALL A.M.P.A.S., OR ANY CONTRIBUTORS OR DISTRIBUTORS, BE LIABLE
40 // FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, RESITUTIONARY,
41 // OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
42 // SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
43 // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
44 // CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
45 // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
46 // THE POSSIBILITY OF SUCH DAMAGE.
47 //
48 // WITHOUT LIMITING THE GENERALITY OF THE FOREGOING, THE ACADEMY
49 // SPECIFICALLY DISCLAIMS ANY REPRESENTATIONS OR WARRANTIES WHATSOEVER
50 // RELATED TO PATENT OR OTHER INTELLECTUAL PROPERTY RIGHTS IN THE ACADEMY
51 // COLOR ENCODING SYSTEM, OR APPLICATIONS THEREOF, HELD BY PARTIES OTHER
52 // THAN A.M.P.A.S., WHETHER DISCLOSED OR UNDISCLOSED.
53 ///////////////////////////////////////////////////////////////////////////
54 
55 
56 #ifndef INCLUDED_CTL_SYNTAX_TREE_H
57 #define INCLUDED_CTL_SYNTAX_TREE_H
58 
59 //-----------------------------------------------------------------------------
60 //
61 //	The syntax tree for the color transformation language.
62 //
63 //-----------------------------------------------------------------------------
64 
65 #include <CtlTokens.h>
66 #include <CtlRcPtr.h>
67 #include <half.h>
68 #include <vector>
69 #include <string>
70 
71 namespace Ctl {
72 
73 
74 struct SyntaxNode;
75 typedef RcPtr<SyntaxNode> SyntaxNodePtr;
76 
77 struct ModuleNode;
78 typedef RcPtr<ModuleNode> ModuleNodePtr;
79 
80 struct FunctionNode;
81 typedef RcPtr<FunctionNode> FunctionNodePtr;
82 
83 struct StatementNode;
84 typedef RcPtr<StatementNode> StatementNodePtr;
85 
86 struct VariableNode;
87 typedef RcPtr<VariableNode> VariableNodePtr;
88 
89 struct AssignmentNode;
90 typedef RcPtr<AssignmentNode> AssignmentNodePtr;
91 
92 struct ExprStatementNode;
93 typedef RcPtr<ExprStatementNode> ExprStatementNodePtr;
94 
95 struct IfNode;
96 typedef RcPtr<IfNode> IfNodePtr;
97 
98 struct ReturnNode;
99 typedef RcPtr<ReturnNode> ReturnNodePtr;
100 
101 struct WhileNode;
102 typedef RcPtr<WhileNode> WhileNodePtr;
103 
104 struct ExprNode;
105 typedef RcPtr<ExprNode> ExprNodePtr;
106 
107 struct BinaryOpNode;
108 typedef RcPtr<BinaryOpNode> BinaryOpNodePtr;
109 
110 struct UnaryOpNode;
111 typedef RcPtr<UnaryOpNode> UnaryOpNodePtr;
112 
113 struct ArrayIndexNode;
114 typedef RcPtr<ArrayIndexNode> ArrayIndexNodePtr;
115 
116 struct MemberNode;
117 typedef RcPtr<MemberNode> MemberNodePtr;
118 
119 struct SizeNode;
120 typedef RcPtr<SizeNode> SizeNodePtr;
121 
122 struct NameNode;
123 typedef RcPtr<NameNode> NameNodePtr;
124 
125 struct LiteralNode;
126 typedef RcPtr<LiteralNode> LiteralNodePtr;
127 
128 struct BoolLiteralNode;
129 typedef RcPtr<BoolLiteralNode> BoolLiteralNodePtr;
130 
131 struct IntLiteralNode;
132 typedef RcPtr<IntLiteralNode> IntLiteralNodePtr;
133 
134 struct UIntLiteralNode;
135 typedef RcPtr<UIntLiteralNode> UIntLiteralNodePtr;
136 
137 struct HalfLiteralNode;
138 typedef RcPtr<HalfLiteralNode> HalfLiteralNodePtr;
139 
140 struct FloatLiteralNode;
141 typedef RcPtr<FloatLiteralNode> FloatLiteralNodePtr;
142 
143 struct StringLiteralNode;
144 typedef RcPtr<StringLiteralNode> StringLiteralNodePtr;
145 
146 struct CallNode;
147 typedef RcPtr<CallNode> CallNodePtr;
148 
149 struct ValueNode;
150 typedef RcPtr<ValueNode> ValueNodePtr;
151 
152 class SymbolInfo;
153 typedef RcPtr<SymbolInfo> SymbolInfoPtr;
154 
155 class Type;
156 typedef RcPtr<Type> TypePtr;
157 
158 class DataType;
159 typedef RcPtr<DataType> DataTypePtr;
160 
161 typedef std::vector<size_t> SizeVector;
162 typedef std::vector<size_t>::iterator SizeVectorIterator;
163 
164 class LContext;
165 
166 
167 struct SyntaxNode: public RcObject
168 {
169     //-------------------------------------------------------------
170     // class SyntaxNode is the base class for all syntax tree nodes
171     //-------------------------------------------------------------
172 
173     SyntaxNode (int lineNumber);
174     virtual ~SyntaxNode ();
175 
176     void		printTree () const;
177     virtual void	print (int indent) const = 0;
178 
179 
180     //----------------------------
181     // Generate code for this node
182     //----------------------------
183 
184     virtual void	generateCode (LContext &lcontext) = 0;
185 
186 
187     int			lineNumber;
188 };
189 
190 
191 struct ModuleNode: public SyntaxNode
192 {
193     ModuleNode (int lineNumber,
194 	        const StatementNodePtr &constants,
195 		const FunctionNodePtr &functions);
196 
197     virtual void	print (int indent) const;
198 
199     StatementNodePtr	constants;
200     FunctionNodePtr	functions;
201 };
202 
203 
204 struct FunctionNode: public SyntaxNode
205 {
206     FunctionNode (int lineNumber,
207 	          const std::string &name,
208 		  const SymbolInfoPtr &info,
209 		  const StatementNodePtr &body);
210 
211     virtual void	print (int indent) const;
212 
213     std::string		name;
214     SymbolInfoPtr	info;
215     StatementNodePtr	body;
216     FunctionNodePtr	next;
217 };
218 
219 
220 struct StatementNode: public SyntaxNode
221 {
222     //---------------------------------------------------------
223     // class StatementNode is the base class for all nodes that
224     // represent CTL statements
225     //---------------------------------------------------------
226 
227     StatementNode (int lineNumber);
228 
229     //--------------------------------------------------------
230     // Check if all paths through the code that begin at this
231     // node end with a ReturnNode.  Used to check if execution
232     // of a non-void function can "fall off the end" of the
233     // function without returning a value.
234     //--------------------------------------------------------
235 
236     virtual bool	pathEndsWithReturn () const = 0;
237 
238 
239     StatementNodePtr	next;
240 };
241 
242 
243 struct LinearStatementNode: public StatementNode
244 {
245     //---------------------------------------------------------
246     // class LinearStatementNode is the base class for all
247     // CTL statements that represent a "linear" control flow,
248     // without branching, looping or returning from a function.
249     //---------------------------------------------------------
250 
251     LinearStatementNode (int lineNumber);
252 
253     virtual bool	pathEndsWithReturn () const;
254 };
255 
256 
257 struct VariableNode: public LinearStatementNode
258 {
259     VariableNode (int lineNumber,
260 	          const std::string &name,
261 		  const SymbolInfoPtr &info,
262 		  const ExprNodePtr &initialValue,
263 		  bool assignInitialValue);
264 
265     virtual void	print (int indent) const;
266 
267     std::string		name;
268     SymbolInfoPtr	info;
269     ExprNodePtr		initialValue;
270     bool		assignInitialValue;
271 };
272 
273 
274 struct AssignmentNode: public LinearStatementNode
275 {
276     AssignmentNode (int lineNumber,
277 		    const ExprNodePtr &lhs,
278 		    const ExprNodePtr &rhs);
279 
280     virtual void	print (int indent) const;
281 
282     ExprNodePtr		lhs;
283     ExprNodePtr		rhs;
284 };
285 
286 
287 struct ExprStatementNode: public LinearStatementNode
288 {
289     ExprStatementNode (int lineNumber, const ExprNodePtr &expr);
290 
291     virtual void	print (int indent) const;
292 
293     ExprNodePtr		expr;
294 };
295 
296 
297 struct IfNode: public StatementNode
298 {
299     IfNode (int lineNumber,
300 	    const ExprNodePtr &condition,
301 	    const StatementNodePtr &truePath,
302 	    const StatementNodePtr &falsePath);
303 
304     virtual void	print (int indent) const;
305     virtual bool	pathEndsWithReturn () const;
306 
307     ExprNodePtr		condition;
308     StatementNodePtr	truePath;
309     StatementNodePtr	falsePath;
310 };
311 
312 
313 struct ReturnNode: public StatementNode
314 {
315     ReturnNode (int lineNumber,
316 	        const SymbolInfoPtr &info,
317 		const ExprNodePtr &returnedValue);
318 
319     virtual void	print (int indent) const;
320     virtual bool	pathEndsWithReturn () const;
321 
322     SymbolInfoPtr	info;
323     ExprNodePtr		returnedValue;
324 };
325 
326 
327 struct WhileNode: public StatementNode
328 {
329     WhileNode (int lineNumber,
330 	       const ExprNodePtr &condition,
331 	       const StatementNodePtr &loopBody);
332 
333     virtual void	print (int indent) const;
334     virtual bool	pathEndsWithReturn () const;
335 
336     ExprNodePtr		condition;
337     StatementNodePtr	loopBody;
338 };
339 
340 
341 struct ExprNode: public SyntaxNode
342 {
343     //----------------------------------------------------
344     // class ExprNode is the base class for all node types
345     // that represent parts of a CTL expression.
346     //----------------------------------------------------
347 
348     ExprNode (int lineNumber);
349 
350 
351     //--------------------------------------------------------
352     // Compute the type of the value that will be generated
353     // by evaluating this expression.  If initInfo is non-null,
354     // then this expression is expected to initialize the
355     // object to which initInfo refers via a side effect,
356     // and writing to the object is allowed even if the
357     // object is marked read-only.
358     //--------------------------------------------------------
359 
360     virtual void	computeType (LContext &lcontext,
361 				     const SymbolInfoPtr &initInfo = 0) = 0;
362 
363     //------------------------------------------------------
364     // Simplifiy this expression by evaluating any constant
365     // subexpressions.  Return a pointer to the root node of
366     // the simplified expression.  (The returned pointer may
367     // point to this expression.)
368     //------------------------------------------------------
369 
370     virtual ExprNodePtr	evaluate (LContext &lcontext) = 0;
371 
372 
373     //-----------------------------------------------------
374     // Test if this expression is represents an lvalue.
375     // If initInfo is non-null then we are in the middle
376     // of initializing the object to which initInfo refers,
377     // and writing to the object is allowed, and the object
378     // may be an lvalue, even if it is marked read-only.
379     //-----------------------------------------------------
380 
381     virtual bool	isLvalue (const SymbolInfoPtr &initInfo = 0) const = 0;
382 
383 
384     TypePtr		type;
385 };
386 
387 
388 struct BinaryOpNode: public ExprNode
389 {
390     BinaryOpNode (int lineNumber,
391 	          Token op,
392 		  const ExprNodePtr &leftOperand,
393 		  const ExprNodePtr &rightOperand);
394 
395     virtual void	print (int indent) const;
396 
397     virtual void	computeType (LContext &lcontext,
398 				     const SymbolInfoPtr &initInfo = 0);
399 
400     virtual ExprNodePtr	evaluate (LContext &lcontext);
401 
402     virtual bool	isLvalue (const SymbolInfoPtr &initInfo = 0) const;
403 
404     Token		op;
405     ExprNodePtr		leftOperand;
406     ExprNodePtr		rightOperand;
407     TypePtr		operandType;
408 };
409 
410 
411 struct UnaryOpNode: public ExprNode
412 {
413     UnaryOpNode (int lineNumber,
414 	         Token op,
415 		 const ExprNodePtr &operand);
416 
417     virtual void	print (int indent) const;
418 
419     virtual void	computeType (LContext &lcontext,
420 				     const SymbolInfoPtr &initInfo = 0);
421 
422     virtual ExprNodePtr	evaluate (LContext &lcontext);
423 
424     virtual bool	isLvalue (const SymbolInfoPtr &initInfo = 0) const;
425 
426     Token		op;
427     ExprNodePtr		operand;
428 };
429 
430 
431 struct ArrayIndexNode: public ExprNode
432 {
433     ArrayIndexNode (int lineNumber,
434 		    const ExprNodePtr &array,
435 		    const ExprNodePtr &index);
436 
437     virtual void	print (int indent) const;
438 
439     virtual void	computeType (LContext &lcontext,
440 				     const SymbolInfoPtr &initInfo = 0);
441 
442     virtual ExprNodePtr	evaluate (LContext &lcontext);
443 
444     virtual bool	isLvalue (const SymbolInfoPtr &initInfo = 0) const;
445 
446     ExprNodePtr		array;
447     ExprNodePtr		index;
448 };
449 
450 struct MemberNode: public ExprNode
451 {
452     MemberNode (int lineNumber,
453 		const ExprNodePtr &obj,
454 		const std::string &member);
455 
456     virtual void	print (int indent) const;
457 
458     virtual void	computeType (LContext &lcontext,
459 				     const SymbolInfoPtr &initInfo = 0);
460 
461     virtual ExprNodePtr	evaluate (LContext &lcontext);
462 
463     virtual bool	isLvalue (const SymbolInfoPtr &initInfo = 0) const;
464 
465     ExprNodePtr		obj;
466     std::string          member;
467     size_t              offset;
468 };
469 
470 
471 struct SizeNode: public ExprNode
472 {
473     SizeNode (int lineNumber,
474 	      const ExprNodePtr &obj);
475 
476     virtual void	print (int indent) const;
477 
478     virtual void	computeType (LContext &lcontext,
479 				     const SymbolInfoPtr &initInfo = 0);
480 
481     virtual ExprNodePtr	evaluate (LContext &lcontext);
482 
483     virtual bool	isLvalue (const SymbolInfoPtr &initInfo = 0) const;
484 
485     ExprNodePtr		obj;
486 };
487 
488 struct NameNode: public ExprNode
489 {
490     NameNode (int lineNumber,
491 	      const std::string &name,
492 	      const SymbolInfoPtr &info);
493 
494     virtual void	print (int indent) const;
495 
496     virtual void	computeType (LContext &lcontext,
497 				     const SymbolInfoPtr &initInfo = 0);
498 
499     virtual ExprNodePtr	evaluate (LContext &lcontext);
500 
501     virtual bool	isLvalue (const SymbolInfoPtr &initInfo = 0) const;
502 
503     std::string		name;
504     SymbolInfoPtr	info;
505 };
506 
507 
508 struct LiteralNode: public ExprNode
509 {
510     //----------------------------------------
511     // base class for all nodes that represent
512     // literals in a CTL program
513     //----------------------------------------
514 
515     LiteralNode (int lineNumber);
516 
517     virtual void	computeType (LContext &lcontext,
518 				     const SymbolInfoPtr &initInfo = 0);
519 
520     virtual ExprNodePtr	evaluate (LContext &lcontext);
521 
522     virtual bool	isLvalue (const SymbolInfoPtr &initInfo = 0) const;
523 
524     virtual char*       valuePtr() = 0;
525     virtual void	printLiteral () const = 0;
526 
527 };
528 
529 
530 struct BoolLiteralNode: public LiteralNode
531 {
532     BoolLiteralNode (int lineNumber, const LContext &lcontext, bool value);
533 
534     virtual void	print (int indent) const;
535     virtual void	printLiteral () const;
536 
537     bool		value;
538 };
539 
540 
541 struct IntLiteralNode: public LiteralNode
542 {
543     IntLiteralNode (int lineNumber, const LContext &lcontext, int value);
544 
545     virtual void	print (int indent) const;
546     virtual void	printLiteral () const;
547 
548     int			value;
549 };
550 
551 
552 struct UIntLiteralNode: public LiteralNode
553 {
554     UIntLiteralNode (int lineNumber, const LContext &lcontext, unsigned value);
555 
556     virtual void	print (int indent) const;
557     virtual void	printLiteral () const;
558 
559     unsigned int	value;
560 };
561 
562 
563 struct HalfLiteralNode: public LiteralNode
564 {
565     HalfLiteralNode (int lineNumber, const LContext &lcontext, half value);
566 
567     virtual void	print (int indent) const;
568     virtual void	printLiteral () const;
569 
570     half		value;
571 };
572 
573 
574 struct FloatLiteralNode: public LiteralNode
575 {
576     FloatLiteralNode (int lineNumber, const LContext &lcontext, float value);
577 
578     virtual void	print (int indent) const;
579     virtual void	printLiteral () const;
580 
581     float		value;
582 };
583 
584 
585 struct StringLiteralNode: public LiteralNode
586 {
587     StringLiteralNode (int lineNumber,
588 		       const LContext &lcontext,
589 		       const std::string &value);
590 
591     virtual void	print (int indent) const;
592     virtual void	printLiteral () const;
593 
594     std::string		value;
595 };
596 
597 
598 typedef std::vector <ExprNodePtr> ExprNodeVector;
599 typedef std::vector <ExprNodePtr>::iterator ExprNodeVectorIterator;
600 
601 struct CallNode: public ExprNode
602 {
603     CallNode (int lineNumber,
604 	      const NameNodePtr &function,
605 	      const ExprNodeVector &arguments);
606 
607     virtual void	print (int indent) const;
608 
609     virtual void	computeType (LContext &lcontext,
610 				     const SymbolInfoPtr &initInfo = 0);
611 
612     virtual ExprNodePtr	evaluate (LContext &lcontext);
613 
614     virtual bool	isLvalue (const SymbolInfoPtr &initInfo = 0) const;
615 
616     NameNodePtr		function;
617     ExprNodeVector	arguments;
618 };
619 
620 
621 
622 struct ValueNode: public ExprNode
623 {
624     //------------------------------------------------------------
625     //  class ValueNode represents a set of expressions for the initial
626     //  values of the elements of a struct or array.  (In CTL an
627     //  ValueNode corresponds to an struct initializer, for example
628     //  {1, 3, x/4, 2}.)
629     //------------------------------------------------------------
630 
631     ValueNode (int lineNumber, const ExprNodeVector &elements);
632 
633     virtual void	print (int indent) const;
634 
635 
636     //----------------------------------------------------------
637     // Compute the types of the values that will be generated by
638     // evalutating the expressions for the struct elements.
639     //----------------------------------------------------------
640 
641     virtual void	computeType (LContext &lcontext,
642 				     const SymbolInfoPtr &initInfo = 0);
643 
644     //---------------------------------------------------
645     // Simplify the expressions for the struct elements by
646     // evaluating any constant subexpressions.
647     //---------------------------------------------------
648 
649     virtual ExprNodePtr	evaluate (LContext &lcontext);
650 
651 
652     //------------------------------------------------------------
653     // Verify that the values of the expressions for the struct
654     // elements can be converted to the type struct's element type.
655     //------------------------------------------------------------
656 
657     bool		checkElementTypes (const DataTypePtr &dataType,
658 					   LContext &lcontext) const;
659 
660     bool		checkElementTypesRec (const DataTypePtr &dataType,
661 					      LContext &lcontext,
662 					      int &eIndex) const;
663 
664     //-----------------------------------------------------------------
665     // Check if the expressions for the struct elements are all literals
666     //-----------------------------------------------------------------
667 
668     bool		elementsAreLiterals () const;
669 
670 
671     virtual bool	isLvalue (const SymbolInfoPtr &initInfo = 0) const;
672 
673 
674     ExprNodeVector	elements;
675 };
676 
677 
678 } // namespace Ctl
679 
680 #endif
681