Add class, public, private and protected keywords

This commit is contained in:
drmortalwombat 2023-06-27 17:18:12 +02:00
parent f99185e56d
commit a41c3d445b
5 changed files with 108 additions and 56 deletions

View File

@ -79,6 +79,8 @@ static const uint64 DTF_ZEROPAGE = (1ULL << 22);
static const uint64 DTF_PREVENT_INLINE = (1ULL << 23); static const uint64 DTF_PREVENT_INLINE = (1ULL << 23);
static const uint64 DTF_STRIPED = (1ULL << 24); static const uint64 DTF_STRIPED = (1ULL << 24);
static const uint64 DTF_DYNSTACK = (1ULL << 25); 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_VARIABLE = (1ULL << 32);
static const uint64 DTF_FUNC_ASSEMBLER = (1ULL << 33); static const uint64 DTF_FUNC_ASSEMBLER = (1ULL << 33);

View File

@ -170,7 +170,7 @@ void GlobalAnalyzer::AutoInline(void)
doinline = true; doinline = true;
if (doinline) if (doinline)
{ {
#if 0 #if 0
printf("INLINING %s %d * (%d - 1)\n", f->mIdent->mString, cost, f->mCallers.Size()); printf("INLINING %s %d * (%d - 1)\n", f->mIdent->mString, cost, f->mCallers.Size());
#endif #endif

View File

@ -128,74 +128,95 @@ Declaration* Parser::ParseStructDeclaration(uint64 flags, DecType dt)
Declaration* mlast = nullptr; Declaration* mlast = nullptr;
for (;;) for (;;)
{ {
Declaration* mdec = ParseDeclaration(nullptr, false, false, pthis); if (ConsumeTokenIf(TK_PUBLIC))
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)
{ {
mdec->mType = DT_CONST_FUNCTION; flags &= ~(DTF_PRIVATE | DTF_PROTECTED);
mdec->mSection = mCodeSection; ConsumeToken(TK_COLON);
mdec->mFlags |= DTF_GLOBAL; }
mdec->mBase->mFlags |= DTF_FUNC_THIS; else if (ConsumeTokenIf(TK_PROTECTED))
{
if (mCompilerOptions & COPT_NATIVE) flags &= ~DTF_PRIVATE;
mdec->mFlags |= DTF_NATIVE; flags |= DTF_PROTECTED;
ConsumeToken(TK_COLON);
if (!(mdec->mFlags & DTF_DEFINED)) }
ConsumeToken(TK_SEMICOLON); else if (ConsumeTokenIf(TK_PRIVATE))
{
AddMemberFunction(dec, mdec); flags |= DTF_PRIVATE | DTF_PROTECTED;
ConsumeToken(TK_COLON);
} }
else 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)) mdec->mType = DT_CONST_FUNCTION;
mErrors->Error(mdec->mLocation, EERR_UNDEFINED_OBJECT, "Undefined type used in struct member declaration"); mdec->mSection = mCodeSection;
mdec->mFlags |= DTF_GLOBAL;
mdec->mBase->mFlags |= DTF_FUNC_THIS;
if (mdec->mType != DT_VARIABLE) if (mCompilerOptions & COPT_NATIVE)
{ mdec->mFlags |= DTF_NATIVE;
mErrors->Error(mdec->mLocation, EERR_UNDEFINED_OBJECT, "Named structure element expected");
break;
}
mdec->mType = DT_ELEMENT; if (!(mdec->mFlags & DTF_DEFINED))
mdec->mOffset = offset; ConsumeToken(TK_SEMICOLON);
offset += mdec->mBase->mSize; AddMemberFunction(dec, mdec);
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 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; break;
} }
} }
if (mScanner->mToken == TK_CLOSE_BRACE)
{
mScanner->NextToken();
break;
}
} }
if (mlast) if (mlast)
@ -470,6 +491,9 @@ Declaration* Parser::ParseBaseTypeDeclaration(uint64 flags)
case TK_STRUCT: case TK_STRUCT:
dec = ParseStructDeclaration(flags, DT_TYPE_STRUCT); dec = ParseStructDeclaration(flags, DT_TYPE_STRUCT);
break; break;
case TK_CLASS:
dec = ParseStructDeclaration(flags | DTF_PRIVATE, DT_TYPE_STRUCT);
break;
case TK_UNION: case TK_UNION:
dec = ParseStructDeclaration(flags, DT_TYPE_UNION); dec = ParseStructDeclaration(flags, DT_TYPE_UNION);
break; break;
@ -3331,6 +3355,9 @@ Declaration* Parser::ParseDeclaration(Declaration * pdec, bool variable, bool ex
ndec->mValue = ParseFunction(ndec->mBase); ndec->mValue = ParseFunction(ndec->mBase);
if (pthis)
ndec->mFlags |= DTF_REQUEST_INLINE;
ndec->mFlags |= DTF_DEFINED; ndec->mFlags |= DTF_DEFINED;
ndec->mNumVars = mLocalIndex; ndec->mNumVars = mLocalIndex;
@ -3537,6 +3564,7 @@ Expression* Parser::ParseSimpleExpression(bool lhs)
case TK_CONST: case TK_CONST:
case TK_VOLATILE: case TK_VOLATILE:
case TK_STRUCT: case TK_STRUCT:
case TK_CLASS:
case TK_UNION: case TK_UNION:
case TK_TYPEDEF: case TK_TYPEDEF:
case TK_STATIC: case TK_STATIC:
@ -3872,6 +3900,12 @@ Expression* Parser::ParseQualify(Expression* exp)
if (mdec) 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(); mScanner->NextToken();
if (mdec->mType == DT_ELEMENT) if (mdec->mType == DT_ELEMENT)
{ {

View File

@ -153,7 +153,11 @@ const char* TokenNames[] =
"'namespace'", "'namespace'",
"'using'", "'using'",
"'this'", "'this'",
"'::'" "'::'",
"'class'",
"'public'",
"'protected'",
"'private'",
}; };
@ -1394,6 +1398,14 @@ void Scanner::NextRawToken(void)
mToken = TK_USING; mToken = TK_USING;
else if ((mCompilerOptions & COPT_CPLUSPLUS) && !strcmp(tkident, "this")) else if ((mCompilerOptions & COPT_CPLUSPLUS) && !strcmp(tkident, "this"))
mToken = TK_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")) else if ((mCompilerOptions & COPT_CPLUSPLUS) && !strcmp(tkident, "operator"))
{ {
NextRawToken(); NextRawToken();

View File

@ -153,6 +153,10 @@ enum Token
TK_USING, TK_USING,
TK_THIS, TK_THIS,
TK_COLCOLON, TK_COLCOLON,
TK_CLASS,
TK_PUBLIC,
TK_PROTECTED,
TK_PRIVATE,
NUM_TOKENS NUM_TOKENS
}; };