diff --git a/README.md b/README.md index 63b65b0..007f944 100644 --- a/README.md +++ b/README.md @@ -123,6 +123,7 @@ The compiler is command line driven, and creates an executable .prg file. * -xz : extended zero page usage, more zero page space, but no return to basic * -cid : cartridge type ID, used by vice emulator * -pp : compile in C++ mode +* -psci : use PETSCII encoding for all strings without prefix A list of source files can be provided. diff --git a/oscar64/CompilerTypes.h b/oscar64/CompilerTypes.h index 60efb65..4c8d206 100644 --- a/oscar64/CompilerTypes.h +++ b/oscar64/CompilerTypes.h @@ -38,6 +38,7 @@ static const uint64 COPT_VERBOSE3 = 1ULL << 50; static const uint64 COPT_DEBUGINFO = 1ULL << 51; static const uint64 COPT_CPLUSPLUS = 1ULL << 52; +static const uint64 COPT_PETSCII = 1ULL << 53; diff --git a/oscar64/InterCode.cpp b/oscar64/InterCode.cpp index a6fe536..73a435f 100644 --- a/oscar64/InterCode.cpp +++ b/oscar64/InterCode.cpp @@ -19931,7 +19931,7 @@ void InterCodeProcedure::Close(void) { GrowingTypeArray tstack(IT_NONE); - CheckFunc = !strcmp(mIdent->mString, "clear"); + CheckFunc = !strcmp(mIdent->mString, "KeyExpansion"); CheckCase = false; mEntryBlock = mBlocks[0]; diff --git a/oscar64/NativeCodeGenerator.cpp b/oscar64/NativeCodeGenerator.cpp index 327c143..fd639d8 100644 --- a/oscar64/NativeCodeGenerator.cpp +++ b/oscar64/NativeCodeGenerator.cpp @@ -12515,7 +12515,7 @@ void NativeCodeBasicBlock::LoadEffectiveAddress(InterCodeProcedure* proc, const if (ins->mSrc[0].IsUByte()) mIns.Push(NativeCodeInstruction(ins, iop, ASMIM_IMMEDIATE, 0)); else if ((ins->mSrc[1].mIntConst == 0 || ins->mSrc[0].IsUnsigned()) && - (ins->mSrc[1].mLinkerObject->mSize < 256 || (addrvalid && ins->mSrc[1].mLinkerObject->mSize <= 256))) + (ins->mSrc[1].mLinkerObject->mSize - ins->mSrc[1].mIntConst < 256 || (addrvalid && ins->mSrc[1].mLinkerObject->mSize - ins->mSrc[1].mIntConst <= 256))) mIns.Push(NativeCodeInstruction(ins, iop, ASMIM_IMMEDIATE, 0)); else #endif @@ -21117,7 +21117,7 @@ bool NativeCodeBasicBlock::MoveLoadZeroStoreIndirectUp(int at) if (mIns[j].mMode == ASMIM_INDIRECT_Y && mIns[j].mAddress == mIns[at + 2].mAddress) { - if (yval == -1 || yval == mIns[at].mAddress) + if (yval == -1 || yval == mIns[at + 1].mAddress) return false; } else if (mIns[j].MayBeSameAddress(mIns[at + 2])) @@ -45696,7 +45696,7 @@ void NativeCodeProcedure::Compile(InterCodeProcedure* proc) { mInterProc = proc; - CheckFunc = !strcmp(mInterProc->mIdent->mString, "manager_print_at"); + CheckFunc = !strcmp(mInterProc->mIdent->mString, "KeyExpansion"); int nblocks = proc->mBlocks.Size(); tblocks = new NativeCodeBasicBlock * [nblocks]; @@ -47206,6 +47206,7 @@ void NativeCodeProcedure::Optimize(void) else cnt++; + } while (changed); #if 1 diff --git a/oscar64/Parser.cpp b/oscar64/Parser.cpp index 3879718..7654d5e 100644 --- a/oscar64/Parser.cpp +++ b/oscar64/Parser.cpp @@ -4520,8 +4520,32 @@ Declaration* Parser::ParseDeclaration(Declaration * pdec, bool variable, bool ex ndec = pdec; } - else + else if ((mCompilerOptions & COPT_CPLUSPLUS) || mScope->mLevel >= SLEVEL_FUNCTION) mErrors->Error(ndec->mLocation, EERR_DUPLICATE_DEFINITION, "Duplicate variable declaration", ndec->mIdent); + else + { + 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", ndec->mIdent); + } + + pdec->mSection = ndec->mSection; + + pdec->mFlags |= ndec->mFlags & DTF_ZEROPAGE; + + if (pdec->mValue) + mErrors->Error(ndec->mLocation, EERR_DUPLICATE_DEFINITION, "Duplicate variable declaration", ndec->mIdent); + + ndec = pdec; + + } } } @@ -5571,7 +5595,12 @@ Expression* Parser::ParseSimpleExpression(bool lhs) if (/*(dec->mFlags & DTF_STATIC) &&*/ (dec->mFlags & DTF_CONST) && dec->mValue) { if (dec->mBase->IsNumericType()) - exp = dec->mValue; + { + if (dec->mValue->mType == EX_CONSTANT) + { + exp = dec->mValue; + } + } else if (dec->mBase->mType == DT_TYPE_POINTER) { if (dec->mValue->mType == EX_CONSTANT) diff --git a/oscar64/Scanner.cpp b/oscar64/Scanner.cpp index ea01ae8..419dc05 100644 --- a/oscar64/Scanner.cpp +++ b/oscar64/Scanner.cpp @@ -1385,10 +1385,16 @@ void Scanner::NextRawToken(void) break; case '\'': - CharToken('a'); + if (mCompilerOptions & COPT_PETSCII) + CharToken('p'); + else + CharToken('a'); break; case '"': - StringToken(mTokenChar, 'a'); + if (mCompilerOptions & COPT_PETSCII) + StringToken(mTokenChar, 'p'); + else + StringToken(mTokenChar, 'a'); break; case '#': @@ -2136,8 +2142,14 @@ void Scanner::ParseNumberToken(void) NextChar(); mToken = TK_INTEGERL; } + else if (mant < 65536) + { + mToken = TK_INTEGERU; + } else - mToken = TK_INTEGER; + { + mToken = TK_INTEGERUL; + } } mTokenInteger = mant; @@ -2175,8 +2187,14 @@ void Scanner::ParseNumberToken(void) NextChar(); mToken = TK_INTEGERL; } - else + else if (mant < 32768) mToken = TK_INTEGER; + else if (mant < 65536) + mToken = TK_INTEGERU; + else if (mant < 0x80000000) + mToken = TK_INTEGERL; + else + mToken = TK_INTEGERUL; } mTokenInteger = mant; } @@ -2216,8 +2234,10 @@ void Scanner::ParseNumberToken(void) NextChar(); mToken = TK_INTEGERL; } - else + else if (mant < 32768) mToken = TK_INTEGER; + else + mToken = TK_INTEGERL; } mTokenInteger = mant; } @@ -2275,7 +2295,7 @@ void Scanner::ParseNumberToken(void) } -int64 Scanner::PrepParseSimple(void) +int64 Scanner::PrepParseSimple(bool skip) { int64 v = 0; @@ -2291,19 +2311,19 @@ int64 Scanner::PrepParseSimple(void) break; case TK_SUB: NextPreToken(); - v = -PrepParseSimple(); + v = -PrepParseSimple(skip); break; case TK_LOGICAL_NOT: NextPreToken(); - v = !PrepParseSimple(); + v = !PrepParseSimple(skip); break; case TK_BINARY_NOT: NextPreToken(); - v = ~PrepParseSimple(); + v = ~PrepParseSimple(skip); break; case TK_OPEN_PARENTHESIS: NextPreToken(); - v = PrepParseConditional(); + v = PrepParseConditional(skip); if (mToken == TK_CLOSE_PARENTHESIS) NextPreToken(); else @@ -2312,33 +2332,43 @@ int64 Scanner::PrepParseSimple(void) case TK_IDENT: if (strcmp(mTokenIdent->mString, "defined") == 0) { - NextPreToken(); + bool parenthesis = false; + + NextRawToken(); if (mToken == TK_OPEN_PARENTHESIS) { NextRawToken(); - if (mToken == TK_IDENT) - { - Macro* def = nullptr; - if (mDefineArguments) - def = mDefineArguments->Lookup(mTokenIdent); - if (!def) - def = mDefines->Lookup(mTokenIdent); - if (def) - v = 1; - else - v = 0; - NextPreToken(); - } - else - mErrors->Error(mLocation, ERRR_PREPROCESSOR, "Identifier expected"); + parenthesis = true; + } + if (mToken == TK_IDENT) + { + Macro* def = nullptr; + if (mDefineArguments) + def = mDefineArguments->Lookup(mTokenIdent); + if (!def) + def = mDefines->Lookup(mTokenIdent); + if (def) + v = 1; + else + v = 0; + NextPreToken(); + } + else + mErrors->Error(mLocation, ERRR_PREPROCESSOR, "Identifier expected"); + + if (parenthesis) + { if (mToken == TK_CLOSE_PARENTHESIS) NextPreToken(); else mErrors->Error(mLocation, ERRR_PREPROCESSOR, "')' expected"); } - else - mErrors->Error(mLocation, ERRR_PREPROCESSOR, "'(' expected"); + } + else if (skip) + { + NextPreToken(); + v = 0; } else mErrors->Error(mLocation, ERRR_PREPROCESSOR, "Invalid preprocessor symbol", mTokenIdent); @@ -2352,9 +2382,9 @@ int64 Scanner::PrepParseSimple(void) return v; } -int64 Scanner::PrepParseMul(void) +int64 Scanner::PrepParseMul(bool skip) { - int64 v = PrepParseSimple(); + int64 v = PrepParseSimple(skip); int64 u; for (;;) { @@ -2362,19 +2392,23 @@ int64 Scanner::PrepParseMul(void) { case TK_MUL: NextPreToken(); - v *= PrepParseSimple(); + v *= PrepParseSimple(skip); break; case TK_DIV: NextPreToken(); - u = PrepParseSimple(); - if (u == 0) + u = PrepParseSimple(skip); + if (skip) + ; + else if (u == 0) mErrors->Error(mLocation, ERRR_PREPROCESSOR, "Division by zero"); else v /= u; break; case TK_MOD: - u = PrepParseSimple(); - if (u == 0) + u = PrepParseSimple(skip); + if (skip) + ; + else if (u == 0) mErrors->Error(mLocation, ERRR_PREPROCESSOR, "Division by zero"); else v %= u; @@ -2385,20 +2419,20 @@ int64 Scanner::PrepParseMul(void) } } -int64 Scanner::PrepParseAdd(void) +int64 Scanner::PrepParseAdd(bool skip) { - int64 v = PrepParseMul(); + int64 v = PrepParseMul(skip); for (;;) { switch (mToken) { case TK_ADD: NextPreToken(); - v += PrepParseMul(); + v += PrepParseMul(skip); break; case TK_SUB: NextPreToken(); - v -= PrepParseMul(); + v -= PrepParseMul(skip); break; default: return v; @@ -2406,20 +2440,20 @@ int64 Scanner::PrepParseAdd(void) } } -int64 Scanner::PrepParseShift(void) +int64 Scanner::PrepParseShift(bool skip) { - int64 v = PrepParseAdd(); + int64 v = PrepParseAdd(skip); for (;;) { switch (mToken) { case TK_LEFT_SHIFT: NextPreToken(); - v <<= PrepParseAdd(); + v <<= PrepParseAdd(skip); break; case TK_RIGHT_SHIFT: NextPreToken(); - v >>= PrepParseAdd(); + v >>= PrepParseAdd(skip); break; default: return v; @@ -2427,36 +2461,36 @@ int64 Scanner::PrepParseShift(void) } } -int64 Scanner::PrepParseRel(void) +int64 Scanner::PrepParseRel(bool skip) { - int64 v = PrepParseShift(); + int64 v = PrepParseShift(skip); for (;;) { switch (mToken) { case TK_LESS_THAN: NextPreToken(); - v = v < PrepParseShift(); + v = v < PrepParseShift(skip); break; case TK_GREATER_THAN: NextPreToken(); - v = v > PrepParseShift(); + v = v > PrepParseShift(skip); break; case TK_LESS_EQUAL: NextPreToken(); - v = v <= PrepParseShift(); + v = v <= PrepParseShift(skip); break; case TK_GREATER_EQUAL: NextPreToken(); - v = v >= PrepParseShift(); + v = v >= PrepParseShift(skip); break; case TK_EQUAL: NextPreToken(); - v = v == PrepParseShift(); + v = v == PrepParseShift(skip); break; case TK_NOT_EQUAL: NextPreToken(); - v = v != PrepParseShift(); + v = v != PrepParseShift(skip); break; default: return v; @@ -2465,75 +2499,75 @@ int64 Scanner::PrepParseRel(void) } -int64 Scanner::PrepParseBinaryAnd(void) +int64 Scanner::PrepParseBinaryAnd(bool skip) { - int64 v = PrepParseRel(); + int64 v = PrepParseRel(skip); while (mToken == TK_BINARY_AND) { NextPreToken(); - v &= PrepParseRel(); + v &= PrepParseRel(skip); } return v; } -int64 Scanner::PrepParseBinaryXor(void) +int64 Scanner::PrepParseBinaryXor(bool skip) { - int64 v = PrepParseBinaryAnd(); + int64 v = PrepParseBinaryAnd(skip); while (mToken == TK_BINARY_XOR) { NextPreToken(); - v ^= PrepParseBinaryAnd(); + v ^= PrepParseBinaryAnd(skip); } return v; } -int64 Scanner::PrepParseBinaryOr(void) +int64 Scanner::PrepParseBinaryOr(bool skip) { - int64 v = PrepParseBinaryXor(); + int64 v = PrepParseBinaryXor(skip); while (mToken == TK_BINARY_OR) { NextPreToken(); - v |= PrepParseBinaryXor(); + v |= PrepParseBinaryXor(skip); } return v; } -int64 Scanner::PrepParseLogicalAnd(void) +int64 Scanner::PrepParseLogicalAnd(bool skip) { - int64 v = PrepParseBinaryOr(); + int64 v = PrepParseBinaryOr(skip); while (mToken == TK_LOGICAL_AND) { NextPreToken(); - if (!PrepParseBinaryOr()) + if (!PrepParseBinaryOr(skip || !v)) v = 0; } return v; } -int64 Scanner::PrepParseLogicalOr(void) +int64 Scanner::PrepParseLogicalOr(bool skip) { - int64 v = PrepParseLogicalAnd(); + int64 v = PrepParseLogicalAnd(skip); while (mToken == TK_LOGICAL_OR) { NextPreToken(); - if (PrepParseLogicalAnd()) + if (PrepParseLogicalAnd(skip || v)) v = 1; } return v; } -int64 Scanner::PrepParseConditional(void) +int64 Scanner::PrepParseConditional(bool skip) { - int64 v = PrepParseLogicalOr(); + int64 v = PrepParseLogicalOr(skip); if (mToken == TK_QUESTIONMARK) { NextPreToken(); - int64 vt = PrepParseConditional(); + int64 vt = PrepParseConditional(skip || v); if (mToken == TK_COLON) NextPreToken(); else mErrors->Error(mLocation, ERRR_PREPROCESSOR, "':' expected"); - int64 vf = PrepParseConditional(); + int64 vf = PrepParseConditional(skip || !v); if (v) v = vt; else diff --git a/oscar64/Scanner.h b/oscar64/Scanner.h index dd25a7e..d75f826 100644 --- a/oscar64/Scanner.h +++ b/oscar64/Scanner.h @@ -311,16 +311,16 @@ protected: bool NextChar(void); void ParseNumberToken(void); - int64 PrepParseSimple(void); - int64 PrepParseMul(void); - int64 PrepParseAdd(void); - int64 PrepParseShift(void); - int64 PrepParseRel(void); - int64 PrepParseBinaryAnd(void); - int64 PrepParseBinaryXor(void); - int64 PrepParseBinaryOr(void); - int64 PrepParseLogicalAnd(void); - int64 PrepParseLogicalOr(void); - int64 PrepParseConditional(void); + int64 PrepParseSimple(bool skip); + int64 PrepParseMul(bool skip); + int64 PrepParseAdd(bool skip); + int64 PrepParseShift(bool skip); + int64 PrepParseRel(bool skip); + int64 PrepParseBinaryAnd(bool skip); + int64 PrepParseBinaryXor(bool skip); + int64 PrepParseBinaryOr(bool skip); + int64 PrepParseLogicalAnd(bool skip); + int64 PrepParseLogicalOr(bool skip); + int64 PrepParseConditional(bool skip = false); }; diff --git a/oscar64/oscar64.cpp b/oscar64/oscar64.cpp index c5b5c15..852ff59 100644 --- a/oscar64/oscar64.cpp +++ b/oscar64/oscar64.cpp @@ -186,6 +186,10 @@ int main2(int argc, const char** argv) { compiler->mCompilerOptions &= ~COPT_NATIVE; } + else if (arg[1] == 'p' && arg[2] == 's' && arg[3] == 'c' && arg[4] == 'i') + { + compiler->mCompilerOptions |= COPT_PETSCII; + } else if (arg[1] == 'O') { if (arg[2] == '0')