PreviousUpNext

15.4.206  src/lib/c-kit/src/parser/grammar/tdefs.pkg

## tdefs.pkg

# Compiled by:
#     src/lib/c-kit/src/parser/c-parser.sublib

###                      "God may not play dice with the universe,
###                       but something strange is going on
###                       with the prime numbers."
###
###                                         -- Paul Erdos



api Type_Defs {

    add_tdef: String -> Void;    #  A string as a typename in current scope 
    add_no_tdef: String -> Void; #  A string is not a typename, 
                                 #    may hide typenames of outer scopes
    check_tdef: String -> Bool;  #  is this string a typename in current context ? 
    reset: Void -> Void;         #  Clear all tables, needed if you are doing many files 
    trunc_to: Ref( Int );           #  limited-width names ? 
    push_scope: Void -> Void;    #  entering a new scope in C 
    pop_scope: Void -> Void;     #  exiting the last scope 
}; 



# We need a stack of tables to properly handle the scoping in typenames
# Remember, there are four type of things competing in the namespace of
# typenames:
#   typenames, variables, functions and enum constants
# Once you enter a new scope, reuse of these names can hide previous
# uses.
# Also note that struct field names do not redefine names within their scope
# So, the following is legal:
#    typedef int bar;
#    struct h {
#      bar bar;
#      bar baz;
#    };



stipulate
    package qht = quickstring_hashtable;                        # quickstring_hashtable         is from   src/lib/src/quickstring-hashtable.pkg
herein

    package   type_defs
    : (weak)  Type_Defs                                         # Type_Defs                     is from   src/lib/c-kit/src/parser/grammar/tdefs.pkg
    {
        package parse_control= config::parse_control;           # config                        is from   src/lib/c-kit/src/variants/ansi-c/config.pkg

        exception NOT_TYPE_DEF;

        my trunc_to: Ref( Int )
                  = REF parse_control::symbol_length;

        Item = Bool;         #  TRUE says typename, FALSE says else 

        my say_tdefs:  Ref( Bool )
                    = REF TRUE;

        my tdef_table:  Ref( List( qht::Hashtable( Item ) ) )
                    = REF ([qht::make_hashtable  { size_hint => 1024,  not_found_exception => NOT_TYPE_DEF }]);

        fun check_tdef (str)
            =
            {   s = substring (str, 0, *trunc_to) except substring = str;
                #
                name = quickstring__premicrothread::from_string s;

                fun lookup (n, NIL)
                        =>
                        NULL;

                    lookup (n, fst ! rst)
                        => 
                        case (qht::find fst n)   
                            THE x => THE (x);
                            _     => (lookup (n, rst));
                        esac;
                end;

                case (lookup (name, *tdef_table))

                     THE TRUE  => *say_tdefs;
                     THE FALSE => FALSE;
                     NULL      => FALSE;
                esac;
            };


        fun push_scope ()
            =
            {   tdef_table := (qht::make_hashtable  { size_hint => 1024,  not_found_exception => NOT_TYPE_DEF }) ! *tdef_table;
                ();
            };

        fun pop_scope ()   #  was just tl *tdefTable, but caused problems with mythryl-yacc error correction 
            =
            case *tdef_table
                [x]     => ();  #  Don't change 
                (_ ! l) => (tdef_table := l);
               NIL      => ();
            esac;
            #
            # Don't change; but we are in trouble here! 

        error_count = REF 0;

        fun reset ()
            =
            {   tdef_table  :=  [qht::make_hashtable  { size_hint => 1024,  not_found_exception => NOT_TYPE_DEF }];

                error_count :=  0;
            };

        # TBD: In the next two functions,
        # it is an option to raise exception
        # a syntax error, if there is a
        # redefinition in the same scope,
        # i.e., the topmost table     XXX BUGGO FIXME

        fun add_tdef  str
            = 
            {   s = substring (str, 0, *trunc_to)
                except
                    substring = str;

                name = quickstring__premicrothread::from_string s;

                # Insert name in the top
                # of tdefTable as a typename 
                #
                case *tdef_table

                     x ! _ => qht::set x (name, TRUE);

                     NIL => {   if (*error_count == 0)
                                     print "Error: empty type def table (lexer), probably caused by syntax error"; 
                                     #  should be error::error, but don't have an error stream handy.   XXX BUGGO FIXME
                                fi;

                                error_count := *error_count + 1;
                           };
                esac;
            };

        fun add_no_tdef (str)
            = 
            {
                s = substring (str, 0, *trunc_to)
                except
                    substring = str;

                name = quickstring__premicrothread::from_string s;

                # Insert name in the top of tdefTable as not a typename:
                #
                case *tdef_table

                     x ! _ => qht::set x (name, FALSE);

                     NIL   => {   if (*error_count == 0)

                                       print "Error: empty type def table (lexer), probably caused by syntax error"; 
                                       #  should be error::error, but don't have an error stream handy.    XXX BUGGO FIXME
                                  fi;

                                  error_count := *error_count + 1;
                              };
                esac;
            };
    };
end;


Comments and suggestions to: bugs@mythryl.org

PreviousUpNext