home *** CD-ROM | disk | FTP | other *** search
- /*****************************************************
- File: DEFINE.CPP Copyright 1989 by John M. Dlugosz
- deal with definitions once they are parsed
- *****************************************************/
-
- #include "usual.hpp"
- #include <stream.hpp>
- #include "atom.hpp"
- #include "node.hpp"
- #include "define.hpp"
-
- static type_node_list unnamed_types;
- local_type_list* named_type_list;
-
- bool local_level= FALSE;
- unsigned memory_model= 0; //small model
-
- def_node_list global_stuff;
- struct p_list_struct {
- def_node_list* l;
- p_list_struct* next;
- };
- static p_list_struct *p_list;
- def_node_list* completed_def_list;
-
- /* /\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\ */
-
- local_type_list::local_type_list (local_type_list* old)
- {
- prev= old;
- }
-
- /* /\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\ */
-
- type_node* local_type_list::search (atom s)
- {
- while (this) {
- for (int loop= 0; loop < list.size(); loop++) {
- type_node* p= list[loop];
- if (p->tag == s) return p;
- }
- this= prev; //try next outer scope
- }
- return NULL;
- }
-
- /* /\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\ */
-
- bool local_type_list::add (type_node* n)
- {
- list.add (n);
- return TRUE;
- }
-
- /* /\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\ */
- /* /\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\ */
-
- bool types_match (type_node *a, type_node *b)
- {
- return (a->secondary() == b->secondary() &&
- a->primary == b->primary &&
- a->flags == b->flags);
- }
-
- /* /\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\ */
-
- static type_node* normalize_type (type_node* n)
- {
-
- return n; //short out for testing
-
- if (n->secondary()) n->to_what= normalize_type (n->to_what);
- if (n->tag == -1) { //unnamed type
- if (n->aggr == NULL) {
- // an unnamed class is always a unique type
- for (int loop= 0; loop < unnamed_types.size(); loop++) {
- if (types_match (n, unnamed_types[loop])) { //found it!
- delete n;
- return unnamed_types[loop];
- }
- }
- // drop out of loop. no match
- unnamed_types.add (n); //add to list
- }
- return n;
- }
- else { //type has a name.
- return n;
- }
- }
-
- /* /\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\ */
-
- static check_over (type_node* n)
- {
- while (n) {
- type_node* p= n->secondary();
- switch (n->primary) {
- case type_pointer:
- case type_reference:
- if (!n->isNear() && !n->isFar()) { //fill in default
- if (p->primary == type_function)
- n->flags |= (memory_model & 1) ? 8 : 4;
- else //data pointer
- n->flags |= (memory_model & 2) ? 8 : 4;
- }
- break;
- }
- n= p;
- }
- }
-
- /* /\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\ */
-
- static void check_over_1 (def_node* n)
- {
- if (n->storage_class == 0) {
- n->storage_class == (local_level) ? 4 /* auto */ : 2 /* extern */;
- }
- }
-
- /* /\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\ */
-
- void store_thing (type_node* t, atom name, int storage_class, int param, bool isfriend, int protect_mode)
- {
- /* 'param' is passed through from the grammar. If 1, this is a declaration
- for a local or global object. If 2, this is part of a parameter list */
- check_over (t);
- def_node* n= new def_node (name, storage_class, normalize_type(t));
-
- // file it away somewhere
- switch (param) {
- case 1: // top level definition
- if (name == -1) {
- // >> I need to get a standard error reporter
- cout << "abstract declarator ignored\n";
- }
- check_over_1 (n);
- global_stuff.add (n);
- break;
- case 2: // a parameter list
- // >> check it over
- p_list->l->add(n);
- break;
- case 3: // a class definition list
- if (isfriend) {
- // >> do something with it
- }
- else { //a member
- // >> check it over
- n->flags |= protect_mode;
- p_list->l->add(n);
- }
- break;
- }
- }
-
- /* /\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\ */
-
- void parameter_list (int x)
- {
- p_list_struct* p;
- if (x) {
- p= new p_list_struct;
- p->next= p_list;
- p->l= new def_node_list;
- p_list= p;
- }
- else {
- p= p_list;
- p_list= p_list->next;
- completed_def_list= p->l;
- delete p;
- }
- }
-
- /* /\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\ */
- /* /\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\ */
- /* /\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\ */
-
- void dump_types()
- {
- cout << "-----unnamed types-----\n";
- for (int loop= 0; loop < unnamed_types.size(); loop++) {
- unnamed_types[loop]->print();
- cout.put ('\n');
- }
- cout << "-----named types-----\n";
- for (loop= 0; loop < named_type_list->list.size(); loop++) {
- named_type_list->list[loop]->print();
- cout.put ('\n');
- }
-
- }
-
- /* /\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\ */
-
- extern "C" void cpp_setup();
- void cpp_setup()
- {
- named_type_list= new local_type_list;
- }
-
- /* /\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\ */
-