Presentation is loading. Please wait.

Presentation is loading. Please wait.

Symbol table lookup & install

Similar presentations


Presentation on theme: "Symbol table lookup & install"— Presentation transcript:

1 Symbol table lookup & install
Kei Hasegawa

2 Variables and literals in program text
struct scope { ... map<string, vector<usr*> > usrs; // Accessible symbol infomation form name };

3 map<string, vector<usr*> >
// Outside of function int i = 1; int i; // ok extern int i; // Of cause ok That's because chosing map<string, vector<usr*> > not map<string, usr*>

4 How backend deal with symbol table?
int i = 1; // (1) int i; // (2) extern int i; // (3) For these delarations, backend shall allocate 4 (=sizeof(int)) bytes with initial value `1' for `i'. For (2) declaration, it is not correct to allocate 4 bytes for `i' because multiple definition of `i'.

5 frontend function lookup()
// For string, return lexical kind by searching symbol table lex::kind_t lookup(string name, scope* ptr) { const map<string, vector<usr*> >& usrs = ptr->usrs; map<string, vector<usr*> >::const_iterator p = usrs.find(name); if ( p != usrs.end() ) { const vector<usr*>& v = p->second; usr* u = v.back(); // POINT : Reference to the last one ... } int i = 1; // (1) int i; // (2) extern int i; // (3) void f(void){ ... use i ... } // Reference to (3) declaration

6 How backend deal with symbol table?(2)
In function `gen' For (1), generate `i' space code with initial value For (2), generate `i' space code with no initial value For (3), just skip because of `extern' These are not correct because of multipe definition of `i' find_if(v.begin(), v.end(), gen); may works roughly. int i = 1; // (1) int i; // (2) extern int i; // (3) Implementation of backend const map<string, vector<usr*> >& usrs = ... for_each(usrs.begin(), usrs.end(), usr); void usr(const pair<string vector<usr*> >& p) { const vector<usr*>& v = p.second; for_each(v.begin(), v.end(), gen); }

7 How backend deal with symbol table?(3)
int i = 1; // (1) int i; // (2) void f(void){ ... use i ... } // Reference to not (1) but to (2). So backend have to decide address descriptor of (2) `i' declaration extern int i; void g(void){ ... use i ... } // Reference to (3) neither (1) or (2). Instad of code generation for some declarations, backend has to decide address descriptor for the last one. i.e: const vector<usr*>& v = p.second; find_if(v.begin(), v.end(), gen); decide_address_descriptor(v.back());

8 Install to the symbol table
void install(usr* curr, scope* ptr) { string name = curr->m_name; map<string, vector<usr*> >& usrs = ptr->m_usrs; map<string, vector<usr*> >::iterator p = usrs.find(name); if ( p != usrs.end() ) { vector<usr*>& v = p->second; usr* prev = v.back(); // Just compare with the last one if (!prev->m_type->compaitble(curr->m_type) || ... ) { // Eror. redeclaration. } else { curr->m_type = prev->m_type->composite(curr->m_type); usrs[name].push_back(curr);

9 Example void f(); // Register as void (...) void g() { }
f(1,2,3); // ok } void f(int); // ok. void (...) is compatible with void (int) // Register as composite type void (int) void h() { f(3); f(1,2,3); // error. void f(); // Once again! void (int) is compatible with void (...) // Register as composite type void (int) not void (...) void i() { f(1,2,3); // error


Download ppt "Symbol table lookup & install"

Similar presentations


Ads by Google