📄 variable.cpp
字号:
#include <alloc.h>
#include <stdio.h>
#include <conio.h>
#include <assert.h>
#include "InstInfo.h"
#include "Variable.h"
char VariableTypes[VAR_UNKNOWN+1][10] = {"char","int","long","void","proc",\
"proc","struct","union","typedef","int","unknown"};
int Variable::SameKind(Variable &v)
{
switch(Operand)
{
case OPER_UNKNOWN : return 0;
case REG_DIRECT :
case IMMEDIATE :
case MEMORY : return Operand==v.Operand;
// for other cases,...
default : return Operand==v.Operand && Data1==v.Data1;
}
}
int Variable::IsCVariable()
{
switch(Operand)
{
case REG_DIRECT : return 1; // for register variables.
case INDEXED_BYTE : case INDEXED_WORD : if (Data1!=INDX_BP) return 0;
case MEMORY : case IMMEDIATE : return 1;
default : return 0;
}
}
void Variable::operator = (Variable &v)
{
Operand=v.Operand;
Data1=v.Data1;
Data2=v.Data2;
}
Variable &Variable::operator - (int offset)
{
static Variable v;
v=*this;
switch(Operand)
{
case REG_DIRECT : break;
case MEMORY : v.Data1-=offset; break;
case INDEXED_BYTE :
case INDEXED_WORD :
if (v.Data1==INDX_BP) v.Data2-=offset;
break;
default : assert("Address of variable"!="Supported mode");
}
return v;
}
int Variable::operator == (Variable &v)
{
return (Operand==v.Operand && Data1==v.Data1 && Data2==v.Data2);
}
Word Variable::GetAddress()
{
switch(Operand)
{
case MEMORY : return Data1;
case INDEXED_BYTE :
case INDEXED_WORD :
if (Data1==INDX_BP) return Data2;
return 0;
case REG_DIRECT : return 0;
default : assert("Address of variable"!="Supported mode");
}
return 0;
}
Variable::operator char *()
{
InstInfo inst;
inst.SetVariable(*this,2);
String tt;
static char tname[10];
tname[0]=0;
switch(Operand)
{
case MEMORY :
case INDEXED_BYTE :
case INDEXED_WORD :
strcpy(tname,(char *)inst.GetOperand2(NULL,NULL)); break;
case IMMEDIATE : // variable is containing address of a function.
tt=(Word)Data2;
strcpy(tname,(char *)tt);
strcat(tname,":"); tt=(Word)Data1;
strcat(tname,(char *)tt); break;
}
return tname;
}
VariableList::VariableList()
{
Data.Operand=OPER_UNKNOWN;
Next=NULL;
}
VariableList::~VariableList()
{
Data.Operand=OPER_UNKNOWN;
if (Next) delete Next;
Next=NULL;
}
void VariableList::Display()
{
VariableList *ptr=this;
while(ptr && ptr->Data.Operand!=OPER_UNKNOWN)
{
printf("%s is %s of type %s\n",(char *)ptr->Data,ptr->Name,VariableTypes[ptr->Type]);
ptr=ptr->Next;
}
}
void VariableList::Add(Variable &v,int _type,int _size,char *_name,int _readonly)
{
if (!v.IsCVariable()) return;
VariableList *ptr=this;
while(ptr->Data.Operand!=OPER_UNKNOWN)
{
// If the same variable is present, just replace the type, name, etc.
if (ptr->Data==v)
{
if (ptr->readOnly) return;
break;
}
if (ptr->Next==NULL)
{
ptr->Next = new VariableList;
assert(ptr);
ptr = ptr->Next;
break;
}
ptr=ptr->Next;
}
ptr->Data=v;
ptr->Type=_type;
ptr->Size=_size;
if (_name) strcpy(ptr->Name,_name);
else strcpy(ptr->Name,"");
readOnly=_readonly;
}
int VariableList::GetType(Variable &v)
{
VariableList *ptr=this;
while(ptr!=NULL && ptr->Data.Operand!=OPER_UNKNOWN)
{
if (ptr->Data==v) return ptr->Type;
ptr=ptr->Next;
}
return VAR_UNKNOWN;
}
void VariableList::Del(Variable &v)
{
VariableList *ptr=this;
VariableList *parent=this;
if (Data==v)
{
if (readOnly) return;
if (Next)
{
memcpy(this,Next,sizeof(VariableList));
ptr=ptr->Next;
}
else
{
Data.Operand=OPER_UNKNOWN; return;
}
} else ptr=ptr->Next;
do
{
while(ptr!=NULL && ptr->Data.Operand!=OPER_UNKNOWN)
{
if (ptr->Data==v)
{
if (ptr->readOnly) return;
break;
}
parent=ptr;
ptr=ptr->Next;
}
if (ptr!=NULL && ptr->Data.Operand!=OPER_UNKNOWN)
{
parent->Next=ptr->Next;
ptr->Next=NULL;
delete ptr;
ptr=parent->Next;
}
}while(ptr!=NULL && ptr->Data.Operand!=OPER_UNKNOWN);
}
char *VariableList::GetName(Variable &v,int _type)
{
VariableList *ptr=this;
while(ptr!=NULL && ptr->Data.Operand!=OPER_UNKNOWN)
{
if (ptr->Data==v)
{
// check Type only if requested to.
if (_type>=0 && _type!=Type) goto checknext;
if (strcmp(ptr->Name,"")==0) return NULL;
return ptr->Name;
}
checknext:
ptr=ptr->Next;
}
return NULL;
}
int VariableList::IsPresent(Variable &v,int _type)
{
VariableList *ptr=this;
while(ptr!=NULL && ptr->Data.Operand!=OPER_UNKNOWN)
{
if (ptr->Data==v)
{
// check Type only if requested to.
if (_type>=0 && _type!=Type) continue;
return 1;
}
ptr=ptr->Next;
}
return 0;
}
void VariableList::MakeAllReadOnly()
{
VariableList *ptr=this;
while(ptr!=NULL && ptr->Data.Operand!=OPER_UNKNOWN)
{
ptr->readOnly=1;
ptr=ptr->Next;
}
}
int VariableList::PartOfAnyVariable(Variable &v1,Variable &v2,int &v2Type)
{
VariableList *ptr=this;
while(ptr && ptr->Data.Operand!=OPER_UNKNOWN)
{
if (ptr->Data.SameKind(v1))
{
Word addr2 = ptr->Data.GetAddress();
Word addr1 = v1.GetAddress();
// does the given variable's address fall in the range of this variable's
// address range?
addr1+=1000; addr2+=1000; // 1000 = BP(assumed).
if (addr1==addr2 || (addr2<=addr1 && addr2+ptr->Size>addr1))
{
v2=ptr->Data;
v2Type=ptr->Type;
return 1;
}
}
ptr=ptr->Next;
}
return 0;
}
void VariableList::NameUnknownVariables()
{
char prefix[3];
VariableList *ptr=this;
int Counters[VAR_UNKNOWN]; // VAR_UNKNOWN must be the last index
// in the enum list, hence has the
// size of the list.
for(int i=0;i<VAR_UNKNOWN;i++) Counters[i]=1;
prefix[1]='_'; prefix[2]=0;
while(ptr && ptr->Data.Operand!=OPER_UNKNOWN)
{
if (strcmp(ptr->Name,"")==0)
{
switch(ptr->Data.Operand)
{
// Entry for any known function.
case IMMEDIATE : prefix[0]='g'; break;
case MEMORY : prefix[0]='g'; break;
// for register variables.
case REG_DIRECT : prefix[0]='r'; break;
case REG_INDIRECT:
case INDEXED_BYTE:
case INDEXED_WORD: if (ptr->Data.Data1==INDX_BP)
prefix[0]=(ptr->Data.Data2<=0)?'l':'p';
}
strcpy(ptr->Name,prefix);
strcat(ptr->Name,VariableTypes[ptr->Type]);
strcat(ptr->Name,"_");
itoa(Counters[ptr->Type],EndOf(ptr->Name),10);
Counters[ptr->Type]++;
}
else
{
// check for similar existing entries like l_int_1, and increment
// the appropriate counter.
for(int i=0;i<VAR_UNKNOWN;i++)
if (ptr->Name[1]=='_' &&
strncmp(ptr->Name+2,VariableTypes[i],strlen(VariableTypes[i]))==0)
Counters[i]++;
}
ptr=ptr->Next;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -