From a41c3d445b8207be8aa619b9f98f883f38f5ac27 Mon Sep 17 00:00:00 2001 From: drmortalwombat <90205530+drmortalwombat@users.noreply.github.com> Date: Tue, 27 Jun 2023 17:18:12 +0200 Subject: [PATCH] Add class, public, private and protected keywords --- oscar64/Declaration.h | 2 + oscar64/GlobalAnalyzer.cpp | 2 +- oscar64/Parser.cpp | 142 +++++++++++++++++++++++-------------- oscar64/Scanner.cpp | 14 +++- oscar64/Scanner.h | 4 ++ 5 files changed, 108 insertions(+), 56 deletions(-) diff --git a/oscar64/Declaration.h b/oscar64/Declaration.h index 5672068..5139bda 100644 --- a/oscar64/Declaration.h +++ b/oscar64/Declaration.h @@ -79,6 +79,8 @@ static const uint64 DTF_ZEROPAGE = (1ULL << 22); static const uint64 DTF_PREVENT_INLINE = (1ULL << 23); static const uint64 DTF_STRIPED = (1ULL << 24); static const uint64 DTF_DYNSTACK = (1ULL << 25); +static const uint64 DTF_PRIVATE = (1ULL << 26); +static const uint64 DTF_PROTECTED = (1ULL << 27); static const uint64 DTF_FUNC_VARIABLE = (1ULL << 32); static const uint64 DTF_FUNC_ASSEMBLER = (1ULL << 33); diff --git a/oscar64/GlobalAnalyzer.cpp b/oscar64/GlobalAnalyzer.cpp index f299058..4fedd33 100644 --- a/oscar64/GlobalAnalyzer.cpp +++ b/oscar64/GlobalAnalyzer.cpp @@ -170,7 +170,7 @@ void GlobalAnalyzer::AutoInline(void) doinline = true; if (doinline) - { + { #if 0 printf("INLINING %s %d * (%d - 1)\n", f->mIdent->mString, cost, f->mCallers.Size()); #endif diff --git a/oscar64/Parser.cpp b/oscar64/Parser.cpp index 1992d83..7f523b5 100644 --- a/oscar64/Parser.cpp +++ b/oscar64/Parser.cpp @@ -128,74 +128,95 @@ Declaration* Parser::ParseStructDeclaration(uint64 flags, DecType dt) Declaration* mlast = nullptr; for (;;) { - Declaration* mdec = ParseDeclaration(nullptr, false, false, pthis); - - mdec->mQualIdent = dec->mScope->Mangle(mdec->mIdent); - - int offset = dec->mSize; - if (dt == DT_TYPE_UNION) - offset = 0; - - if (mdec->mBase->mType == DT_TYPE_FUNCTION) + if (ConsumeTokenIf(TK_PUBLIC)) { - mdec->mType = DT_CONST_FUNCTION; - mdec->mSection = mCodeSection; - mdec->mFlags |= DTF_GLOBAL; - mdec->mBase->mFlags |= DTF_FUNC_THIS; - - if (mCompilerOptions & COPT_NATIVE) - mdec->mFlags |= DTF_NATIVE; - - if (!(mdec->mFlags & DTF_DEFINED)) - ConsumeToken(TK_SEMICOLON); - - AddMemberFunction(dec, mdec); + flags &= ~(DTF_PRIVATE | DTF_PROTECTED); + ConsumeToken(TK_COLON); + } + else if (ConsumeTokenIf(TK_PROTECTED)) + { + flags &= ~DTF_PRIVATE; + flags |= DTF_PROTECTED; + ConsumeToken(TK_COLON); + } + else if (ConsumeTokenIf(TK_PRIVATE)) + { + flags |= DTF_PRIVATE | DTF_PROTECTED; + ConsumeToken(TK_COLON); } else { - while (mdec) + Declaration* mdec = ParseDeclaration(nullptr, false, false, pthis); + + mdec->mFlags |= flags & (DTF_PRIVATE | DTF_PROTECTED); + + mdec->mQualIdent = dec->mScope->Mangle(mdec->mIdent); + + int offset = dec->mSize; + if (dt == DT_TYPE_UNION) + offset = 0; + + if (mdec->mBase->mType == DT_TYPE_FUNCTION) { - if (!(mdec->mBase->mFlags & DTF_DEFINED)) - mErrors->Error(mdec->mLocation, EERR_UNDEFINED_OBJECT, "Undefined type used in struct member declaration"); + mdec->mType = DT_CONST_FUNCTION; + mdec->mSection = mCodeSection; + mdec->mFlags |= DTF_GLOBAL; + mdec->mBase->mFlags |= DTF_FUNC_THIS; - if (mdec->mType != DT_VARIABLE) - { - mErrors->Error(mdec->mLocation, EERR_UNDEFINED_OBJECT, "Named structure element expected"); - break; - } + if (mCompilerOptions & COPT_NATIVE) + mdec->mFlags |= DTF_NATIVE; - mdec->mType = DT_ELEMENT; - mdec->mOffset = offset; + if (!(mdec->mFlags & DTF_DEFINED)) + ConsumeToken(TK_SEMICOLON); - offset += mdec->mBase->mSize; - if (offset > dec->mSize) - dec->mSize = offset; - - if (dec->mScope->Insert(mdec->mIdent, mdec)) - mErrors->Error(mdec->mLocation, EERR_DUPLICATE_DEFINITION, "Duplicate struct member declaration", mdec->mIdent); - - if (mlast) - mlast->mNext = mdec; - else - dec->mParams = mdec; - mlast = mdec; - mdec = mdec->mNext; + AddMemberFunction(dec, mdec); } - - if (mScanner->mToken == TK_SEMICOLON) - mScanner->NextToken(); else { - mErrors->Error(mScanner->mLocation, EERR_SYNTAX, "';' expected"); + while (mdec) + { + if (!(mdec->mBase->mFlags & DTF_DEFINED)) + mErrors->Error(mdec->mLocation, EERR_UNDEFINED_OBJECT, "Undefined type used in struct member declaration"); + + if (mdec->mType != DT_VARIABLE) + { + mErrors->Error(mdec->mLocation, EERR_UNDEFINED_OBJECT, "Named structure element expected"); + break; + } + + mdec->mType = DT_ELEMENT; + mdec->mOffset = offset; + + offset += mdec->mBase->mSize; + if (offset > dec->mSize) + dec->mSize = offset; + + if (dec->mScope->Insert(mdec->mIdent, mdec)) + mErrors->Error(mdec->mLocation, EERR_DUPLICATE_DEFINITION, "Duplicate struct member declaration", mdec->mIdent); + + 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, EERR_SYNTAX, "';' expected"); + break; + } + } + + if (mScanner->mToken == TK_CLOSE_BRACE) + { + mScanner->NextToken(); break; } } - - if (mScanner->mToken == TK_CLOSE_BRACE) - { - mScanner->NextToken(); - break; - } } if (mlast) @@ -470,6 +491,9 @@ Declaration* Parser::ParseBaseTypeDeclaration(uint64 flags) case TK_STRUCT: dec = ParseStructDeclaration(flags, DT_TYPE_STRUCT); break; + case TK_CLASS: + dec = ParseStructDeclaration(flags | DTF_PRIVATE, DT_TYPE_STRUCT); + break; case TK_UNION: dec = ParseStructDeclaration(flags, DT_TYPE_UNION); break; @@ -3331,6 +3355,9 @@ Declaration* Parser::ParseDeclaration(Declaration * pdec, bool variable, bool ex ndec->mValue = ParseFunction(ndec->mBase); + if (pthis) + ndec->mFlags |= DTF_REQUEST_INLINE; + ndec->mFlags |= DTF_DEFINED; ndec->mNumVars = mLocalIndex; @@ -3537,6 +3564,7 @@ Expression* Parser::ParseSimpleExpression(bool lhs) case TK_CONST: case TK_VOLATILE: case TK_STRUCT: + case TK_CLASS: case TK_UNION: case TK_TYPEDEF: case TK_STATIC: @@ -3872,6 +3900,12 @@ Expression* Parser::ParseQualify(Expression* exp) if (mdec) { + if (mdec->mFlags & DTF_PROTECTED) + { + if (!mThisPointer || mThisPointer->mBase->IsConstSame(dtype)) + mErrors->Error(mScanner->mLocation, EERR_OBJECT_NOT_FOUND, "Struct member identifier not visible", mScanner->mTokenIdent); + } + mScanner->NextToken(); if (mdec->mType == DT_ELEMENT) { diff --git a/oscar64/Scanner.cpp b/oscar64/Scanner.cpp index 91cba05..535e6f3 100644 --- a/oscar64/Scanner.cpp +++ b/oscar64/Scanner.cpp @@ -153,7 +153,11 @@ const char* TokenNames[] = "'namespace'", "'using'", "'this'", - "'::'" + "'::'", + "'class'", + "'public'", + "'protected'", + "'private'", }; @@ -1394,6 +1398,14 @@ void Scanner::NextRawToken(void) mToken = TK_USING; else if ((mCompilerOptions & COPT_CPLUSPLUS) && !strcmp(tkident, "this")) mToken = TK_THIS; + else if ((mCompilerOptions & COPT_CPLUSPLUS) && !strcmp(tkident, "class")) + mToken = TK_CLASS; + else if ((mCompilerOptions & COPT_CPLUSPLUS) && !strcmp(tkident, "public")) + mToken = TK_PUBLIC; + else if ((mCompilerOptions & COPT_CPLUSPLUS) && !strcmp(tkident, "protected")) + mToken = TK_PROTECTED; + else if ((mCompilerOptions & COPT_CPLUSPLUS) && !strcmp(tkident, "private")) + mToken = TK_PRIVATE; else if ((mCompilerOptions & COPT_CPLUSPLUS) && !strcmp(tkident, "operator")) { NextRawToken(); diff --git a/oscar64/Scanner.h b/oscar64/Scanner.h index 08a4992..a7474a3 100644 --- a/oscar64/Scanner.h +++ b/oscar64/Scanner.h @@ -153,6 +153,10 @@ enum Token TK_USING, TK_THIS, TK_COLCOLON, + TK_CLASS, + TK_PUBLIC, + TK_PROTECTED, + TK_PRIVATE, NUM_TOKENS };