source: src/Parser/ParseNode.cc @ 99f11dd

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

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

  • Property mode set to 100644
File size: 7.3 KB
RevLine 
[b87a5ed]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
[ca35c51]11// Last Modified By : Peter A. Buhr
[8e9cbb2]12// Last Modified On : Thu Jun 30 21:13:12 2016
13// Update Count     : 52
[b87a5ed]14//
15
[ca35c51]16#include <climits>
[51b7345]17#include "ParseNode.h"
18using namespace std;
19
[ca35c51]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
[8e9cbb2]159
[ca35c51]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
[51b7345]177// Builder
178int ParseNode::indent_by = 4;
179
[e869d663]180ParseNode::ParseNode() : next( 0 ) {};
181ParseNode::ParseNode( const string *name ) : name( *name ), next( 0 ) { delete name; }
182ParseNode::ParseNode( const string &name ) : name( name ), next( 0 ) { }
[51b7345]183
[59db689]184ParseNode::~ParseNode() {
[e869d663]185        delete next;
[51b7345]186};
187
[59db689]188ParseNode *ParseNode::get_last() {
[a08ba92]189        ParseNode *current = this;
[51b7345]190
[a08ba92]191        while ( current->get_link() != 0 )
[3848e0e]192        current = current->get_link();
[51b7345]193
[a08ba92]194        return current;
[51b7345]195}
196
[59db689]197ParseNode *ParseNode::set_link( ParseNode *next_ ) {
198        if ( next_ == 0 ) return this;
[71bd8c6]199        get_last()->next = next_;
[a08ba92]200        return this;
[51b7345]201}
202
[a61fea9a]203void ParseNode::print( std::ostream &os, int indent ) const {}
[51b7345]204
205
[3848e0e]206void ParseNode::printList( std::ostream &os, int indent ) const {
[a08ba92]207        print( os, indent );
[51b7345]208
[a08ba92]209        if ( next ) {
[a61fea9a]210                next->printList( os, indent );
[59db689]211        } // if
[51b7345]212}
213
[3848e0e]214ParseNode &ParseNode::operator,( ParseNode &p ) {
[a08ba92]215        set_link( &p );
[51b7345]216
[a08ba92]217        return *this;
[51b7345]218}
219
[bdd516a]220ParseNode *mkList( ParseNode &pn ) {
[a08ba92]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;
[51b7345]225}
226
227// Local Variables: //
[b87a5ed]228// tab-width: 4 //
229// mode: c++ //
230// compile-command: "make install" //
[51b7345]231// End: //
Note: See TracBrowser for help on using the repository browser.