source: src/Parser/ParseNode.cc@ 3f869f0

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 3f869f0 was 8e9cbb2, checked in by Peter A. Buhr <pabuhr@…>, 9 years ago

add more code to handle gcc extension and test program, second attempt

  • Property mode set to 100644
File size: 7.3 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// ParseNode.cc --
8//
9// Author : Rodolfo G. Esteves
10// Created On : Sat May 16 13:26:29 2015
11// Last Modified By : Peter A. Buhr
12// Last Modified On : Thu Jun 30 21:13:12 2016
13// Update Count : 52
14//
15
16#include <climits>
17#include "ParseNode.h"
18using namespace std;
19
20// Difficult to separate extra parts of constants during lexing because actions are not allow in the middle of patterns:
21//
22// prefix action constant action suffix
23//
24// Alternatively, breaking a pattern using BEGIN does not work if the following pattern can be empty:
25//
26// constant BEGIN CONT ...
27// <CONT>(...)? BEGIN 0 ... // possible empty suffix
28//
29// because the CONT rule is NOT triggered if the pattern is empty. Hence, constants are reparsed here to determine their
30// type.
31
32static inline bool checkU( char c ) { return c == 'u' || c == 'U'; }
33static inline bool checkL( char c ) { return c == 'l' || c == 'L'; }
34static inline bool checkF( char c ) { return c == 'f' || c == 'F'; }
35static inline bool checkD( char c ) { return c == 'd' || c == 'D'; }
36static inline bool checkI( char c ) { return c == 'i' || c == 'I'; }
37static inline bool checkX( char c ) { return c == 'x' || c == 'X'; }
38
39BasicType::Kind literalType( ConstantNode::Type type, string &value ) {
40 BasicType::Kind btype;
41
42 // lexing divides constants into 4 kinds
43 switch ( type ) {
44 case ConstantNode::Integer:
45 {
46 static const BasicType::Kind kind[2][3] = {
47 { BasicType::SignedInt, BasicType::LongSignedInt, BasicType::LongLongSignedInt },
48 { BasicType::UnsignedInt, BasicType::LongUnsignedInt, BasicType::LongLongUnsignedInt },
49 };
50 bool dec = true, Unsigned = false; // decimal, unsigned constant
51 int size; // 0 => int, 1 => long, 2 => long long
52 unsigned long long v; // converted integral value
53 size_t last = value.length() - 1; // last character of constant
54
55 if ( value[0] == '0' ) { // octal constant ?
56 dec = false;
57 if ( last != 0 && checkX( value[1] ) ) { // hex constant ?
58 sscanf( (char *)value.c_str(), "%llx", &v );
59 //printf( "%llx %llu\n", v, v );
60 } else {
61 sscanf( (char *)value.c_str(), "%llo", &v );
62 //printf( "%llo %llu\n", v, v );
63 } // if
64 } else { // decimal constant ?
65 sscanf( (char *)value.c_str(), "%llu", &v );
66 //printf( "%llu %llu\n", v, v );
67 } // if
68
69 if ( v <= INT_MAX ) { // signed int
70 size = 0;
71 } else if ( v <= UINT_MAX && ! dec ) { // unsigned int
72 size = 0;
73 Unsigned = true; // unsigned
74 } else if ( v <= LONG_MAX ) { // signed long int
75 size = 1;
76 } else if ( v <= ULONG_MAX && ( ! dec || LONG_MAX == LLONG_MAX ) ) { // signed long int
77 size = 1;
78 Unsigned = true; // unsigned long int
79 } else if ( v <= LLONG_MAX ) { // signed long long int
80 size = 2;
81 } else { // unsigned long long int
82 size = 2;
83 Unsigned = true; // unsigned long long int
84 } // if
85
86 if ( checkU( value[last] ) ) { // suffix 'u' ?
87 Unsigned = true;
88 if ( last > 0 && checkL( value[ last - 1 ] ) ) { // suffix 'l' ?
89 size = 1;
90 if ( last > 1 && checkL( value[ last - 2 ] ) ) { // suffix 'll' ?
91 size = 2;
92 } // if
93 } // if
94 } else if ( checkL( value[ last ] ) ) { // suffix 'l' ?
95 size = 1;
96 if ( last > 0 && checkL( value[ last - 1 ] ) ) { // suffix 'll' ?
97 size = 2;
98 if ( last > 1 && checkU( value[ last - 2 ] ) ) { // suffix 'u' ?
99 Unsigned = true;
100 } // if
101 } else {
102 if ( last > 0 && checkU( value[ last - 1 ] ) ) { // suffix 'u' ?
103 Unsigned = true;
104 } // if
105 } // if
106 } // if
107 btype = kind[Unsigned][size]; // lookup constant type
108 break;
109 }
110 case ConstantNode::Float:
111 {
112 static const BasicType::Kind kind[2][3] = {
113 { BasicType::Float, BasicType::Double, BasicType::LongDouble },
114 { BasicType::FloatComplex, BasicType::DoubleComplex, BasicType::LongDoubleComplex },
115 };
116 bool complx = false; // real, complex
117 int size = 1; // 0 => float, 1 => double (default), 2 => long double
118 // floating-point constant has minimum of 2 characters: 1. or .1
119 size_t last = value.length() - 1;
120
121 if ( checkI( value[last] ) ) { // imaginary ?
122 complx = true;
123 last -= 1; // backup one character
124 } // if
125 if ( checkF( value[last] ) ) { // float ?
126 size = 0;
127 } else if ( checkD( value[last] ) ) { // double ?
128 size = 1;
129 } else if ( checkL( value[last] ) ) { // long double ?
130 size = 2;
131 } // if
132 if ( ! complx && checkI( value[last - 1] ) ) { // imaginary ?
133 complx = true;
134 } // if
135 btype = kind[complx][size]; // lookup constant type
136 break;
137 }
138 case ConstantNode::Character:
139 btype = BasicType::Char; // default
140 if ( string( "LUu" ).find( value[0] ) != string::npos ) {
141 // ???
142 } // if
143 break;
144 case ConstantNode::String:
145 assert( false );
146 // array of char
147 if ( string( "LUu" ).find( value[0] ) != string::npos ) {
148 if ( value[0] == 'u' && value[1] == '8' ) {
149 // ???
150 } else {
151 // ???
152 } // if
153 } // if
154 break;
155 } // switch
156 return btype;
157} // literalType
158
159
160ConstantNode *makeConstant( ConstantNode::Type type, std::string *str ) {
161 ::Type::Qualifiers emptyQualifiers; // no qualifiers on constants
162 return new ConstantNode( new ConstantExpr( Constant( new BasicType( emptyQualifiers, literalType( type, *str ) ), *str ), nullptr ) );
163}
164
165ConstantNode *makeConstantStr( ConstantNode::Type type, std::string *str ) {
166 ::Type::Qualifiers emptyQualifiers; // no qualifiers on constants
167 // string should probably be a primitive type
168 ArrayType *at = new ArrayType( emptyQualifiers, new BasicType( emptyQualifiers, BasicType::Char ),
169 new ConstantExpr(
170 Constant( new BasicType( emptyQualifiers, BasicType::UnsignedInt ),
171 toString( str->size()+1-2 ) ) ), // +1 for '\0' and -2 for '"'
172 false, false );
173 return new ConstantNode( new ConstantExpr( Constant( at, *str ), nullptr ) );
174}
175
176
177// Builder
178int ParseNode::indent_by = 4;
179
180ParseNode::ParseNode() : next( 0 ) {};
181ParseNode::ParseNode( const string *name ) : name( *name ), next( 0 ) { delete name; }
182ParseNode::ParseNode( const string &name ) : name( name ), next( 0 ) { }
183
184ParseNode::~ParseNode() {
185 delete next;
186};
187
188ParseNode *ParseNode::get_last() {
189 ParseNode *current = this;
190
191 while ( current->get_link() != 0 )
192 current = current->get_link();
193
194 return current;
195}
196
197ParseNode *ParseNode::set_link( ParseNode *next_ ) {
198 if ( next_ == 0 ) return this;
199 get_last()->next = next_;
200 return this;
201}
202
203void ParseNode::print( std::ostream &os, int indent ) const {}
204
205
206void ParseNode::printList( std::ostream &os, int indent ) const {
207 print( os, indent );
208
209 if ( next ) {
210 next->printList( os, indent );
211 } // if
212}
213
214ParseNode &ParseNode::operator,( ParseNode &p ) {
215 set_link( &p );
216
217 return *this;
218}
219
220ParseNode *mkList( ParseNode &pn ) {
221 // it just relies on `operator,' to take care of the "arguments" and provides a nice interface to an awful-looking
222 // address-of, rendering, for example (StatementNode *)(&(*$5 + *$7)) into (StatementNode *)mkList(($5, $7))
223 // (although "nice" is probably not the word)
224 return &pn;
225}
226
227// Local Variables: //
228// tab-width: 4 //
229// mode: c++ //
230// compile-command: "make install" //
231// End: //
Note: See TracBrowser for help on using the repository browser.