📄 scope.cpp
字号:
/*
* File: scope.cc
* --------------
* Our version has a ScopeStack class which maintains an stack of Scope
* objects using an array. Each Scope object tracks its own hashtable and
* may have additional information about the particulars for this
* scope (class, fn, global, etc.)
*/
#include "scope.h"
#include "declaration.h"
#include "hashtable.h"
#include "type.h"
#include "semantic.h"
#include "typelist.h"
#include "decllist.h"
/* Class: Scope
* ------------
* Each level in the ScopeStack is a Scope object. Scope objects are
* largely just a hashtable, but there are a few other bits of information
* tracked for special scopes (the class type for class scopes, the return
* type for a function scope, etc.)
*/
/* Scope constructors
* ------------------
* There are several variations for constructing different types of scopes.
*/
Scope::Scope(KindOfScope s)
{
scopeCode = s;
table = new Hashtable;
// maxVarCount=0;
}
/* Scope ctor used for function scopes. Takes the parameter list from the fn
* type and declares all of the parameters into this scope.
*/
Scope::Scope(Declaration *fn)
{
Assert(fn->IsFunctionDecl());
scopeCode = Function;
table = new Hashtable;
DeclList *formals = fn->GetType()->GetFnFormals();
for (int i = 0; i < formals->NumElements(); i++)
Declare(formals->Nth(i));
}
/* Scope ctor used for class scopes. Not too much special about
* these, but we do record the classType for later use in semantic
* analysis (checking accessibility of fields, etc.).
*/
Scope::Scope(Type *type)
{
Assert(type->IsClassType());
scopeCode = Class;
table = new Hashtable;
classType = type;
}
/* Method: Lookup
* --------------
* Looks for an identifier in this scope only. Returns NULL if
* not found.
*/
Declaration *Scope::Lookup(const char *identifier)
{
return table->Lookup(identifier);
}
/* Method: Declare
* ---------------
* Adds an identifier to this scope and sets scope on declaration.
*/
bool Scope::Declare(Declaration *decl)
{
const char *identifier = decl->GetName();
table->Enter(identifier, decl);
decl->SetScope(this);
return true;
}
Type *Scope::GetClassType()
{
Assert(IsClassScope());
return classType;
}
/* CopyFieldsFromParent
* --------------------
* Helper to copy parent fields into subclass table. Uses an iterator to
* walk scope's hashtable and uses copy ctor to make a new heap copy
* that is identical.
*/
void Scope::CopyFieldsFromParent(Scope *parent)
{
Assert(IsClassScope() && parent->IsClassScope());
Declaration *decl;
decl = parent->table->FirstDecla();
while (decl != NULL) {
if(!strcmp(decl->GetName(),"New"))
{
decl = parent->table->NextDecla();
continue;
}
Declaration *copy = new Declaration(*decl); // use copy ctor
table->Enter(copy->GetName(), copy);
decl = parent->table->NextDecla();
}
}
/* Class: ScopeStack
* -----------------
* Very simple implementation using a fixed-size array.
*/
ScopeStack::ScopeStack()
{
top = -1;
PushScope(new Scope(Scope::Global)); // create and push global scope
}
/* Method: Lookup
* --------------
* Returns Declaration associated with identifier in closest open scope
* The optional second parameter specifies Shallow (just topmost scope)
* or Deep, all the way to bottom of stack. The default is Deep.
*/
Declaration *ScopeStack::Lookup(const char *identifier, TypeOfLookup lk)
{
for (int i = top; i >= 0; i--)
{
Declaration *found = stack[i]->Lookup(identifier);
if (found) return found;
if (lk == Shallow) break; // Shallow stops after looking in top-most scope
}
return NULL;
}
/* Method: Declare
* ---------------
* Add a Declaration into the topmost scope.
*/
bool ScopeStack::Declare(Declaration *decl)
{
Assert(top >= 0);
return stack[top]->Declare(decl);
}
/* Method: PushScope
* -----------------
* Push a newly created scope onto scope stack at top.
*/
void ScopeStack::PushScope(Scope *scope)
{
Assert(top < MaxNest - 1);
stack[++top] = scope;
}
/* Method: PopScope
* ----------------
* Pop topmost scope from stack
*/
void ScopeStack::PopScope()
{
Assert(top >= 0);
top--;
}
/* Method: GetCurrentScope
* ----------------------
* Return scope currently on top of stack.
*/
Scope *ScopeStack::GetCurrentScope()
{
Assert(top >= 0);
return stack[top];
}
//新添加函数
Declaration * Scope::FirstDecla()
{
return table->FirstDecla();
}
Declaration * Scope::NextDecla()
{
return table->NextDecla();
}
//找到class scope返回指向他的指针,否则返回NULL
Scope * ScopeStack::GetClassScope()
{
Assert(top >= 0);
for(int i=top; i>=0; i--)
{
if(stack[i]->IsClassScope())
{
return stack[i];
}
}
return NULL;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -