Add union

This commit is contained in:
drmortalwombat 2021-09-12 10:04:37 +02:00
parent 82d499fdae
commit 8031ad8dee
8 changed files with 107 additions and 85 deletions

View File

@ -2852,6 +2852,8 @@ ByteCodeProcedure::~ByteCodeProcedure(void)
void ByteCodeProcedure::Compile(ByteCodeGenerator* generator, InterCodeProcedure* proc)
{
mID = proc->mID;
tblocks = new ByteCodeBasicBlock * [proc->mBlocks.Size()];
for (int i = 0; i < proc->mBlocks.Size(); i++)
tblocks[i] = nullptr;

View File

@ -241,7 +241,7 @@ public:
ByteCodeBasicBlock * entryBlock, * exitBlock;
ByteCodeBasicBlock ** tblocks;
int mProgStart, mProgSize;
int mProgStart, mProgSize, mID;
void Compile(ByteCodeGenerator* generator, InterCodeProcedure* proc);
ByteCodeBasicBlock * CompileBlock(InterCodeProcedure* iproc, InterCodeBasicBlock* block);

View File

@ -59,6 +59,7 @@ bool Compiler::GenerateCode(void)
return false;
}
mInterCodeGenerator->mForceNativeCode = mNativeCode;
mInterCodeGenerator->TranslateAssembler(mInterCodeModule, dcrtstart->mValue);
if (mErrors->mErrorCount != 0)
@ -95,9 +96,6 @@ bool Compiler::GenerateCode(void)
proc->ReduceTemporaries();
if (mNativeCode)
proc->mNativeProcedure = true;
#if _DEBUG
proc->Disassemble("final");
#endif
@ -279,7 +277,7 @@ bool Compiler::WriteOutputFile(const char* targetPath)
if (file)
{
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);

View File

@ -359,7 +359,7 @@ bool Declaration::IsSubType(const Declaration* dec) const
return true;
else if (mType == DT_TYPE_BOOL || mType == DT_TYPE_FLOAT || mType == DT_TYPE_VOID)
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;
else if (mType == DT_TYPE_POINTER || mType == DT_TYPE_ARRAY)
return mBase->IsSubType(dec->mBase);

View File

@ -2,7 +2,7 @@
#include <crtdbg.h>
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)
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);
vl = Dereference(proc, block, vl, 1);
@ -2242,6 +2242,9 @@ InterCodeProcedure* InterCodeGenerator::TranslateProcedure(InterCodeModule * mod
InterCodeProcedure* proc = new InterCodeProcedure(mod, dec->mLocation, dec->mIdent);
dec->mVarIndex = proc->mID;
if (mForceNativeCode)
dec->mFlags |= DTF_NATIVE;
if (dec->mFlags & DTF_NATIVE)
proc->mNativeProcedure = true;

View File

@ -19,6 +19,7 @@ public:
{}
};
bool mForceNativeCode;
InterCodeProcedure* TranslateProcedure(InterCodeModule* mod, Expression* exp, Declaration * dec);
void TranslateAssembler(InterCodeModule* mod, Expression * exp);

View File

@ -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* dec = nullptr;
@ -176,81 +262,11 @@ Declaration* Parser::ParseBaseTypeDeclaration(uint32 flags)
break;
}
case TK_STRUCT:
{
const Ident* structName = nullptr;
dec = new Declaration(mScanner->mLocation, DT_TYPE_STRUCT);
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;
}
dec = ParseStructDeclaration(flags, DT_TYPE_STRUCT);
break;
case TK_UNION:
dec = ParseStructDeclaration(flags, DT_TYPE_UNION);
break;
}
default:
mErrors->Error(mScanner->mLocation, "Declaration starts with invalid token", TokenNames[mScanner->mToken]);
mScanner->NextToken();
@ -491,7 +507,7 @@ Expression* Parser::ParseInitExpression(Declaration* dtype)
Expression* exp = nullptr;
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))
{
@ -813,6 +829,7 @@ Expression* Parser::ParseSimpleExpression(void)
case TK_CONST:
case TK_VOLATILE:
case TK_STRUCT:
case TK_UNION:
case TK_TYPEDEF:
case TK_STATIC:
exp = ParseDeclarationExpression();
@ -1058,7 +1075,7 @@ Expression* Parser::ParsePostfixExpression(void)
dexp->mDecType = exp->mDecType->mBase;
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);
nexp->mLeft = dexp;
@ -1087,7 +1104,7 @@ Expression* Parser::ParsePostfixExpression(void)
else if (mScanner->mToken == TK_DOT)
{
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);
nexp->mLeft = exp;

View File

@ -23,6 +23,7 @@ protected:
Declaration* ParseBaseTypeDeclaration(uint32 flags);
Declaration* ParseDeclaration(bool variable);
Declaration* ParseStructDeclaration(uint32 flags, DecType dt);
Declaration* CopyConstantInitializer(int offset, Declaration* dtype, Expression* exp);
Expression* ParseInitExpression(Declaration* dtype);