home *** CD-ROM | disk | FTP | other *** search
- /*****************************************************
- File: ACTIONS.CPP Copyright 1989 by John M. Dlugosz
- the Actions called from the parser
- *****************************************************/
-
- #include "usual.hpp"
- #include <stream.hpp>
- #include "atom.hpp"
- #include "node.hpp"
- #include "define.hpp"
-
- // #define SHORT return 0
- /* short out actions for testing parser only.
- if something suddenly goes wrong, I can stub
- out all the actions to make sure I'm not walking
- on data somewhere. */
- #define SHORT
- // the normal case.
-
- /* /\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\ */
-
- static char last_token[81];
-
- void get_last_token()
- {
- /* copy last token from scanner into a nul-terminated string */
- int len= 80; //maximum sig. length
- extern char *T_beg, *T_end; //from the scanner
- char* source= T_beg;
- char* dest= last_token;
-
- //cout << (unsigned)T_beg << " " << T_end;
- //for (int x= 0; x < 5; x++) cout.put(T_beg[x]);
-
- while (len-- && source < T_end) *dest++ = *source++;
- *dest= '\0';
- }
-
- /* /\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\ */
-
- /* in a declaration, a storage class is the first thing I get. This starts
- it off. Then a ConstVol, a StoreType, and a second ConstVol. The const
- or volatile keyword may appear before or after the type, with equal
- effect. The two bits are ORed together for the final result.
- After this, I get one or more calls to Declaration.
- */
-
- /* /\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\ */
-
- // the type I'm building
- struct working_type {
- type_node* this_type; //the tail
- type_node* root_type; //the head
- int base_type;
- atom tag_name; // if base_type has a name
- atom name; //The name of the thing being declared
- int storage_class;
- int const_vol;
- working_type* next;
- } MainType;
-
- working_type* Tx= &MainType;
- /* this is accessed through a pointer because a declarator can be encounted
- while parsing another declarator. This lets me stack them. */
-
- /* /\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\ */
-
- static int const_vol_stack[50];
- static int const_vol_stacktop= 0;
-
- /* /\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\ */
-
- int Declaration (int x,...)
- {
- /* values for x: 1- global or local def.
- 2- parameters
- 3- struct/union list
- */
- SHORT;
- /* This finishes it off. A complete declaration has been found. */
- Tx->this_type->stuff_primary (Tx->base_type, Tx->tag_name);
- Tx->this_type->flags |= Tx->const_vol;
- // build the 'thing' from the type_node and the name.
- store_thing (Tx->root_type, Tx->name, Tx->storage_class, x);
- // Tx->root_type->print();
- // cout.put('\n');
- return 0;
- }
-
- /* /\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\ */
-
- int StoreBaseConstVol (int x,...)
- {
- SHORT;
- // the first two calls to ConstVol apply here.
- Tx->const_vol = const_vol_stack[--const_vol_stacktop];
- Tx->const_vol |= const_vol_stack[--const_vol_stacktop];
- return 0;
- }
-
- /* /\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\ */
-
- int StoreType (int x,...)
- {
- SHORT;
- Tx->base_type= x;
- return 0;
- }
-
- /* /\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\ */
-
- int StoreTag (int x,...)
- {
- SHORT;
- /* called when a struct, union, or enum is parsed. The tag is the last
- token read. After this call, the StoreType call is made with 'union'
- or whatever. */
- get_last_token();
- Tx->tag_name= atoms[last_token];
- return 0;
- }
-
- /* /\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\ */
-
- int StoreStorage (int x,...)
- {
- SHORT;
- /* this is the first thing called */
- Tx->storage_class= x;
- return 0;
- }
-
- /* /\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\ */
-
- int Dname (int x,...)
- {
- SHORT;
- /* if x==1, the last token is the name of a thing being declared. If
- x==0, there is no name and this is an abstact declarator. Either
- way, build a type node and store the name. This overwrites the type
- node, as it will be the first thing called. */
-
- if (x) {
- get_last_token();
- Tx->name= atoms[last_token];
- }
- Tx->this_type= new type_node;
- Tx->root_type= Tx->this_type;
- return 0;
- }
-
- /* /\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\ */
-
- int TypeModifier (int x,...)
- {
- SHORT;
- /* 1 t() 2 t[] 3 *t 4 &t */
-
- switch (x) {
- case 1:
- Tx->this_type->primary= type_function;
- // attach parameter list
- Tx->this_type->aggr= completed_def_list;
- break;
- case 2:
- Tx->this_type->primary= type_array;
- // >> attach size
- break;
- case 3:
- Tx->this_type->primary= type_pointer;
- Tx->this_type->flags |= const_vol_stack[--const_vol_stacktop];
- break;
- case 4:
- Tx->this_type->primary= type_reference;
- Tx->this_type->flags |= const_vol_stack[--const_vol_stacktop];
- break;
- }
- Tx->this_type->to_what= new type_node;
- Tx->this_type= Tx->this_type->to_what;
-
- return 0;
- }
-
- /* /\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\ */
-
- int ConstVol (int x,...)
- {
- SHORT;
- /* 1-const 2-volatile 3-both */
- const_vol_stack[const_vol_stacktop++]= x;
- return 0;
- }
-
- /* /\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\ */
-
- int ReachType (int x,...)
- {
- SHORT;
- /* 0-default 1-near 2-far */
- return 0;
- }
-
- /* /\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\ */
-
- int NestedType (int x, ...)
- {
- SHORT;
- working_type* p;
- if (x) { //start nesting
- p= new working_type;
- p->next= Tx;
- Tx= p;
- }
- else { //restore old type
- p= Tx;
- Tx= Tx->next;
- delete p;
- }
- parameter_list (x); //pass on to DEFINE module
- return 0;
- }
-
- /* /\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\ */
- /* /\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\ */
- /* /\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\ */
-
- int AllDoneNow (int x, ...)
- {
- SHORT;
- cout << "parser complete. \n";
- for (int loop= 0; loop < global_stuff.size(); loop++) {
- global_stuff[loop]->print();
- cout.put ('\n');
- }
- return 0;
- }
-
- /* /\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\ */
-