diff --git a/include/gfx/vector3d.c b/include/gfx/vector3d.c index 897c8c4..f3430c7 100644 --- a/include/gfx/vector3d.c +++ b/include/gfx/vector3d.c @@ -776,7 +776,7 @@ void mat4_mmul(Matrix4 * md, const Matrix4 * ms) for(char j=0; j<4; j++) ma[j] = md->m[i + 0] * ms->m[4 * j] + md->m[i + 4] * ms->m[4 * j + 1] + md->m[i + 8] * ms->m[4 * j + 2] + md->m[i + 12] * ms->m[4 * j + 3]; for(char j=0; j<4; j++) - md->m[(char)(i + 4 * j)] = ma[j]; + md->m[i + 4 * j] = ma[j]; } } diff --git a/oscar64/Declaration.cpp b/oscar64/Declaration.cpp index c4da221..10a2670 100644 --- a/oscar64/Declaration.cpp +++ b/oscar64/Declaration.cpp @@ -377,6 +377,21 @@ Declaration::~Declaration(void) delete[] mData; } +Declaration* Declaration::ToConstType(void) +{ + if (mFlags & DTF_CONST) + return this; + + Declaration* ndec = new Declaration(mLocation, mType); + ndec->mSize = mSize; + ndec->mBase = mBase; + ndec->mFlags = mFlags | DTF_CONST; + ndec->mScope = mScope; + ndec->mParams = mParams; + + return ndec; +} + bool Declaration::IsSubType(const Declaration* dec) const { if (this == dec) @@ -403,6 +418,8 @@ 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 && dec->mType == DT_TYPE_STRUCT) + return mScope == dec->mScope; else if (mType == DT_TYPE_STRUCT || mType == DT_TYPE_ENUM || mType == DT_TYPE_UNION) return false; else if (mType == DT_TYPE_ARRAY) @@ -457,6 +474,8 @@ bool Declaration::IsSame(const Declaration* dec) const } else if (mType == DT_TYPE_POINTER || mType == DT_TYPE_ARRAY) return mBase->IsSame(dec->mBase); + else if (mType == DT_TYPE_STRUCT && dec->mType == DT_TYPE_STRUCT) + return mScope == dec->mScope; else if (mType == DT_TYPE_FUNCTION) { if (!mBase->IsSame(dec->mBase)) @@ -491,6 +510,8 @@ bool Declaration::CanAssign(const Declaration* fromType) const if (fromType->IsNumericType()) return true; } + else if (mType == DT_TYPE_STRUCT && fromType->mType == DT_TYPE_STRUCT) + return mScope == fromType->mScope; else if (mType == DT_TYPE_POINTER) { if (fromType->mType == DT_TYPE_POINTER || fromType->mType == DT_TYPE_ARRAY) diff --git a/oscar64/Declaration.h b/oscar64/Declaration.h index c7e408f..4e2da77 100644 --- a/oscar64/Declaration.h +++ b/oscar64/Declaration.h @@ -105,6 +105,7 @@ enum ExpressionType EX_CONSTANT, EX_VARIABLE, EX_ASSIGNMENT, + EX_INITIALIZATION, EX_BINARY, EX_RELATIONAL, EX_PREINCDEC, @@ -187,6 +188,8 @@ public: bool IsIntegerType(void) const; bool IsNumericType(void) const; bool IsSimpleType(void) const; + + Declaration* ToConstType(void); }; void InitDeclarations(void); diff --git a/oscar64/GlobalAnalyzer.cpp b/oscar64/GlobalAnalyzer.cpp index cb5373e..329f024 100644 --- a/oscar64/GlobalAnalyzer.cpp +++ b/oscar64/GlobalAnalyzer.cpp @@ -279,6 +279,7 @@ Declaration * GlobalAnalyzer::Analyze(Expression* exp, Declaration* procDec) } } return exp->mDecValue; + case EX_INITIALIZATION: case EX_ASSIGNMENT: ldec = Analyze(exp->mLeft, procDec); rdec = Analyze(exp->mRight, procDec); diff --git a/oscar64/InterCodeGenerator.cpp b/oscar64/InterCodeGenerator.cpp index 24f35d7..b1aaf10 100644 --- a/oscar64/InterCodeGenerator.cpp +++ b/oscar64/InterCodeGenerator.cpp @@ -940,6 +940,7 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration* case EX_ASSIGNMENT: + case EX_INITIALIZATION: { if (exp->mLeft->mDecType && exp->mLeft->mDecType->mType == DT_TYPE_STRUCT) { @@ -958,7 +959,7 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration* mErrors->Error(exp->mLocation, EERR_INCOMPATIBLE_TYPES, "Cannot assign incompatible types"); } - if (vl.mType->mFlags & DTF_CONST) + if (exp->mType != EX_INITIALIZATION && (vl.mType->mFlags & DTF_CONST)) mErrors->Error(exp->mLocation, EERR_CONST_ASSIGN, "Cannot assign to const type"); if (vl.mType->mType == DT_TYPE_STRUCT || vl.mType->mType == DT_TYPE_ARRAY || vl.mType->mType == DT_TYPE_UNION) diff --git a/oscar64/NativeCodeGenerator.cpp b/oscar64/NativeCodeGenerator.cpp index 0251910..fc9cb81 100644 --- a/oscar64/NativeCodeGenerator.cpp +++ b/oscar64/NativeCodeGenerator.cpp @@ -2628,18 +2628,25 @@ void NativeCodeInstruction::Assemble(NativeCodeBasicBlock* block) block->PutByte(mParam); } - if (mMode == ASMIM_IMMEDIATE_ADDRESS) + AsmInsMode mode = mMode; + + if (mode == ASMIM_ABSOLUTE && !mLinkerObject && mAddress < 256 && HasAsmInstructionMode(mType, ASMIM_ZERO_PAGE)) + mode = ASMIM_ZERO_PAGE; + else if (mode == ASMIM_ABSOLUTE_X && !mLinkerObject && mAddress < 256 && HasAsmInstructionMode(mType, ASMIM_ZERO_PAGE_X)) + mode = ASMIM_ZERO_PAGE_X; + + if (mode == ASMIM_IMMEDIATE_ADDRESS) { assert(HasAsmInstructionMode(mType, ASMIM_IMMEDIATE)); block->PutByte(AsmInsOpcodes[mType][ASMIM_IMMEDIATE]); } else { - assert(HasAsmInstructionMode(mType, mMode)); - block->PutByte(AsmInsOpcodes[mType][mMode]); + assert(HasAsmInstructionMode(mType, mode)); + block->PutByte(AsmInsOpcodes[mType][mode]); } - switch (mMode) + switch (mode) { case ASMIM_IMPLIED: break; @@ -12802,20 +12809,22 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(int pass) mIns[i + 1].mType = ASMIT_NOP; mIns[i + 1].mMode = ASMIM_IMPLIED; progress = true; } +#if 1 else if ( mIns[i + 0].mType == ASMIT_TXA && mIns[i + 1].mType == ASMIT_CMP && (mIns[i + 1].mMode == ASMIM_IMMEDIATE || mIns[i + 1].mMode == ASMIM_ZERO_PAGE || mIns[i + 1].mMode == ASMIM_ABSOLUTE)) { mIns[i + 1].mType = ASMIT_CPX; - mIns[i + 0].mLive |= CPU_REG_X; + mIns[i + 0].mLive |= LIVE_CPU_REG_X; progress = true; } +#endif else if ( mIns[i + 0].mType == ASMIT_TYA && mIns[i + 1].mType == ASMIT_CMP && (mIns[i + 1].mMode == ASMIM_IMMEDIATE || mIns[i + 1].mMode == ASMIM_ZERO_PAGE || mIns[i + 1].mMode == ASMIM_ABSOLUTE)) { mIns[i + 1].mType = ASMIT_CPY; - mIns[i + 0].mLive |= CPU_REG_Y; + mIns[i + 0].mLive |= LIVE_CPU_REG_Y; progress = true; } else if ( diff --git a/oscar64/Parser.cpp b/oscar64/Parser.cpp index 37bf283..726acc7 100644 --- a/oscar64/Parser.cpp +++ b/oscar64/Parser.cpp @@ -235,6 +235,16 @@ Declaration* Parser::ParseBaseTypeDeclaration(uint32 flags) ndec->mBase = dec->mBase; dec = ndec; } + else if (dec->mType == DT_TYPE_STRUCT && (flags & ~dec->mFlags)) + { + Declaration* ndec = new Declaration(dec->mLocation, dec->mType); + ndec->mFlags = dec->mFlags | flags; + ndec->mSize = dec->mSize; + ndec->mBase = dec->mBase; + ndec->mScope = dec->mScope; + ndec->mParams = dec->mParams; + dec = ndec; + } mScanner->NextToken(); } else if (!dec) @@ -345,6 +355,12 @@ Declaration* Parser::ParseBaseTypeDeclaration(uint32 flags) dec->mFlags |= DTF_DEFINED; } + if (mScanner->mToken == TK_CONST) + { + dec = dec->ToConstType(); + mScanner->NextToken(); + } + return dec; } @@ -356,11 +372,18 @@ Declaration* Parser::ParsePostfixDeclaration(void) if (mScanner->mToken == TK_MUL) { mScanner->NextToken(); - Declaration* dec = ParsePostfixDeclaration(); + Declaration* ndec = new Declaration(mScanner->mLocation, DT_TYPE_POINTER); - ndec->mBase = dec; ndec->mSize = 2; ndec->mFlags |= DTF_DEFINED; + if (mScanner->mToken == TK_CONST) + { + ndec->mFlags |= DTF_CONST; + mScanner->NextToken(); + } + + Declaration* dec = ParsePostfixDeclaration(); + ndec->mBase = dec; return ndec; } else if (mScanner->mToken == TK_OPEN_PARENTHESIS) @@ -648,6 +671,23 @@ Expression* Parser::ParseInitExpression(Declaration* dtype) Declaration* mdec = dtype->mParams; while (mdec) { + if (ConsumeTokenIf(TK_DOT)) + { + if (mScanner->mToken == TK_IDENT) + { + Declaration* ndec = dtype->mScope->Lookup(mScanner->mTokenIdent); + if (ndec) + mdec = ndec; + else + mErrors->Error(mScanner->mLocation, EERR_CONSTANT_INITIALIZER, "Struct member not found"); + + mScanner->NextToken(); + ConsumeToken(TK_ASSIGN); + } + else + mErrors->Error(mScanner->mLocation, EERR_CONSTANT_INITIALIZER, "Identifier expected"); + } + Expression* texp = ParseInitExpression(mdec->mBase); Declaration* cdec = CopyConstantInitializer(mdec->mOffset, mdec->mBase, texp); @@ -907,11 +947,32 @@ Declaration* Parser::ParseDeclaration(bool variable) ndec = pdec; } - else if ((ndec->mFlags & DTF_EXTERN) || (pdec->mFlags & DTF_EXTERN)) + else if (ndec->mFlags & DTF_EXTERN) { if (!ndec->mBase->IsSame(pdec->mBase)) { - mErrors->Error(ndec->mLocation, EERR_DECLARATION_DIFFERS, "Variable declaration differs"); + if (ndec->mBase->mType == DT_TYPE_ARRAY && pdec->mBase->mType == DT_TYPE_ARRAY && ndec->mBase->mBase->IsSame(pdec->mBase->mBase) && ndec->mBase->mSize == 0) + ; + else if (ndec->mBase->mType == DT_TYPE_POINTER && pdec->mBase->mType == DT_TYPE_ARRAY && ndec->mBase->mBase->IsSame(pdec->mBase->mBase)) + ; + else + mErrors->Error(ndec->mLocation, EERR_DECLARATION_DIFFERS, "Variable declaration differs"); + } + + ndec = pdec; + } + else if (pdec->mFlags & DTF_EXTERN) + { + if (!ndec->mBase->IsSame(pdec->mBase)) + { + if (ndec->mBase->mType == DT_TYPE_ARRAY && pdec->mBase->mType == DT_TYPE_ARRAY && ndec->mBase->mBase->IsSame(pdec->mBase->mBase) && pdec->mBase->mSize == 0) + pdec->mBase->mSize = ndec->mBase->mSize; + else if (pdec->mBase->mType == DT_TYPE_POINTER && ndec->mBase->mType == DT_TYPE_ARRAY && ndec->mBase->mBase->IsSame(pdec->mBase->mBase)) + { + pdec->mBase = ndec->mBase; + } + else + mErrors->Error(ndec->mLocation, EERR_DECLARATION_DIFFERS, "Variable declaration differs"); } if (!(ndec->mFlags & DTF_EXTERN)) @@ -991,9 +1052,9 @@ Expression* Parser::ParseDeclarationExpression(void) { while (dec) { - if (dec->mValue) + if (dec->mValue && !(dec->mFlags & DTF_GLOBAL)) { - Expression* nexp = new Expression(dec->mValue->mLocation, EX_ASSIGNMENT); + Expression* nexp = new Expression(dec->mValue->mLocation, EX_INITIALIZATION); nexp->mToken = TK_ASSIGN; nexp->mLeft = new Expression(dec->mLocation, EX_VARIABLE); nexp->mLeft->mDecValue = dec; @@ -1125,7 +1186,7 @@ Expression* Parser::ParseSimpleExpression(void) dec->mBase->mSize = dec->mSize; dec->mBase->mBase = TheConstCharTypeDeclaration; dec->mBase->mFlags |= DTF_DEFINED; - uint8* d = new uint8[dec->mSize]; + uint8* d = new uint8[dec->mSize + 1]; dec->mData = d; int i = 0; diff --git a/oscar64/Scanner.cpp b/oscar64/Scanner.cpp index bc93ea6..7876cba 100644 --- a/oscar64/Scanner.cpp +++ b/oscar64/Scanner.cpp @@ -123,6 +123,7 @@ const char* TokenNames[] = "embedded", "'#define'", + "'#undef'", "'#include'", "'#if'", "'#elif'", @@ -241,6 +242,26 @@ void MacroDict::Insert(Macro * macro) } } +void MacroDict::Remove(const Ident* ident) +{ + if (mHashSize > 0) + { + int hm = mHashSize - 1; + int hi = ident->mHash & hm; + + while (mHash[hi]) + { + if (ident == mHash[hi]->mIdent) + { + mHash[hi]->mIdent = nullptr; + return; + } + + hi = (hi + 1) & hm; + } + } +} + Macro* MacroDict::Lookup(const Ident* ident) { if (mHashSize > 0) @@ -512,6 +533,15 @@ void Scanner::NextToken(void) mOffset += slen; } } + else if (mToken == TK_PREP_UNDEF) + { + NextRawToken(); + if (mToken == TK_IDENT) + { + mDefines->Remove(mTokenIdent); + } + + } else if (mToken == TK_PREP_IFDEF) { NextRawToken(); @@ -1045,6 +1075,8 @@ void Scanner::NextRawToken(void) if (!strcmp(tkprep, "define")) mToken = TK_PREP_DEFINE; + else if (!strcmp(tkprep, "undef")) + mToken = TK_PREP_UNDEF; else if (!strcmp(tkprep, "include")) mToken = TK_PREP_INCLUDE; else if (!strcmp(tkprep, "if")) diff --git a/oscar64/Scanner.h b/oscar64/Scanner.h index c4a1ec9..8f54b3a 100644 --- a/oscar64/Scanner.h +++ b/oscar64/Scanner.h @@ -121,6 +121,7 @@ enum Token TK_EMBEDDED, TK_PREP_DEFINE, + TK_PREP_UNDEF, TK_PREP_INCLUDE, TK_PREP_IF, TK_PREP_ELIF, @@ -165,6 +166,7 @@ public: ~MacroDict(void); void Insert(Macro * macro); + void Remove(const Ident* ident); Macro* Lookup(const Ident* ident); protected: