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_TYPE_H
57 #define INCLUDED_CTL_TYPE_H
58 
59 //-----------------------------------------------------------------------------
60 //
61 //	Types in the color transformation language
62 //
63 //	CTL types are represented by the following class hierarchy:
64 //
65 //	    Type		base class for all types
66 //		DataType	base class for types that represent data
67 //		    VoidType    void
68 //		    BoolType	bool
69 //		    IntType	int
70 //		    UIntType	unsigned int
71 //		    HalfType	half
72 //		    FloatType	float
73 //		    StringType	character string
74 //		    ArrayType	arrays
75 //		    StructType	structs
76 //		FunctionType	function signatures
77 //
78 //-----------------------------------------------------------------------------
79 
80 #include <CtlReadWriteAccess.h>
81 #include <CtlAddr.h>
82 #include <string>
83 #include <vector>
84 #include <stdarg.h>
85 
86 namespace Ctl {
87 
88 struct SyntaxNode;
89 typedef RcPtr <SyntaxNode> SyntaxNodePtr;
90 
91 struct StatementNode;
92 typedef RcPtr <StatementNode> StatementNodePtr;
93 
94 struct ExprNode;
95 typedef RcPtr <ExprNode> ExprNodePtr;
96 
97 class Type;
98 typedef RcPtr <Type> TypePtr;
99 
100 class DataType;
101 typedef RcPtr <DataType> DataTypePtr;
102 
103 class VoidType;
104 typedef RcPtr <VoidType> VoidTypePtr;
105 
106 class BoolType;
107 typedef RcPtr <BoolType> BoolTypePtr;
108 
109 class IntType;
110 typedef RcPtr <IntType> IntTypePtr;
111 
112 class UIntType;
113 typedef RcPtr <UIntType> UIntTypePtr;
114 
115 class HalfType;
116 typedef RcPtr <HalfType> HalfTypePtr;
117 
118 class FloatType;
119 typedef RcPtr <FloatType> FloatTypePtr;
120 
121 class StringType;
122 typedef RcPtr <StringType> StringTypePtr;
123 
124 class ArrayType;
125 typedef RcPtr <ArrayType> ArrayTypePtr;
126 
127 class StructType;
128 typedef RcPtr <StructType> StructTypePtr;
129 
130 class FunctionType;
131 typedef RcPtr <FunctionType> FunctionTypePtr;
132 
133 enum CDataType_e {
134 	VoidTypeEnum=0,
135 	BoolTypeEnum=1,
136 	IntTypeEnum=2,
137 	UIntTypeEnum=3,
138 	HalfTypeEnum=4,
139 	FloatTypeEnum=5,
140 	StringTypeEnum=6,
141 	StructTypeEnum=7,
142 	ArrayTypeEnum=8
143 };
144 
145 typedef std::vector<size_t> SizeVector;
146 typedef std::vector<size_t>::iterator SizeVectorIterator;
147 typedef std::vector<size_t>::reverse_iterator SizeVectorRIterator;
148 
149 class LContext;
150 class XContext;
151 class Module;
152 
153 class Type: public RcObject
154 {
155   public:
156 
157     virtual ~Type ();
158 
159 
160     //----------------------------------------
161     // Test if type t is the same as this type
162     //----------------------------------------
163 
164     virtual bool		isSameTypeAs (const TypePtr &t) const = 0;
165 
166 
167     //-------------------------------------------------
168     // Test if type t can be "promoted" to this type.
169     // For example, int can be promoted to float, but
170     // float cannot be promoted to int.
171     // (Called by ExprNode::computeType())
172     //-------------------------------------------------
173 
174     virtual bool		canPromoteFrom (const TypePtr &t) const = 0;
175 
176 
177     //-----------------------------------------------------
178     // Test if a cast from type t to this type is possible.
179     // For example, int can be cast to float, and float can
180     // be cast to int.
181     // (Called by ExprNode::computeType())
182     //-----------------------------------------------------
183 
184     virtual bool		canCastFrom (const TypePtr &t) const = 0;
185 
186 
187 
188     //-----------------------------------------------------
189     // Test if an assignment is allowed between the two types.
190     // Same as canCastFrom except returns fals for varrying
191     // array types, string, function and void;
192     //-----------------------------------------------------
193 
194     virtual bool		canAssign (const TypePtr &t) const = 0;
195 
196 
197     //---------------------------------------------------
198     // Attempt to evaluate a simple constant expression,
199     // for example, of the form "operator operand" or
200     // "operand operator operand", and produce a result
201     // of this type.  Depending on whether evaluation
202     // is successful or not, return either the result or
203     // the original expression.
204     // (Called by ExprNode::evaluate())
205     //---------------------------------------------------
206 
207     virtual ExprNodePtr		evaluate (LContext &lcontext,
208 					  const ExprNodePtr &expr) const = 0;
209 
210 
211     //---------------------------------------------------
212     // Attempt to cast the value of a constant expression
213     // to this type.  Depending on whether the cast is
214     // successful or not, return either the result or the
215     // original expression.
216     // (Called by ExprNode::evaluate())
217     //---------------------------------------------------
218 
219     virtual ExprNodePtr		castValue (LContext &lcontext,
220 					   const ExprNodePtr &expr) const = 0;
221 
222 
223     //--------------------------------
224     // Print this type (for debugging)
225     //--------------------------------
226 
227     virtual void		print (int indent) const = 0;
228 
229 
230     //--------------------------------------------------------
231     // Convert this type to a string for use in error messages
232     //--------------------------------------------------------
233 
234     virtual std::string		asString () const = 0;
235 
236 
237     //-------------------------------------------------------------
238     // Output code that casts from the result of the given ExprNode
239     // to this type
240     //-------------------------------------------------------------
241 
242     virtual void		generateCastFrom (const ExprNodePtr &expr,
243 						  LContext &lcontext) const = 0;
244 
245     //-------------------------------------
246     // Output code for the given SyntaxNode
247     //-------------------------------------
248 
249     virtual void		generateCode (const SyntaxNodePtr &node,
250 					      LContext &lcontext) const = 0;
251 
252 	// This is something of a cheat and mostly for internal use
253 	// to avoid doing RTTI for determining type conversions.
cDataType()254 	virtual CDataType_e cDataType() const { return VoidTypeEnum; };
255 
256 	// These methods are for dealing with complex and aggregate
257 	// type introspection. They have the concept of a 'path' where
258 	// that consists of a '/' separated list of element identifiers.
259 	// In the case of an array an element identifier is interpreted
260 	// as a number. In the case of a struct an element identifier is
261 	// interpreted as a structure item name. The following element
262 	// identifiers have special meaning (but do not conflict with CTL
263 	// syntax:
264 	//
265 	//   *  A null identifier or "." is a no-op to the parser.
266 	//   *  If an identifier is "%s" then the next item on the var-args
267 	//      list is interpreted as a char * string and used as the element
268 	//      identifier.
269 	//   *  If an identifier is "%u", "%d" then the next item on the vargs
270 	//      list is interpreted as an integer and used as the element
271 	//      identifier.
272 	//   *  If an identifier is "%v" then the next item on the vargs list
273 	//      is interpreted as a SizeVector * and all elements are used to
274 	//      identify an element in a matrix.
275 	//
276 	static void         childElement(size_t *offset, TypePtr *type,
277 	                                 const std::string &path, ...);
278 
279 	static void         childElementV(size_t *offset, TypePtr *type,
280 	                                  const std::string &path, va_list ap);
281 };
282 
283 
284 class DataType: public Type
285 {
286   public:
287     //------------------------------------------------------------
288     // Size and required alignment of objects of this data type:
289     //
290     // Objects of this type occupy ojectSize() bytes, and the
291     // first byte must be at an address that is divisible by
292     // objectAlignment().  In an array of objects of this type,
293     // the addresses of the array elements are alignedObjectSize()
294     // bytes apart.
295     //
296     // alignObjectAddr(x) computes the smallest address, y,
297     // such that y >= x and y is divisible by objectAlignment().
298     //------------------------------------------------------------
299 
300     virtual size_t  objectSize() const=0;
301     virtual size_t  alignedObjectSize() const=0;
302     virtual size_t  objectAlignment() const=0;
303     char *          alignObjectAddr(char *addr) const;
304 
305     //-------------------------------------------------------
306     // For basic data types, appends alignedOjectSize.  For arrays
307     // and structs recurses through sub-elements to return number of
308     // non-struct, non-array elements.
309     //-------------------------------------------------------
310     virtual void    coreSizes(size_t parentOffset,
311 					          SizeVector &sizes,
312 	                          SizeVector &offsets) const;
313 
314 
315     //-------------------------------------------------------
316     // Generate a new static variable of this type and return
317     // the variable's address
318     //-------------------------------------------------------
319 
320     virtual AddrPtr             newStaticVariable (Module *module) const = 0;
321     virtual void                newAutomaticVariable
322                                      (StatementNodePtr node,
323 				      LContext &lcontext) const = 0;
324 };
325 
326 
327 class VoidType: public DataType
328 {
329   public:
330 
331     VoidType ();
332 
333     virtual bool		isSameTypeAs (const TypePtr &t) const;
334     virtual bool		canAssign (const TypePtr &t) const;
335     virtual bool		canPromoteFrom (const TypePtr &t) const;
336     virtual bool		canCastFrom (const TypePtr &t) const;
337 
cDataType()338 	virtual CDataType_e cDataType() const { return VoidTypeEnum; };
339 
340     virtual ExprNodePtr		evaluate (LContext &lcontext,
341 					  const ExprNodePtr &expr) const;
342 
343     virtual ExprNodePtr		castValue (LContext &lcontext,
344 				           const ExprNodePtr &expr) const;
345 
346     virtual void		print (int indent) const;
347     virtual std::string		asString () const;
348 
349     // arrays of void not allowed
350     AddrPtr                     newStaticVariable (Module *module) const;
351     void                        newAutomaticVariable
352                                      (StatementNodePtr node,
353 				      LContext &lcontext) const;
354 };
355 
356 class BoolType: public DataType
357 {
358   public:
359 
360     BoolType ();
361 
362     virtual bool		isSameTypeAs (const TypePtr &t) const;
363     virtual bool		canAssign (const TypePtr &t) const;
364     virtual bool		canPromoteFrom (const TypePtr &t) const;
365     virtual bool		canCastFrom (const TypePtr &t) const;
366 
cDataType()367 	virtual CDataType_e cDataType() const { return IntTypeEnum; };
368 
369     virtual ExprNodePtr		evaluate (LContext &lcontext,
370 					  const ExprNodePtr &expr) const;
371 
372     virtual ExprNodePtr		castValue (LContext &lcontext,
373 				           const ExprNodePtr &expr) const;
374 
375     virtual void		print (int indent) const;
376     virtual std::string		asString () const;
377 };
378 
379 
380 class IntType: public DataType
381 {
382   public:
383 
384     IntType ();
385 
386     virtual bool		isSameTypeAs (const TypePtr &t) const;
387     virtual bool		canAssign (const TypePtr &t) const;
388     virtual bool		canPromoteFrom (const TypePtr &t) const;
389     virtual bool		canCastFrom (const TypePtr &t) const;
390 
cDataType()391 	virtual CDataType_e cDataType() const { return IntTypeEnum; };
392 
393     virtual ExprNodePtr		evaluate (LContext &lcontext,
394 					  const ExprNodePtr &expr) const;
395 
396     virtual ExprNodePtr		castValue (LContext &lcontext,
397 				           const ExprNodePtr &expr) const;
398 
399     virtual void		print (int indent) const;
400     virtual std::string		asString () const;
401 };
402 
403 
404 class UIntType: public DataType
405 {
406   public:
407 
408     UIntType ();
409 
410     virtual bool		isSameTypeAs (const TypePtr &t) const;
411     virtual bool		canAssign (const TypePtr &t) const;
412     virtual bool		canPromoteFrom (const TypePtr &t) const;
413     virtual bool		canCastFrom (const TypePtr &t) const;
414 
cDataType()415 	virtual CDataType_e cDataType() const { return UIntTypeEnum; };
416 
417     virtual ExprNodePtr		evaluate (LContext &lcontext,
418 					  const ExprNodePtr &expr) const;
419 
420     virtual ExprNodePtr		castValue (LContext &lcontext,
421 				           const ExprNodePtr &expr) const;
422 
423     virtual void		print (int indent) const;
424     virtual std::string		asString () const;
425 };
426 
427 
428 class HalfType: public DataType
429 {
430   public:
431 
432     HalfType ();
433 
434     virtual bool		isSameTypeAs (const TypePtr &t) const;
435     virtual bool		canAssign (const TypePtr &t) const;
436     virtual bool		canPromoteFrom (const TypePtr &t) const;
437     virtual bool		canCastFrom (const TypePtr &t) const;
438 
cDataType()439 	virtual CDataType_e cDataType() const { return HalfTypeEnum; };
440 
441     virtual ExprNodePtr		evaluate (LContext &lcontext,
442 					  const ExprNodePtr &expr) const;
443 
444     virtual ExprNodePtr		castValue (LContext &lcontext,
445 				           const ExprNodePtr &expr) const;
446 
447     virtual void		print (int indent) const;
448     virtual std::string		asString () const;
449 };
450 
451 
452 class FloatType: public DataType
453 {
454   public:
455 
456     FloatType ();
457 
458     virtual bool		isSameTypeAs (const TypePtr &t) const;
459     virtual bool		canAssign (const TypePtr &t) const;
460     virtual bool		canPromoteFrom (const TypePtr &t) const;
461     virtual bool		canCastFrom (const TypePtr &t) const;
462 
cDataType()463 	virtual CDataType_e cDataType() const { return FloatTypeEnum; };
464 
465     virtual ExprNodePtr		evaluate (LContext &lcontext,
466  					  const ExprNodePtr &expr) const;
467 
468     virtual ExprNodePtr		castValue (LContext &lcontext,
469 				           const ExprNodePtr &expr) const;
470 
471     virtual void		print (int indent) const;
472     virtual std::string		asString () const;
473 };
474 
475 
476 class StringType: public DataType
477 {
478   public:
479 
480     StringType ();
481 
482     virtual bool		isSameTypeAs (const TypePtr &t) const;
483     virtual bool		canAssign (const TypePtr &t) const;
484     virtual bool		canPromoteFrom (const TypePtr &t) const;
485     virtual bool		canCastFrom (const TypePtr &t) const;
486 
cDataType()487 	virtual CDataType_e cDataType() const { return StringTypeEnum; };
488 
489     virtual ExprNodePtr		evaluate (LContext &lcontext,
490  					  const ExprNodePtr &expr) const;
491 
492     virtual ExprNodePtr		castValue (LContext &lcontext,
493 				           const ExprNodePtr &expr) const;
494 
495     virtual void		print (int indent) const;
496     virtual std::string		asString () const;
497 };
498 
499 
500 class ArrayType: public DataType
501 {
502   public:
503     ArrayType (const DataTypePtr &elementType, int size);
504 
505     //---------------------------------------------------------------
506     // For array types, objectSize() returns the size of the entire
507     // array object.  elementSize() returns the size of an individual
508     // array element, including padding for proper alignment
509     // (elementSize() returns elementType()->alignedObjectSize()).
510     // For example, if an array's elements occypy 10-bytes each, but
511     // require four-byte alignment, then each element will be padded
512     // with two extra bytes, and elementSize() returns 12.
513     //---------------------------------------------------------------
514 
515     size_t			elementSize () const;
516 
517     virtual bool		isSameTypeAs (const TypePtr &t) const;
518     virtual bool		canAssign (const TypePtr &t) const;
519     virtual bool		canPromoteFrom (const TypePtr &t) const;
520     virtual bool		canCastFrom (const TypePtr &t) const;
521 
cDataType()522 	virtual CDataType_e cDataType() const { return ArrayTypeEnum; };
523 
524     virtual ExprNodePtr		evaluate (LContext &lcontext,
525 					  const ExprNodePtr &expr) const;
526 
527     virtual ExprNodePtr		castValue (LContext &lcontext,
528 				           const ExprNodePtr &expr) const;
529 
530     virtual void		print (int indent) const;
531     virtual std::string		asString () const;
532 
elementType()533     const DataTypePtr &		elementType () const	{return _elementType;}
size()534     int				size () const		{return _size;}
535 
536     // utility functions for arrays of arrays
537     void			sizes (SizeVector &sizes) const;
538     virtual void                coreSizes(size_t parentOffset,
539 					  SizeVector &sizes,
540 					  SizeVector &offsets) const;
541 
542     //
543     //  The underlying non-array type of an array.  e.g. for
544     //  a type int[3][2], returns IntType
545     //
546     DataTypePtr                 coreType() const;
547 
548   private:
549 
550     DataTypePtr _elementType;
551     int         _size;
552 };
553 
554 
555 struct Member
556 {
557      Member (const std::string &name, const DataTypePtr &type);
558     ~Member ();
559 
560     std::string	name;
561     DataTypePtr	type;
562     size_t	offset;		// set by StructType
563 };
564 
565 
566 typedef std::vector <Member> MemberVector;
567 typedef std::vector <Member>::iterator MemberVectorIterator;
568 typedef std::vector <Member>::const_iterator MemberVectorConstIterator;
569 
570 
571 class StructType: public DataType
572 {
573   public:
574 
575     StructType (const std::string &name,
576 		const MemberVector &members);
577 
name()578     const std::string &		name () const		{return _name;}
members()579     const MemberVector &	members () const	{return _members;}
580     virtual void                coreSizes(size_t parentOffset,
581 					  SizeVector &sizes,
582 					  SizeVector &offsets) const;
583 
584     virtual bool		isSameTypeAs (const TypePtr &t) const;
585     virtual bool		canAssign (const TypePtr &t) const;
586     virtual bool		canPromoteFrom (const TypePtr &t) const;
587     virtual bool		canCastFrom (const TypePtr &t) const;
588 
cDataType()589 	virtual CDataType_e cDataType() const { return StructTypeEnum; };
590 
591     virtual ExprNodePtr		evaluate (LContext &lcontext,
592 					  const ExprNodePtr &expr) const;
593 
594     virtual ExprNodePtr		castValue (LContext &lcontext,
595 				           const ExprNodePtr &expr) const;
596 
597     virtual void		print (int indent) const;
598     virtual std::string		asString () const;
599 
600 
601   protected:
602 
member(size_t i)603     Member &			member (size_t i)	{return _members[i];}
604 
605   private:
606 
607     const std::string		_name;
608     MemberVector		_members;
609 };
610 
611 
612 struct Param
613 {
614      Param (const std::string &name,
615 	    const DataTypePtr &type,
616 	    const ExprNodePtr &defaultValue,
617 	    ReadWriteAccess access,
618 	    bool varying);
619 
620     ~Param();
621 
622     bool isWritable() const;
623     bool isReadable() const;
624 
625     std::string		name;
626     DataTypePtr		type;
627     ExprNodePtr		defaultValue;
628     ReadWriteAccess	access;
629     bool		varying;
630 };
631 
632 typedef std::vector <Param> ParamVector;
633 
634 
635 class FunctionType: public Type
636 {
637   public:
638 
639     FunctionType (const DataTypePtr &returnType,
640 		  bool returnVarying,
641 	          const ParamVector &parameters);
642 
returnType()643     const DataTypePtr &		returnType () const	{return _returnType;}
returnVarying()644     bool			returnVarying () const	{return _returnVarying;}
parameters()645     const ParamVector &		parameters () const	{return _parameters;}
646 
647     virtual bool		isSameTypeAs (const TypePtr &t) const;
648     virtual bool		canAssign (const TypePtr &t) const;
649     virtual bool		canPromoteFrom (const TypePtr &t) const;
650     virtual bool		canCastFrom (const TypePtr &t) const;
651 
652     virtual ExprNodePtr		evaluate (LContext &lcontext,
653 					  const ExprNodePtr &expr) const;
654 
655     virtual ExprNodePtr		castValue (LContext &lcontext,
656 				           const ExprNodePtr &expr) const;
657 
658     virtual void		print (int indent) const;
659     virtual std::string		asString () const;
660 
661   private:
662 
663     DataTypePtr			_returnType;
664     bool			_returnVarying;
665     ParamVector			_parameters;
666 };
667 
668 
669 } // namespace Ctl
670 
671 #endif
672