const member functions

This commit is contained in:
drmortalwombat 2023-06-29 18:11:11 +02:00
parent fa9aa9c2bb
commit 1b73df7e25
6 changed files with 374 additions and 12 deletions

147
include/opp/string.cpp Normal file
View File

@ -0,0 +1,147 @@
#include "string.h"
#include <string.h>
#include <stdlib.h>
string::string(void) : cstr(nullptr)
{}
string::string(const string & s)
{
cstr = malloc(strlen(s.cstr) + 1);
strcpy(cstr, s.cstr);
}
string::string(const char * s)
{
cstr = malloc(strlen(s) + 1);
strcpy(cstr, s);
}
string::string(const char * s1, const char * s2)
{
cstr = malloc(strlen(s1) + strlen(s2) + 1);
strcpy(cstr, s1);
strcat(cstr, s2);
}
string::~string(void)
{
free(cstr);
}
string & string::operator=(const string & s)
{
if (cstr != s.cstr)
{
free(cstr);
cstr = malloc(strlen(s.cstr) + 1);
strcpy(cstr, s.cstr);
}
return *this;
}
string & string::operator=(const char * s)
{
free(cstr);
cstr = malloc(strlen(s) + 1);
strcpy(cstr, s);
return *this;
}
string & string::operator+=(const string & s)
{
char * nstr = malloc(strlen(cstr) + strlen(s.cstr) + 1);
strcpy(nstr, cstr);
strcat(nstr, s.cstr);
free(cstr);
cstr = nstr;
return *this;
}
string & string::operator+=(const char * s)
{
char * nstr = malloc(strlen(cstr) + strlen(s) + 1);
strcpy(nstr, cstr);
strcat(nstr, s);
free(cstr);
cstr = nstr;
return *this;
}
inline const char * string::tocstr(void) const
{
return cstr;
}
string string::operator+(const string & s)
{
return string(cstr, s.cstr);
}
string string::operator+(const char * s)
{
return string(cstr, s);
}
inline bool string::operator==(const string & s) const
{
return strcmp(cstr, s.cstr) == 0;
}
inline bool string::operator==(const char * s) const
{
return strcmp(cstr, s) == 0;
}
inline bool string::operator!=(const string & s) const
{
return strcmp(cstr, s.cstr) != 0;
}
inline bool string::operator!=(const char * s) const
{
return strcmp(cstr, s) == 0;
}
inline bool string::operator<(const string & s) const
{
return strcmp(cstr, s.cstr) < 0;
}
inline bool string::operator<(const char * s) const
{
return strcmp(cstr, s) < 0;
}
inline bool string::operator<=(const string & s) const
{
return strcmp(cstr, s.cstr) <= 0;
}
inline bool string::operator<=(const char * s) const
{
return strcmp(cstr, s) <= 0;
}
inline bool string::operator>(const string & s) const
{
return strcmp(cstr, s.cstr) > 0;
}
inline bool string::operator>(const char * s) const
{
return strcmp(cstr, s) > 0;
}
inline bool string::operator>=(const string & s) const
{
return strcmp(cstr, s.cstr) >= 0;
}
inline bool string::operator>=(const char * s) const
{
return strcmp(cstr, s) >= 0;
}

45
include/opp/string.h Normal file
View File

@ -0,0 +1,45 @@
#ifndef OPP_STRING_H
#define OPP_STRING_H
class string
{
private:
char * cstr;
public:
string(void);
string(const string & s);
string(const char * s);
string(const char * s1, const char * s2);
~string(void);
string & operator=(const string & s);
string & operator=(const char * s);
string & operator+=(const string & s);
string & operator+=(const char * s);
string operator+(const string & s);
string operator+(const char * s);
bool operator==(const string & s) const;
bool operator==(const char * s) const;
bool operator!=(const string & s) const;
bool operator!=(const char * s) const;
bool operator<(const string & s) const;
bool operator<(const char * s) const;
bool operator<=(const string & s) const;
bool operator<=(const char * s) const;
bool operator>(const string & s) const;
bool operator>(const char * s) const;
bool operator>=(const string & s) const;
bool operator>=(const char * s) const;
const char * tocstr(void) const;
};
#pragma compile("string.cpp")
#endif

View File

@ -801,6 +801,15 @@ int Declaration::Stride(void) const
return mStride > 0 ? mStride : mBase->mSize; return mStride > 0 ? mStride : mBase->mSize;
} }
Declaration* Declaration::BuildPointer(const Location& loc)
{
Declaration* pdec = new Declaration(loc, DT_TYPE_POINTER);
pdec->mBase = this;
pdec->mFlags = DTF_DEFINED;
pdec->mSize = 2;
return pdec;
}
Declaration* Declaration::Last(void) Declaration* Declaration::Last(void)
{ {
mPrev = nullptr; mPrev = nullptr;

View File

@ -262,6 +262,8 @@ public:
Declaration* Clone(void); Declaration* Clone(void);
Declaration* Last(void); Declaration* Last(void);
Declaration* BuildPointer(const Location& loc);
int Stride(void) const; int Stride(void) const;
}; };

View File

@ -48,6 +48,8 @@ void Parser::AddMemberFunction(Declaration* dec, Declaration* mdec)
pcdec->mNext = mdec; pcdec->mNext = mdec;
dec->mScope->Insert(mdec->mIdent, gdec); dec->mScope->Insert(mdec->mIdent, gdec);
if (dec->mConst)
dec->mConst->mScope->Insert(mdec->mIdent, gdec);
} }
else else
mErrors->Error(mdec->mLocation, EERR_DUPLICATE_DEFINITION, "Duplicate struct member declaration", mdec->mIdent); mErrors->Error(mdec->mLocation, EERR_DUPLICATE_DEFINITION, "Duplicate struct member declaration", mdec->mIdent);
@ -2993,6 +2995,9 @@ Declaration* Parser::ParseDeclaration(Declaration * pdec, bool variable, bool ex
Declaration * bthis = new Declaration(mScanner->mLocation, DT_TYPE_POINTER); Declaration * bthis = new Declaration(mScanner->mLocation, DT_TYPE_POINTER);
bthis->mFlags |= DTF_CONST | DTF_DEFINED; bthis->mFlags |= DTF_CONST | DTF_DEFINED;
if (ConsumeTokenIf(TK_CONST))
bthis->mBase = bdec->ToConstType();
else
bthis->mBase = bdec; bthis->mBase = bdec;
bthis->mSize = 2; bthis->mSize = 2;
@ -3128,9 +3133,10 @@ Declaration* Parser::ParseDeclaration(Declaration * pdec, bool variable, bool ex
{ {
if (ndec->mBase->mType == DT_TYPE_FUNCTION && pthis) if (ndec->mBase->mType == DT_TYPE_FUNCTION && pthis)
{ {
if (ConsumeTokenIf(TK_CONST))
PrependThisArgument(ndec->mBase, pthis->mBase->ToConstType()->BuildPointer(ndec->mLocation));
else
PrependThisArgument(ndec->mBase, pthis); PrependThisArgument(ndec->mBase, pthis);
} }
if (variable) if (variable)
@ -3180,6 +3186,9 @@ Declaration* Parser::ParseDeclaration(Declaration * pdec, bool variable, bool ex
Declaration* adec = pdec->mBase->mParams->Clone(); Declaration* adec = pdec->mBase->mParams->Clone();
adec->mNext = ndec->mBase->mParams; adec->mNext = ndec->mBase->mParams;
if (ConsumeTokenIf(TK_CONST))
adec->mBase = adec->mBase->mBase->ToConstType()->BuildPointer(adec->mLocation);
Declaration* p = adec->mBase->mParams; Declaration* p = adec->mBase->mParams;
while (p) while (p)
{ {
@ -3230,6 +3239,8 @@ Declaration* Parser::ParseDeclaration(Declaration * pdec, bool variable, bool ex
} }
} }
pdec->mFlags |= ndec->mFlags & DTF_REQUEST_INLINE;
ndec = pdec; ndec = pdec;
} }
} }
@ -4603,6 +4614,8 @@ Expression* Parser::ParseShiftExpression(bool lhs)
nexp->mDecType = exp->mDecType; nexp->mDecType = exp->mDecType;
exp = nexp->ConstantFold(mErrors); exp = nexp->ConstantFold(mErrors);
exp = CheckOperatorOverload(exp);
} }
return exp; return exp;
@ -4622,6 +4635,8 @@ Expression* Parser::ParseRelationalExpression(bool lhs)
nexp->mDecType = TheBoolTypeDeclaration; nexp->mDecType = TheBoolTypeDeclaration;
exp = nexp->ConstantFold(mErrors); exp = nexp->ConstantFold(mErrors);
exp = CheckOperatorOverload(exp);
} }
return exp; return exp;
@ -4641,6 +4656,8 @@ Expression* Parser::ParseBinaryAndExpression(bool lhs)
nexp->mDecType = exp->mDecType; nexp->mDecType = exp->mDecType;
exp = nexp->ConstantFold(mErrors); exp = nexp->ConstantFold(mErrors);
exp = CheckOperatorOverload(exp);
} }
return exp; return exp;
@ -4659,6 +4676,8 @@ Expression* Parser::ParseBinaryXorExpression(bool lhs)
nexp->mRight = ParseBinaryAndExpression(false); nexp->mRight = ParseBinaryAndExpression(false);
nexp->mDecType = exp->mDecType; nexp->mDecType = exp->mDecType;
exp = nexp->ConstantFold(mErrors); exp = nexp->ConstantFold(mErrors);
exp = CheckOperatorOverload(exp);
} }
return exp; return exp;
@ -4677,6 +4696,8 @@ Expression* Parser::ParseBinaryOrExpression(bool lhs)
nexp->mRight = ParseBinaryXorExpression(false); nexp->mRight = ParseBinaryXorExpression(false);
nexp->mDecType = exp->mDecType; nexp->mDecType = exp->mDecType;
exp = nexp->ConstantFold(mErrors); exp = nexp->ConstantFold(mErrors);
exp = CheckOperatorOverload(exp);
} }
return exp; return exp;
@ -4772,9 +4793,47 @@ Expression* Parser::CheckOperatorOverload(Expression* exp)
Declaration* tdec = exp->mLeft->mDecType; Declaration* tdec = exp->mLeft->mDecType;
if (tdec->mType == DT_TYPE_STRUCT) if (tdec->mType == DT_TYPE_STRUCT)
{ {
if (exp->mToken == TK_ASSIGN) const Ident* opident = nullptr;
switch (exp->mToken)
{ {
Declaration* mdec = tdec->mScope->Lookup(Ident::Unique("operator=")); case TK_ASSIGN:
opident = Ident::Unique("operator=");
break;
case TK_ASSIGN_ADD:
opident = Ident::Unique("operator+=");
break;
case TK_ASSIGN_SUB:
opident = Ident::Unique("operator-=");
break;
case TK_ASSIGN_MUL:
opident = Ident::Unique("operator*=");
break;
case TK_ASSIGN_DIV:
opident = Ident::Unique("operator/=");
break;
case TK_ASSIGN_MOD:
opident = Ident::Unique("operator%=");
break;
case TK_ASSIGN_SHL:
opident = Ident::Unique("operator<<=");
break;
case TK_ASSIGN_SHR:
opident = Ident::Unique("operator>>=");
break;
case TK_ASSIGN_AND:
opident = Ident::Unique("operator&=");
break;
case TK_ASSIGN_XOR:
opident = Ident::Unique("operator^=");
break;
case TK_ASSIGN_OR:
opident = Ident::Unique("operator|=");
break;
}
if (opident)
{
Declaration* mdec = tdec->mScope->Lookup(opident);
if (mdec) if (mdec)
{ {
Expression * nexp = new Expression(mScanner->mLocation, EX_CALL); Expression * nexp = new Expression(mScanner->mLocation, EX_CALL);
@ -4807,7 +4866,7 @@ Expression* Parser::CheckOperatorOverload(Expression* exp)
} }
} }
} }
else if (exp->mType == EX_BINARY) else if (exp->mType == EX_BINARY || exp->mType == EX_RELATIONAL)
{ {
const Ident* opident = nullptr; const Ident* opident = nullptr;
switch (exp->mToken) switch (exp->mToken)
@ -4816,17 +4875,50 @@ Expression* Parser::CheckOperatorOverload(Expression* exp)
opident = Ident::Unique("operator+"); opident = Ident::Unique("operator+");
break; break;
case TK_SUB: case TK_SUB:
opident = Ident::Unique("operator+"); opident = Ident::Unique("operator-");
break; break;
case TK_MUL: case TK_MUL:
opident = Ident::Unique("operator+"); opident = Ident::Unique("operator*");
break; break;
case TK_DIV: case TK_DIV:
opident = Ident::Unique("operator+"); opident = Ident::Unique("operator/");
break; break;
case TK_MOD: case TK_MOD:
opident = Ident::Unique("operator%"); opident = Ident::Unique("operator%");
break; break;
case TK_BINARY_AND:
opident = Ident::Unique("operator&");
break;
case TK_BINARY_OR:
opident = Ident::Unique("operator|");
break;
case TK_BINARY_XOR:
opident = Ident::Unique("operator^");
break;
case TK_LEFT_SHIFT:
opident = Ident::Unique("operator<<");
break;
case TK_RIGHT_SHIFT:
opident = Ident::Unique("operator>>");
break;
case TK_EQUAL:
opident = Ident::Unique("operator==");
break;
case TK_NOT_EQUAL:
opident = Ident::Unique("operator!=");
break;
case TK_GREATER_THAN:
opident = Ident::Unique("operator>");
break;
case TK_GREATER_EQUAL:
opident = Ident::Unique("operator>=");
break;
case TK_LESS_THAN:
opident = Ident::Unique("operator<");
break;
case TK_LESS_EQUAL:
opident = Ident::Unique("operator<=");
break;
} }
if (opident) if (opident)
@ -4851,7 +4943,7 @@ Expression* Parser::CheckOperatorOverload(Expression* exp)
texp->mLeft = exp->mLeft; texp->mLeft = exp->mLeft;
texp->mDecType = new Declaration(nexp->mLocation, DT_TYPE_POINTER); texp->mDecType = new Declaration(nexp->mLocation, DT_TYPE_POINTER);
texp->mDecType->mFlags |= DTF_CONST | DTF_DEFINED; texp->mDecType->mFlags |= DTF_CONST | DTF_DEFINED;
texp->mDecType->mBase = exp->mDecType; texp->mDecType->mBase = exp->mLeft->mDecType;
texp->mDecType->mSize = 2; texp->mDecType->mSize = 2;
Expression* lexp = new Expression(nexp->mLocation, EX_LIST); Expression* lexp = new Expression(nexp->mLocation, EX_LIST);

View File

@ -1415,6 +1415,37 @@ void Scanner::NextRawToken(void)
mTokenIdent = Ident::Unique("operator="); mTokenIdent = Ident::Unique("operator=");
break; break;
case TK_ASSIGN_ADD:
mTokenIdent = Ident::Unique("operator+=");
break;
case TK_ASSIGN_SUB:
mTokenIdent = Ident::Unique("operator-=");
break;
case TK_ASSIGN_MUL:
mTokenIdent = Ident::Unique("operator*=");
break;
case TK_ASSIGN_DIV:
mTokenIdent = Ident::Unique("operator/=");
break;
case TK_ASSIGN_MOD:
mTokenIdent = Ident::Unique("operator%=");
break;
case TK_ASSIGN_SHL:
mTokenIdent = Ident::Unique("operator<<=");
break;
case TK_ASSIGN_SHR:
mTokenIdent = Ident::Unique("operator>>=");
break;
case TK_ASSIGN_AND:
mTokenIdent = Ident::Unique("operator&=");
break;
case TK_ASSIGN_XOR:
mTokenIdent = Ident::Unique("operator^=");
break;
case TK_ASSIGN_OR:
mTokenIdent = Ident::Unique("operator|=");
break;
case TK_ADD: case TK_ADD:
mTokenIdent = Ident::Unique("operator+"); mTokenIdent = Ident::Unique("operator+");
break; break;
@ -1431,6 +1462,42 @@ void Scanner::NextRawToken(void)
mTokenIdent = Ident::Unique("operator%"); mTokenIdent = Ident::Unique("operator%");
break; break;
case TK_BINARY_AND:
mTokenIdent = Ident::Unique("operator&");
break;
case TK_BINARY_OR:
mTokenIdent = Ident::Unique("operator|");
break;
case TK_BINARY_XOR:
mTokenIdent = Ident::Unique("operator^");
break;
case TK_LEFT_SHIFT:
mTokenIdent = Ident::Unique("operator<<");
break;
case TK_RIGHT_SHIFT:
mTokenIdent = Ident::Unique("operator>>");
break;
case TK_EQUAL:
mTokenIdent = Ident::Unique("operator==");
break;
case TK_NOT_EQUAL:
mTokenIdent = Ident::Unique("operator!=");
break;
case TK_GREATER_THAN:
mTokenIdent = Ident::Unique("operator>");
break;
case TK_GREATER_EQUAL:
mTokenIdent = Ident::Unique("operator>=");
break;
case TK_LESS_THAN:
mTokenIdent = Ident::Unique("operator<");
break;
case TK_LESS_EQUAL:
mTokenIdent = Ident::Unique("operator<=");
break;
default: default:
mErrors->Error(mLocation, EERR_INVALID_OPERATOR, "Invalid operator token"); mErrors->Error(mLocation, EERR_INVALID_OPERATOR, "Invalid operator token");
} }