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

ADT aaron-thesis arm-eh ast-experimental cleanup-dtors ctor deferred_resn demangler enum forall-pointer-decay jacob/cs343-translation jenkins-sandbox memory new-ast new-ast-unique-expr new-env no_list persistent-indexer pthread-emulation qualifiedEnum resolv-new with_gc
Last change on this file since 35f9114 was d9e2280, checked in by Peter A. Buhr <pabuhr@…>, 9 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.