source: src/Parser/ExpressionNode.cc @ 35f9114

ADTaaron-thesisarm-ehast-experimentalcleanup-dtorsctordeferred_resndemanglerenumforall-pointer-decayjacob/cs343-translationjenkins-sandboxmemorynew-astnew-ast-unique-exprnew-envno_listpersistent-indexerpthread-emulationqualifiedEnumresolv-newwith_gc
Last change on this file since 35f9114 was d9e2280, checked in by Peter A. Buhr <pabuhr@…>, 8 years ago

even more more refactoring of parser code

  • Property mode set to 100644
File size: 18.2 KB
Line 
1//
2// Cforall Version 1.0.0 Copyright (C) 2015 University of Waterloo
3//
4// The contents of this file are covered under the licence agreement in the
5// file "LICENCE" distributed with Cforall.
6//
7// ExpressionNode.cc --
8//
9// Author           : Rodolfo G. Esteves
10// Created On       : Sat May 16 13:17:07 2015
11// Last Modified By : Peter A. Buhr
12// Last Modified On : Fri Aug  5 15:07:19 2016
13// Update Count     : 409
14//
15
16#include <cassert>
17#include <cctype>
18#include <algorithm>
19#include <sstream>
20#include <cstdio>
21
22#include "ParseNode.h"
23#include "TypeData.h"
24#include "SynTree/Constant.h"
25#include "SynTree/Expression.h"
26#include "SynTree/Declaration.h"
27#include "Common/UnimplementedError.h"
28#include "parseutility.h"
29#include "Common/utility.h"
30
31using namespace std;
32
33ExpressionNode::ExpressionNode() : ParseNode() {}
34
35ExpressionNode::ExpressionNode( const string *name ) : ParseNode( name ) {}
36
37ExpressionNode::ExpressionNode( const ExpressionNode &other ) : ParseNode( other.name ), extension( other.extension ) {
38        if ( other.argName ) {
39                argName = other.argName->clone();
40        } else {
41                argName = 0;
42        } // if
43}
44
45ExpressionNode * ExpressionNode::set_argName( const std::string *aName ) {
46        argName = new VarRefNode( aName );
47        return this;
48}
49
50ExpressionNode * ExpressionNode::set_argName( ExpressionNode *aDesignator ) {
51        argName = aDesignator;
52        return this;
53}
54
55void ExpressionNode::printDesignation( std::ostream &os, int indent ) const {
56        if ( argName ) {
57                os << string( indent, ' ' ) << "(designated by:  ";
58                argName->printOneLine( os, indent );
59                os << ")" << std::endl;
60        } // if
61}
62
63//##############################################################################
64
65NullExprNode::NullExprNode() {}
66
67NullExprNode *NullExprNode::clone() const {
68        return new NullExprNode();
69}
70
71void NullExprNode::print( std::ostream & os, int indent ) const {
72        printDesignation( os );
73        os << "null expression";
74}
75
76void NullExprNode::printOneLine( std::ostream & os, int indent ) const {
77        printDesignation( os );
78        os << "null";
79}
80
81Expression *NullExprNode::build() const {
82        return 0;
83}
84
85// CommaExprNode *ExpressionNode::add_to_list( ExpressionNode *exp ) {
86//      return new CommaExprNode( this, exp );
87// }
88
89//##############################################################################
90
91ConstantNode::ConstantNode( ConstantExpr *expr ) : expr( expr ) {
92} // ConstantNode::ConstantNode
93
94ConstantNode *ConstantNode::appendstr( const std::string *newValue ) {
95        assert( newValue != 0 );
96
97        string value = expr->get_constant()->get_value();
98
99        // "abc" "def" "ghi" => "abcdefghi", remove new text from quotes and insert before last quote in old string.
100        value.insert( value.length() - 1, newValue->substr( 1, newValue->length() - 2 ) );
101        expr->get_constant()->set_value( value );
102
103        delete newValue;                                                                        // allocated by lexer
104        return this;
105}
106
107void ConstantNode::printOneLine( std::ostream &os, int indent ) const {
108        // os << string( indent, ' ' );
109        // printDesignation( os );
110
111        // switch ( type ) {
112        //   case Integer:
113        //   case Float:
114        //      os << value ;
115        //      break;
116        //   case Character:
117        //      os << "'" << value << "'";
118        //      break;
119        //   case String:
120        //      os << '"' << value << '"';
121        //      break;
122        // } // switch
123
124        // os << ' ';
125}
126
127void ConstantNode::print( std::ostream &os, int indent ) const {
128        printOneLine( os, indent );
129        os << endl;
130}
131
132Expression *ConstantNode::build() const {
133        return expr->clone();
134}
135
136//##############################################################################
137
138VarRefNode::VarRefNode() : isLabel( false ) {}
139
140VarRefNode::VarRefNode( const string *name_, bool labelp ) : ExpressionNode( name_ ), isLabel( labelp ) {}
141
142VarRefNode::VarRefNode( const VarRefNode &other ) : ExpressionNode( other ), isLabel( other.isLabel ) {
143}
144
145Expression *VarRefNode::build() const {
146        return new NameExpr( get_name(), maybeBuild< Expression >( get_argName() ) );
147}
148
149void VarRefNode::printOneLine( std::ostream &os, int indent ) const {
150        printDesignation( os );
151        os << get_name() << ' ';
152}
153
154void VarRefNode::print( std::ostream &os, int indent ) const {
155        printDesignation( os );
156        os << string( indent, ' ' ) << "Referencing: ";
157        os << "Variable: " << get_name();
158        os << endl;
159}
160
161//##############################################################################
162
163DesignatorNode::DesignatorNode( ExpressionNode *expr, bool isArrayIndex ) : isArrayIndex( isArrayIndex ) {
164        set_argName( expr );
165        assert( get_argName() );
166
167        if ( ! isArrayIndex ) {
168                if ( VarRefNode * var = dynamic_cast< VarRefNode * >( expr ) ) {
169
170                        stringstream ss( var->get_name() );
171                        double value;
172                        if ( ss >> value ) {
173                                // this is a floating point constant. It MUST be
174                                // ".0" or ".1", otherwise the program is invalid
175                                if ( ! (var->get_name() == ".0" || var->get_name() == ".1") ) {
176                                        throw SemanticError( "invalid designator name: " + var->get_name() );
177                                } // if
178                                var->set_name( var->get_name().substr(1) );
179                        } // if
180                } // if
181        } // if
182}
183
184DesignatorNode::DesignatorNode( const DesignatorNode &other ) : ExpressionNode( other ), isArrayIndex( other.isArrayIndex ) {
185}
186
187class DesignatorFixer : public Mutator {
188public:
189        virtual Expression* mutate( NameExpr *nameExpr ) {
190                if ( nameExpr->get_name() == "0" || nameExpr->get_name() == "1" ) {
191                        Constant val( new BasicType( Type::Qualifiers(), BasicType::SignedInt ), nameExpr->get_name() );
192                        delete nameExpr;
193                        return new ConstantExpr( val );
194                }
195                return nameExpr;
196        }
197};
198
199Expression *DesignatorNode::build() const {
200        Expression * ret = maybeBuild<Expression>(get_argName());
201
202        if ( isArrayIndex ) {
203                // need to traverse entire structure and change any instances of 0 or 1 to
204                // ConstantExpr
205                DesignatorFixer fixer;
206                ret = ret->acceptMutator( fixer );
207        } // if
208
209        return ret;
210}
211
212void DesignatorNode::printOneLine( std::ostream &os, int indent ) const {
213        if ( get_argName() ) {
214                if ( isArrayIndex ) {
215                        os << "[";
216                        get_argName()->printOneLine( os, indent );
217                        os << "]";
218                } else {
219                        os << ".";
220                        get_argName()->printOneLine( os, indent );
221                }
222        } // if
223}
224
225void DesignatorNode::print( std::ostream &os, int indent ) const {
226        if ( get_argName() ) {
227                if ( isArrayIndex ) {
228                        os << "[";
229                        get_argName()->print( os, indent );
230                        os << "]";
231                } else {
232                        os << ".";
233                        get_argName()->print( os, indent );
234                }
235        } // if
236}
237
238//##############################################################################
239
240static const char *OperName[] = {
241        // diadic
242        "SizeOf", "AlignOf", "OffsetOf", "Attr", "?+?", "?-?", "?*?", "?/?", "?%?", "||", "&&",
243        "?|?", "?&?", "?^?", "Cast", "?<<?", "?>>?", "?<?", "?>?", "?<=?", "?>=?", "?==?", "?!=?",
244        "?=?", "?*=?", "?/=?", "?%=?", "?+=?", "?-=?", "?<<=?", "?>>=?", "?&=?", "?^=?", "?|=?",
245        "?[?]", "...",
246        // monadic
247        "+?", "-?", "AddressOf", "*?", "!?", "~?", "++?", "?++", "--?", "?--", "&&"
248};
249
250//##############################################################################
251
252CompositeExprNode::CompositeExprNode( Expression *expr ) : expr( expr ) {}
253CompositeExprNode::CompositeExprNode( const CompositeExprNode &other ) : expr( other.expr->clone() ) {}
254CompositeExprNode::~CompositeExprNode() { delete expr; }
255void CompositeExprNode::print( std::ostream &, int indent ) const { assert( false ); }
256void CompositeExprNode::printOneLine( std::ostream &, int indent ) const { assert( false ); }
257
258Expression *build_cast( TypeValueNode * arg, ExpressionNode *expr_node ) {
259        DeclarationNode *decl_node = arg->get_decl();
260
261        Type *targetType = decl_node->buildType();
262        if ( dynamic_cast< VoidType* >( targetType ) ) {
263                delete targetType;
264                return new CastExpr( maybeBuild<Expression>(expr_node) );
265        } else {
266                return new CastExpr( maybeBuild<Expression>(expr_node), targetType );
267        } // if
268}
269
270Expression *build_fieldSel( ExpressionNode *expr_node, VarRefNode *member ) {
271        NameExpr* memberExpr = dynamic_cast<NameExpr*> ( maybeBuild<Expression>( member) );
272        assert( memberExpr );
273        UntypedMemberExpr *ret = new UntypedMemberExpr( memberExpr->get_name(), maybeBuild<Expression>(expr_node) );
274        delete member;
275        return ret;
276}
277
278Expression *build_pfieldSel( ExpressionNode *expr_node, VarRefNode *member ) {
279        NameExpr* memberExpr = dynamic_cast<NameExpr*> ( maybeBuild<Expression>( member) );
280        assert( memberExpr );
281        UntypedExpr *deref = new UntypedExpr( new NameExpr( "*?" ) );
282        deref->get_args().push_back( maybeBuild<Expression>(expr_node) );
283        UntypedMemberExpr *ret = new UntypedMemberExpr( memberExpr->get_name(), deref );
284        delete member;
285        return ret;
286}
287
288Expression *build_addressOf( ExpressionNode *expr_node ) {
289                return new AddressExpr( maybeBuild<Expression>(expr_node) );
290}
291Expression *build_sizeOf( ExpressionNode *expr_node ) {
292        if ( TypeValueNode * arg = dynamic_cast<TypeValueNode *>( expr_node ) ) {
293                return new SizeofExpr( arg->get_decl()->buildType() );
294        } else {
295                return new SizeofExpr( maybeBuild<Expression>(expr_node) );
296        } // if
297}
298Expression *build_alignOf( ExpressionNode *expr_node ) {
299        if ( TypeValueNode * arg = dynamic_cast<TypeValueNode *>( expr_node ) ) {
300                return new AlignofExpr( arg->get_decl()->buildType() );
301        } else {
302                return new AlignofExpr( maybeBuild<Expression>(expr_node) );
303        } // if
304}
305Expression *build_offsetOf( TypeValueNode * arg, VarRefNode *member ) {
306        NameExpr *memberExpr = dynamic_cast<NameExpr *>( maybeBuild<Expression>( member ) );
307        assert( memberExpr );
308        return new UntypedOffsetofExpr( arg->get_decl()->buildType(), memberExpr->get_name() );
309}
310
311Expression *build_and_or( ExpressionNode *expr_node1, ExpressionNode *expr_node2, bool kind ) {
312        return new LogicalExpr( notZeroExpr( maybeBuild<Expression>(expr_node1) ), notZeroExpr( maybeBuild<Expression>(expr_node2) ), kind );
313}
314
315Expression *build_unary_val( OperKinds op, ExpressionNode *expr_node ) {
316        std::list<Expression *> args;
317        args.push_back( maybeBuild<Expression>(expr_node) );
318        return new UntypedExpr( new NameExpr( OperName[ (int)op ] ), args );
319}
320Expression *build_unary_ptr( OperKinds op, ExpressionNode *expr_node ) {
321        std::list<Expression *> args;
322        args.push_back( new AddressExpr( maybeBuild<Expression>(expr_node) ) );
323        return new UntypedExpr( new NameExpr( OperName[ (int)op ] ), args );
324}
325Expression *build_binary_val( OperKinds op, ExpressionNode *expr_node1, ExpressionNode *expr_node2 ) {
326        std::list<Expression *> args;
327        args.push_back( maybeBuild<Expression>(expr_node1) );
328        args.push_back( maybeBuild<Expression>(expr_node2) );
329        return new UntypedExpr( new NameExpr( OperName[ (int)op ] ), args );
330}
331Expression *build_binary_ptr( OperKinds op, ExpressionNode *expr_node1, ExpressionNode *expr_node2 ) {
332        std::list<Expression *> args;
333        args.push_back( new AddressExpr( maybeBuild<Expression>(expr_node1) ) );
334        args.push_back( maybeBuild<Expression>(expr_node2) );
335        return new UntypedExpr( new NameExpr( OperName[ (int)op ] ), args );
336}
337
338Expression *build_cond( ExpressionNode *expr_node1, ExpressionNode *expr_node2, ExpressionNode *expr_node3 ) {
339        return new ConditionalExpr( notZeroExpr( maybeBuild<Expression>(expr_node1) ), maybeBuild<Expression>(expr_node2), maybeBuild<Expression>(expr_node3) );
340}
341
342Expression *build_comma( ExpressionNode *expr_node1, ExpressionNode *expr_node2 ) {
343        return new CommaExpr( maybeBuild<Expression>(expr_node1), maybeBuild<Expression>(expr_node2) );
344}
345
346Expression *build_attr( VarRefNode *var, ExpressionNode * expr ) {
347        if ( TypeValueNode * arg = dynamic_cast<TypeValueNode *>( expr ) ) {
348                return new AttrExpr( maybeBuild<Expression>(var), arg->get_decl()->buildType() );
349        } else {
350                return new AttrExpr( maybeBuild<Expression>(var), maybeBuild<Expression>(expr) );
351        } // if
352}
353
354Expression *build_tuple( ExpressionNode * expr ) {
355        TupleExpr *ret = new TupleExpr();
356        buildList( expr, ret->get_exprs() );
357        return ret;
358}
359
360Expression *build_func( ExpressionNode * function, ExpressionNode * expr ) {
361        std::list<Expression *> args;
362
363        buildList( expr, args );
364        return new UntypedExpr( maybeBuild<Expression>(function), args, nullptr );
365}
366
367Expression *build_range( ExpressionNode * low, ExpressionNode *high ) {
368        Expression *low_cexpr = maybeBuild<Expression>( low );
369        Expression *high_cexpr = maybeBuild<Expression>( high );
370        return new RangeExpr( low_cexpr, high_cexpr );
371}
372
373//##############################################################################
374
375Expression *AsmExprNode::build() const {
376        return new AsmExpr( maybeBuild< Expression >( inout ), (ConstantExpr *)maybeBuild<Expression>(constraint), maybeBuild<Expression>(operand) );
377}
378
379void AsmExprNode::print( std::ostream &os, int indent ) const {
380        os << string( indent, ' ' ) << "Assembler Expression:" << endl;
381        if ( inout ) {
382                os << string( indent, ' ' ) << "inout: " << std::endl;
383                inout->print( os, indent + 2 );
384        } // if
385        if ( constraint ) {
386                os << string( indent, ' ' ) << "constraint: " << std::endl;
387                constraint->print( os, indent + 2 );
388        } // if
389        if ( operand ) {
390                os << string( indent, ' ' ) << "operand: " << std::endl;
391                operand->print( os, indent + 2 );
392        } // if
393}
394
395void AsmExprNode::printOneLine( std::ostream &os, int indent ) const {
396        printDesignation( os );
397        os << "( ";
398        if ( inout ) inout->printOneLine( os, indent + 2 );
399        os << ", ";
400        if ( constraint ) constraint->printOneLine( os, indent + 2 );
401        os << ", ";
402        if ( operand ) operand->printOneLine( os, indent + 2 );
403        os << ") ";
404}
405
406//##############################################################################
407
408void LabelNode::print( std::ostream &os, int indent ) const {}
409
410void LabelNode::printOneLine( std::ostream &os, int indent ) const {}
411
412//##############################################################################
413
414ValofExprNode::ValofExprNode( StatementNode *s ): body( s ) {}
415
416ValofExprNode::ValofExprNode( const ValofExprNode &other ) : ExpressionNode( other ), body( maybeClone( body ) ) {
417}
418
419ValofExprNode::~ValofExprNode() {
420        delete body;
421}
422
423void ValofExprNode::print( std::ostream &os, int indent ) const {
424        printDesignation( os );
425        os << string( indent, ' ' ) << "Valof Expression:" << std::endl;
426        get_body()->print( os, indent + 4);
427}
428
429void ValofExprNode::printOneLine( std::ostream &, int indent ) const {
430        assert( false );
431}
432
433Expression *ValofExprNode::build() const {
434        return new UntypedValofExpr ( maybeBuild<Statement>(get_body()), maybeBuild< Expression >( get_argName() ) );
435}
436
437//##############################################################################
438
439ForCtlExprNode::ForCtlExprNode( ParseNode *init_, ExpressionNode *cond, ExpressionNode *incr ) throw ( SemanticError ) : condition( cond ), change( incr ) {
440        if ( init_ == 0 )
441                init = 0;
442        else {
443                DeclarationNode *decl;
444                ExpressionNode *exp;
445
446                if (( decl = dynamic_cast<DeclarationNode *>(init_) ) != 0)
447                        init = new StatementNode( decl );
448                else if (( exp = dynamic_cast<ExpressionNode *>( init_)) != 0)
449                        init = new StatementNode( StatementNode::Exp, exp );
450                else
451                        throw SemanticError("Error in for control expression");
452        }
453}
454
455ForCtlExprNode::ForCtlExprNode( const ForCtlExprNode &other )
456        : ExpressionNode( other ), init( maybeClone( other.init ) ), condition( maybeClone( other.condition ) ), change( maybeClone( other.change ) ) {
457}
458
459ForCtlExprNode::~ForCtlExprNode() {
460        delete init;
461        delete condition;
462        delete change;
463}
464
465Expression *ForCtlExprNode::build() const {
466        // this shouldn't be used!
467        assert( false );
468        return 0;
469}
470
471void ForCtlExprNode::print( std::ostream &os, int indent ) const{
472        os << string( indent,' ' ) << "For Control Expression -- :" << endl;
473
474        os << string( indent + 2, ' ' ) << "initialization:" << endl;
475        if ( init != 0 )
476                init->printList( os, indent + 4 );
477
478        os << string( indent + 2, ' ' ) << "condition: " << endl;
479        if ( condition != 0 )
480                condition->print( os, indent + 4 );
481        os << string( indent + 2, ' ' ) << "increment: " << endl;
482        if ( change != 0 )
483                change->print( os, indent + 4 );
484}
485
486void ForCtlExprNode::printOneLine( std::ostream &, int indent ) const {
487        assert( false );
488}
489
490//##############################################################################
491
492TypeValueNode::TypeValueNode( DeclarationNode *decl ) : decl( decl ) {
493}
494
495TypeValueNode::TypeValueNode( const TypeValueNode &other ) : ExpressionNode( other ), decl( maybeClone( other.decl ) ) {
496}
497
498Expression *TypeValueNode::build() const {
499        return new TypeExpr( decl->buildType() );
500}
501
502void TypeValueNode::print( std::ostream &os, int indent ) const {
503        os << std::string( indent, ' ' ) << "Type:";
504        get_decl()->print( os, indent + 2);
505}
506
507void TypeValueNode::printOneLine( std::ostream &os, int indent ) const {
508        os << "Type:";
509        get_decl()->print( os, indent + 2);
510}
511
512
513CompoundLiteralNode::CompoundLiteralNode( DeclarationNode *type, InitializerNode *kids ) : type( type ), kids( kids ) {}
514CompoundLiteralNode::CompoundLiteralNode( const CompoundLiteralNode &other ) : ExpressionNode( other ), type( other.type ), kids( other.kids ) {}
515
516CompoundLiteralNode::~CompoundLiteralNode() {
517        delete kids;
518        delete type;
519}
520
521CompoundLiteralNode *CompoundLiteralNode::clone() const {
522        return new CompoundLiteralNode( *this );
523}
524
525void CompoundLiteralNode::print( std::ostream &os, int indent ) const {
526        os << string( indent,' ' ) << "CompoundLiteralNode:" << endl;
527
528        os << string( indent + 2, ' ' ) << "type:" << endl;
529        if ( type != 0 )
530                type->print( os, indent + 4 );
531
532        os << string( indent + 2, ' ' ) << "initialization:" << endl;
533        if ( kids != 0 )
534                kids->printList( os, indent + 4 );
535}
536
537void CompoundLiteralNode::printOneLine( std::ostream &os, int indent ) const {
538        os << "( ";
539        if ( type ) type->print( os );
540        os << ", ";
541        if ( kids ) kids->printOneLine( os );
542        os << ") ";
543}
544
545Expression *CompoundLiteralNode::build() const {
546        Declaration * newDecl = maybeBuild<Declaration>(type); // compound literal type
547        if ( DeclarationWithType * newDeclWithType = dynamic_cast< DeclarationWithType * >( newDecl ) ) { // non-sue compound-literal type
548                return new CompoundLiteralExpr( newDeclWithType->get_type(), maybeBuild<Initializer>(kids) );
549        // these types do not have associated type information
550        } else if ( StructDecl * newDeclStructDecl = dynamic_cast< StructDecl * >( newDecl )  ) {
551                return new CompoundLiteralExpr( new StructInstType( Type::Qualifiers(), newDeclStructDecl->get_name() ), maybeBuild<Initializer>(kids) );
552        } else if ( UnionDecl * newDeclUnionDecl = dynamic_cast< UnionDecl * >( newDecl )  ) {
553                return new CompoundLiteralExpr( new UnionInstType( Type::Qualifiers(), newDeclUnionDecl->get_name() ), maybeBuild<Initializer>(kids) );
554        } else if ( EnumDecl * newDeclEnumDecl = dynamic_cast< EnumDecl * >( newDecl )  ) {
555                return new CompoundLiteralExpr( new EnumInstType( Type::Qualifiers(), newDeclEnumDecl->get_name() ), maybeBuild<Initializer>(kids) );
556        } else {
557                assert( false );
558        } // if
559}
560
561// Local Variables: //
562// tab-width: 4 //
563// mode: c++ //
564// compile-command: "make install" //
565// End: //
Note: See TracBrowser for help on using the repository browser.