Add union
This commit is contained in:
parent
82d499fdae
commit
8031ad8dee
|
@ -2852,6 +2852,8 @@ ByteCodeProcedure::~ByteCodeProcedure(void)
|
||||||
|
|
||||||
void ByteCodeProcedure::Compile(ByteCodeGenerator* generator, InterCodeProcedure* proc)
|
void ByteCodeProcedure::Compile(ByteCodeGenerator* generator, InterCodeProcedure* proc)
|
||||||
{
|
{
|
||||||
|
mID = proc->mID;
|
||||||
|
|
||||||
tblocks = new ByteCodeBasicBlock * [proc->mBlocks.Size()];
|
tblocks = new ByteCodeBasicBlock * [proc->mBlocks.Size()];
|
||||||
for (int i = 0; i < proc->mBlocks.Size(); i++)
|
for (int i = 0; i < proc->mBlocks.Size(); i++)
|
||||||
tblocks[i] = nullptr;
|
tblocks[i] = nullptr;
|
||||||
|
|
|
@ -241,7 +241,7 @@ public:
|
||||||
ByteCodeBasicBlock * entryBlock, * exitBlock;
|
ByteCodeBasicBlock * entryBlock, * exitBlock;
|
||||||
ByteCodeBasicBlock ** tblocks;
|
ByteCodeBasicBlock ** tblocks;
|
||||||
|
|
||||||
int mProgStart, mProgSize;
|
int mProgStart, mProgSize, mID;
|
||||||
|
|
||||||
void Compile(ByteCodeGenerator* generator, InterCodeProcedure* proc);
|
void Compile(ByteCodeGenerator* generator, InterCodeProcedure* proc);
|
||||||
ByteCodeBasicBlock * CompileBlock(InterCodeProcedure* iproc, InterCodeBasicBlock* block);
|
ByteCodeBasicBlock * CompileBlock(InterCodeProcedure* iproc, InterCodeBasicBlock* block);
|
||||||
|
|
|
@ -59,6 +59,7 @@ bool Compiler::GenerateCode(void)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mInterCodeGenerator->mForceNativeCode = mNativeCode;
|
||||||
mInterCodeGenerator->TranslateAssembler(mInterCodeModule, dcrtstart->mValue);
|
mInterCodeGenerator->TranslateAssembler(mInterCodeModule, dcrtstart->mValue);
|
||||||
|
|
||||||
if (mErrors->mErrorCount != 0)
|
if (mErrors->mErrorCount != 0)
|
||||||
|
@ -95,9 +96,6 @@ bool Compiler::GenerateCode(void)
|
||||||
|
|
||||||
proc->ReduceTemporaries();
|
proc->ReduceTemporaries();
|
||||||
|
|
||||||
if (mNativeCode)
|
|
||||||
proc->mNativeProcedure = true;
|
|
||||||
|
|
||||||
#if _DEBUG
|
#if _DEBUG
|
||||||
proc->Disassemble("final");
|
proc->Disassemble("final");
|
||||||
#endif
|
#endif
|
||||||
|
@ -279,7 +277,7 @@ bool Compiler::WriteOutputFile(const char* targetPath)
|
||||||
if (file)
|
if (file)
|
||||||
{
|
{
|
||||||
for (int i = 0; i < mByteCodeFunctions.Size(); i++)
|
for (int i = 0; i < mByteCodeFunctions.Size(); i++)
|
||||||
mByteCodeFunctions[i]->Disassemble(file, mByteCodeGenerator, mInterCodeModule->mProcedures[i]);
|
mByteCodeFunctions[i]->Disassemble(file, mByteCodeGenerator, mInterCodeModule->mProcedures[mByteCodeFunctions[i]->mID]);
|
||||||
|
|
||||||
mByteCodeGenerator->WriteAsmFile(file);
|
mByteCodeGenerator->WriteAsmFile(file);
|
||||||
|
|
||||||
|
|
|
@ -359,7 +359,7 @@ bool Declaration::IsSubType(const Declaration* dec) const
|
||||||
return true;
|
return true;
|
||||||
else if (mType == DT_TYPE_BOOL || mType == DT_TYPE_FLOAT || mType == DT_TYPE_VOID)
|
else if (mType == DT_TYPE_BOOL || mType == DT_TYPE_FLOAT || mType == DT_TYPE_VOID)
|
||||||
return true;
|
return true;
|
||||||
else if (mType == DT_TYPE_STRUCT || mType == DT_TYPE_ENUM)
|
else if (mType == DT_TYPE_STRUCT || mType == DT_TYPE_ENUM || DT_TYPE_UNION)
|
||||||
return false;
|
return false;
|
||||||
else if (mType == DT_TYPE_POINTER || mType == DT_TYPE_ARRAY)
|
else if (mType == DT_TYPE_POINTER || mType == DT_TYPE_ARRAY)
|
||||||
return mBase->IsSubType(dec->mBase);
|
return mBase->IsSubType(dec->mBase);
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
#include <crtdbg.h>
|
#include <crtdbg.h>
|
||||||
|
|
||||||
InterCodeGenerator::InterCodeGenerator(Errors* errors)
|
InterCodeGenerator::InterCodeGenerator(Errors* errors)
|
||||||
: mErrors(errors)
|
: mErrors(errors), mForceNativeCode(false)
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -539,7 +539,7 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
|
||||||
if (vl.mType->mFlags & DTF_CONST)
|
if (vl.mType->mFlags & DTF_CONST)
|
||||||
mErrors->Error(exp->mLocation, "Cannot assign to const type");
|
mErrors->Error(exp->mLocation, "Cannot assign to const type");
|
||||||
|
|
||||||
if (vl.mType->mType == DT_TYPE_STRUCT || vl.mType->mType == DT_TYPE_ARRAY)
|
if (vl.mType->mType == DT_TYPE_STRUCT || vl.mType->mType == DT_TYPE_ARRAY || vl.mType->mType == DT_TYPE_UNION)
|
||||||
{
|
{
|
||||||
vr = Dereference(proc, block, vr, 1);
|
vr = Dereference(proc, block, vr, 1);
|
||||||
vl = Dereference(proc, block, vl, 1);
|
vl = Dereference(proc, block, vl, 1);
|
||||||
|
@ -2242,6 +2242,9 @@ InterCodeProcedure* InterCodeGenerator::TranslateProcedure(InterCodeModule * mod
|
||||||
InterCodeProcedure* proc = new InterCodeProcedure(mod, dec->mLocation, dec->mIdent);
|
InterCodeProcedure* proc = new InterCodeProcedure(mod, dec->mLocation, dec->mIdent);
|
||||||
dec->mVarIndex = proc->mID;
|
dec->mVarIndex = proc->mID;
|
||||||
|
|
||||||
|
if (mForceNativeCode)
|
||||||
|
dec->mFlags |= DTF_NATIVE;
|
||||||
|
|
||||||
if (dec->mFlags & DTF_NATIVE)
|
if (dec->mFlags & DTF_NATIVE)
|
||||||
proc->mNativeProcedure = true;
|
proc->mNativeProcedure = true;
|
||||||
|
|
||||||
|
|
|
@ -19,6 +19,7 @@ public:
|
||||||
{}
|
{}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
bool mForceNativeCode;
|
||||||
|
|
||||||
InterCodeProcedure* TranslateProcedure(InterCodeModule* mod, Expression* exp, Declaration * dec);
|
InterCodeProcedure* TranslateProcedure(InterCodeModule* mod, Expression* exp, Declaration * dec);
|
||||||
void TranslateAssembler(InterCodeModule* mod, Expression * exp);
|
void TranslateAssembler(InterCodeModule* mod, Expression * exp);
|
||||||
|
|
|
@ -15,6 +15,92 @@ Parser::~Parser(void)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Declaration* Parser::ParseStructDeclaration(uint32 flags, DecType dt)
|
||||||
|
{
|
||||||
|
const Ident* structName = nullptr;
|
||||||
|
|
||||||
|
Declaration * dec = new Declaration(mScanner->mLocation, dt);
|
||||||
|
|
||||||
|
mScanner->NextToken();
|
||||||
|
if (mScanner->mToken == TK_IDENT)
|
||||||
|
{
|
||||||
|
structName = mScanner->mTokenIdent;
|
||||||
|
mScanner->NextToken();
|
||||||
|
Declaration* pdec = mScope->Insert(structName, dec);
|
||||||
|
if (pdec)
|
||||||
|
{
|
||||||
|
if (pdec->mType == dt && (pdec->mFlags & DTF_DEFINED))
|
||||||
|
{
|
||||||
|
dec = pdec;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mErrors->Error(mScanner->mLocation, "Error duplicate struct declaration", structName->mString);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
dec->mIdent = structName;
|
||||||
|
dec->mScope = new DeclarationScope(nullptr);
|
||||||
|
|
||||||
|
if (mScanner->mToken == TK_OPEN_BRACE)
|
||||||
|
{
|
||||||
|
mScanner->NextToken();
|
||||||
|
Declaration* mlast = nullptr;
|
||||||
|
for (;;)
|
||||||
|
{
|
||||||
|
Declaration* mdec = ParseDeclaration(false);
|
||||||
|
while (mdec)
|
||||||
|
{
|
||||||
|
if (!(mdec->mBase->mFlags & DTF_DEFINED))
|
||||||
|
mErrors->Error(mdec->mLocation, "Undefined type used in struct member declaration");
|
||||||
|
mdec->mType = DT_ELEMENT;
|
||||||
|
if (dt == DT_TYPE_UNION)
|
||||||
|
{
|
||||||
|
mdec->mOffset = 0;
|
||||||
|
if (mdec->mBase->mSize > dec->mSize)
|
||||||
|
dec->mSize = mdec->mBase->mSize;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mdec->mOffset = dec->mSize;
|
||||||
|
dec->mSize += mdec->mBase->mSize;
|
||||||
|
}
|
||||||
|
dec->mScope->Insert(mdec->mIdent, mdec);
|
||||||
|
if (mlast)
|
||||||
|
mlast->mNext = mdec;
|
||||||
|
else
|
||||||
|
dec->mParams = mdec;
|
||||||
|
mlast = mdec;
|
||||||
|
mdec = mdec->mNext;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mScanner->mToken == TK_SEMICOLON)
|
||||||
|
mScanner->NextToken();
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mErrors->Error(mScanner->mLocation, "';' expected");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mScanner->mToken == TK_CLOSE_BRACE)
|
||||||
|
{
|
||||||
|
mScanner->NextToken();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mlast)
|
||||||
|
mlast->mNext = nullptr;
|
||||||
|
else
|
||||||
|
dec->mParams = nullptr;
|
||||||
|
|
||||||
|
dec->mFlags |= DTF_DEFINED;
|
||||||
|
}
|
||||||
|
|
||||||
|
return dec;
|
||||||
|
}
|
||||||
|
|
||||||
Declaration* Parser::ParseBaseTypeDeclaration(uint32 flags)
|
Declaration* Parser::ParseBaseTypeDeclaration(uint32 flags)
|
||||||
{
|
{
|
||||||
Declaration* dec = nullptr;
|
Declaration* dec = nullptr;
|
||||||
|
@ -176,81 +262,11 @@ Declaration* Parser::ParseBaseTypeDeclaration(uint32 flags)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case TK_STRUCT:
|
case TK_STRUCT:
|
||||||
{
|
dec = ParseStructDeclaration(flags, DT_TYPE_STRUCT);
|
||||||
const Ident* structName = nullptr;
|
break;
|
||||||
|
case TK_UNION:
|
||||||
dec = new Declaration(mScanner->mLocation, DT_TYPE_STRUCT);
|
dec = ParseStructDeclaration(flags, DT_TYPE_UNION);
|
||||||
|
|
||||||
mScanner->NextToken();
|
|
||||||
if (mScanner->mToken == TK_IDENT)
|
|
||||||
{
|
|
||||||
structName = mScanner->mTokenIdent;
|
|
||||||
mScanner->NextToken();
|
|
||||||
Declaration * pdec = mScope->Insert(structName, dec);
|
|
||||||
if (pdec)
|
|
||||||
{
|
|
||||||
if (pdec->mType == DT_TYPE_STRUCT && (pdec->mFlags & DTF_DEFINED))
|
|
||||||
{
|
|
||||||
dec = pdec;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
mErrors->Error(mScanner->mLocation, "Error duplicate struct declaration", structName->mString);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
dec->mIdent = structName;
|
|
||||||
dec->mScope = new DeclarationScope(nullptr);
|
|
||||||
|
|
||||||
if (mScanner->mToken == TK_OPEN_BRACE)
|
|
||||||
{
|
|
||||||
mScanner->NextToken();
|
|
||||||
Declaration* mlast = nullptr;
|
|
||||||
for (;;)
|
|
||||||
{
|
|
||||||
Declaration* mdec = ParseDeclaration(false);
|
|
||||||
while (mdec)
|
|
||||||
{
|
|
||||||
if (!(mdec->mBase->mFlags & DTF_DEFINED))
|
|
||||||
mErrors->Error(mdec->mLocation, "Undefined type used in struct member declaration");
|
|
||||||
mdec->mType = DT_ELEMENT;
|
|
||||||
mdec->mOffset = dec->mSize;
|
|
||||||
dec->mSize += mdec->mBase->mSize;
|
|
||||||
dec->mScope->Insert(mdec->mIdent, mdec);
|
|
||||||
if (mlast)
|
|
||||||
mlast->mNext = mdec;
|
|
||||||
else
|
|
||||||
dec->mParams = mdec;
|
|
||||||
mlast = mdec;
|
|
||||||
mdec = mdec->mNext;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (mScanner->mToken == TK_SEMICOLON)
|
|
||||||
mScanner->NextToken();
|
|
||||||
else
|
|
||||||
{
|
|
||||||
mErrors->Error(mScanner->mLocation, "';' expected");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (mScanner->mToken == TK_CLOSE_BRACE)
|
|
||||||
{
|
|
||||||
mScanner->NextToken();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (mlast)
|
|
||||||
mlast->mNext = nullptr;
|
|
||||||
else
|
|
||||||
dec->mParams = nullptr;
|
|
||||||
|
|
||||||
dec->mFlags |= DTF_DEFINED;
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
|
|
||||||
default:
|
default:
|
||||||
mErrors->Error(mScanner->mLocation, "Declaration starts with invalid token", TokenNames[mScanner->mToken]);
|
mErrors->Error(mScanner->mLocation, "Declaration starts with invalid token", TokenNames[mScanner->mToken]);
|
||||||
mScanner->NextToken();
|
mScanner->NextToken();
|
||||||
|
@ -491,7 +507,7 @@ Expression* Parser::ParseInitExpression(Declaration* dtype)
|
||||||
Expression* exp = nullptr;
|
Expression* exp = nullptr;
|
||||||
Declaration* dec;
|
Declaration* dec;
|
||||||
|
|
||||||
if (dtype->mType == DT_TYPE_ARRAY || dtype->mType == DT_TYPE_STRUCT)
|
if (dtype->mType == DT_TYPE_ARRAY || dtype->mType == DT_TYPE_STRUCT || dtype->mType == DT_TYPE_UNION)
|
||||||
{
|
{
|
||||||
if (!(dtype->mFlags & DTF_DEFINED))
|
if (!(dtype->mFlags & DTF_DEFINED))
|
||||||
{
|
{
|
||||||
|
@ -813,6 +829,7 @@ Expression* Parser::ParseSimpleExpression(void)
|
||||||
case TK_CONST:
|
case TK_CONST:
|
||||||
case TK_VOLATILE:
|
case TK_VOLATILE:
|
||||||
case TK_STRUCT:
|
case TK_STRUCT:
|
||||||
|
case TK_UNION:
|
||||||
case TK_TYPEDEF:
|
case TK_TYPEDEF:
|
||||||
case TK_STATIC:
|
case TK_STATIC:
|
||||||
exp = ParseDeclarationExpression();
|
exp = ParseDeclarationExpression();
|
||||||
|
@ -1058,7 +1075,7 @@ Expression* Parser::ParsePostfixExpression(void)
|
||||||
dexp->mDecType = exp->mDecType->mBase;
|
dexp->mDecType = exp->mDecType->mBase;
|
||||||
dexp->mLeft = exp;
|
dexp->mLeft = exp;
|
||||||
|
|
||||||
if (dexp->mDecType->mType == DT_TYPE_STRUCT)
|
if (dexp->mDecType->mType == DT_TYPE_STRUCT || dexp->mDecType->mType == DT_TYPE_UNION)
|
||||||
{
|
{
|
||||||
Expression* nexp = new Expression(mScanner->mLocation, EX_QUALIFY);
|
Expression* nexp = new Expression(mScanner->mLocation, EX_QUALIFY);
|
||||||
nexp->mLeft = dexp;
|
nexp->mLeft = dexp;
|
||||||
|
@ -1087,7 +1104,7 @@ Expression* Parser::ParsePostfixExpression(void)
|
||||||
else if (mScanner->mToken == TK_DOT)
|
else if (mScanner->mToken == TK_DOT)
|
||||||
{
|
{
|
||||||
mScanner->NextToken();
|
mScanner->NextToken();
|
||||||
if (exp->mDecType->mType == DT_TYPE_STRUCT)
|
if (exp->mDecType->mType == DT_TYPE_STRUCT || exp->mDecType->mType == DT_TYPE_UNION)
|
||||||
{
|
{
|
||||||
Expression* nexp = new Expression(mScanner->mLocation, EX_QUALIFY);
|
Expression* nexp = new Expression(mScanner->mLocation, EX_QUALIFY);
|
||||||
nexp->mLeft = exp;
|
nexp->mLeft = exp;
|
||||||
|
|
|
@ -23,6 +23,7 @@ protected:
|
||||||
|
|
||||||
Declaration* ParseBaseTypeDeclaration(uint32 flags);
|
Declaration* ParseBaseTypeDeclaration(uint32 flags);
|
||||||
Declaration* ParseDeclaration(bool variable);
|
Declaration* ParseDeclaration(bool variable);
|
||||||
|
Declaration* ParseStructDeclaration(uint32 flags, DecType dt);
|
||||||
|
|
||||||
Declaration* CopyConstantInitializer(int offset, Declaration* dtype, Expression* exp);
|
Declaration* CopyConstantInitializer(int offset, Declaration* dtype, Expression* exp);
|
||||||
Expression* ParseInitExpression(Declaration* dtype);
|
Expression* ParseInitExpression(Declaration* dtype);
|
||||||
|
|
Loading…
Reference in New Issue