diff --git a/oscar64/ByteCodeGenerator.cpp b/oscar64/ByteCodeGenerator.cpp index ee18d54..4ba87c6 100644 --- a/oscar64/ByteCodeGenerator.cpp +++ b/oscar64/ByteCodeGenerator.cpp @@ -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; diff --git a/oscar64/ByteCodeGenerator.h b/oscar64/ByteCodeGenerator.h index 95048e2..c9a6a10 100644 --- a/oscar64/ByteCodeGenerator.h +++ b/oscar64/ByteCodeGenerator.h @@ -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); diff --git a/oscar64/Compiler.cpp b/oscar64/Compiler.cpp index 6f4f85f..ecc0691 100644 --- a/oscar64/Compiler.cpp +++ b/oscar64/Compiler.cpp @@ -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); diff --git a/oscar64/Declaration.cpp b/oscar64/Declaration.cpp index af6439e..271296b 100644 --- a/oscar64/Declaration.cpp +++ b/oscar64/Declaration.cpp @@ -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); diff --git a/oscar64/InterCodeGenerator.cpp b/oscar64/InterCodeGenerator.cpp index abed88d..4ce2ace 100644 --- a/oscar64/InterCodeGenerator.cpp +++ b/oscar64/InterCodeGenerator.cpp @@ -2,7 +2,7 @@ #include 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; diff --git a/oscar64/InterCodeGenerator.h b/oscar64/InterCodeGenerator.h index 68af623..1cd746a 100644 --- a/oscar64/InterCodeGenerator.h +++ b/oscar64/InterCodeGenerator.h @@ -19,6 +19,7 @@ public: {} }; + bool mForceNativeCode; InterCodeProcedure* TranslateProcedure(InterCodeModule* mod, Expression* exp, Declaration * dec); void TranslateAssembler(InterCodeModule* mod, Expression * exp); diff --git a/oscar64/Parser.cpp b/oscar64/Parser.cpp index 8f3f94c..81455dc 100644 --- a/oscar64/Parser.cpp +++ b/oscar64/Parser.cpp @@ -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; diff --git a/oscar64/Parser.h b/oscar64/Parser.h index 5e45edb..7cc6e83 100644 --- a/oscar64/Parser.h +++ b/oscar64/Parser.h @@ -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);