First shot implementing constexpr

This commit is contained in:
drmortalwombat 2023-09-08 20:12:38 +02:00
parent cb352fcc7c
commit ab273181f5
14 changed files with 1388 additions and 66 deletions

View File

@ -30,6 +30,9 @@ bool isfinite(float f);
#pragma intrinsic(floor)
#pragma intrinsic(ceil)
#pragma intrinsic(sin)
#pragma intrinsic(cos)
#pragma compile("math.c")

1133
oscar64/Constexpr.cpp Normal file

File diff suppressed because it is too large Load Diff

89
oscar64/Constexpr.h Normal file
View File

@ -0,0 +1,89 @@
#pragma once
#include "Declaration.h"
class ConstexprInterpreter
{
public:
ConstexprInterpreter(const Location & loc, Errors * err, LinkerSection * dataSection);
~ConstexprInterpreter(void);
Expression* EvalCall(Expression* exp);
protected:
struct Value;
struct ValueItem
{
uint8 mByte;
Value* mBaseValue;
ValueItem(void);
};
struct Value
{
~Value(void);
Value(const Location& location);
Value(Expression * exp);
Value(const Location& location, Declaration * dec);
Value(const Value& value);
Value(Value&& value);
Value(Value * value, Declaration * type, int offset);
Value(Value* value);
Value(const Location& location, const uint8 * data, Declaration* type);
Value(const Location& location, const ValueItem* data, Declaration* type);
Value(void);
Value& operator=(const Value& v);
Value& operator=(Value&& v);
Value ToRValue(void) const;
Expression* ToExpression(LinkerSection* dataSection) const;
void Assign(const Value& v);
Location mLocation;
Declaration * mDecType;
Value * mBaseValue;
int mOffset;
ValueItem * mData;
int mDataSize;
ValueItem mShortData[4];
ValueItem* GetAddr(void);
const ValueItem* GetAddr(void) const;
int64 GetInt(void) const;
double GetFloat(void) const;
Value GetPtr(void) const;
void PutInt(int64 v);
void PutFloat(double v);
void PutPtr(const Value& v);
int64 GetIntAt(int at, Declaration* type) const;
double GetFloatAt(int at, Declaration* type) const;
Value GetPtrAt(int at, Declaration* type) const;
void PutIntAt(int64 v, int at, Declaration* type);
void PutFloatAt(double v, int at, Declaration* type);
void PutPtrAt(const Value& v, int at, Declaration* type);
void PutConst(int offset, Declaration * dec);
Declaration* GetConst(int offset, Declaration* type, LinkerSection* dataSection) const;
};
Value EvalCall(Expression* exp, ConstexprInterpreter* caller);
Value EvalBinary(Expression* exp, const Value& vl, const Value& vr);
Value EvalUnary(Expression* exp, const Value& vl);
Value EvalRelational(Expression* exp, const Value& vl, const Value& vr);
Value EvalTypeCast(Expression* exp, const Value& vl, Declaration* type);
Value EvalCoerce(Expression* exp, const Value& vl, Declaration* type);
Value REval(Expression* exp);
Value Eval(Expression* exp);
Declaration* mProcType;
Location mLocation;
LinkerSection* mDataSection;
GrowingArray<Value> mParams, mLocals;
Errors * mErrors;
Value mResult;
};

View File

@ -1,4 +1,6 @@
#include "Declaration.h"
#include "Constexpr.h"
#include <math.h>
DeclarationScope::DeclarationScope(DeclarationScope* parent, ScopeLevel level, const Ident* name)
{
@ -430,7 +432,7 @@ Expression* Expression::LogicInvertExpression(void)
}
}
Expression* Expression::ConstantFold(Errors * errors)
Expression* Expression::ConstantFold(Errors * errors, LinkerSection * dataSection)
{
if (mType == EX_PREFIX && mLeft->mType == EX_CONSTANT)
{
@ -775,9 +777,9 @@ Expression* Expression::ConstantFold(Errors * errors)
if (mLeft->mDecValue->mType == DT_CONST_INTEGER)
{
if (mLeft->mDecValue->mInteger != 0)
return mRight->mLeft->ConstantFold(errors);
return mRight->mLeft->ConstantFold(errors, dataSection);
else
return mRight->mRight->ConstantFold(errors);
return mRight->mRight->ConstantFold(errors, dataSection);
}
}
else if (mType == EX_BINARY && mToken == TK_ADD && mLeft->mType == EX_VARIABLE && mLeft->mDecValue->mType == DT_VARIABLE && (mLeft->mDecValue->mFlags & DTF_GLOBAL) && mLeft->mDecType->mType == DT_TYPE_ARRAY && mRight->mType == EX_CONSTANT && mRight->mDecValue->mType == DT_CONST_INTEGER)
@ -807,7 +809,7 @@ Expression* Expression::ConstantFold(Errors * errors)
else if (mType == EX_BINARY && mToken == TK_ADD && mLeft->mType == EX_VARIABLE && mLeft->mDecValue->mType == DT_VARIABLE && (mLeft->mDecValue->mFlags & DTF_CONST) && mLeft->mDecType->mType == DT_TYPE_POINTER && mRight->mType == EX_CONSTANT && mRight->mDecValue->mType == DT_CONST_INTEGER)
{
mLeft = mLeft->mDecValue->mValue;
return this->ConstantFold(errors);
return this->ConstantFold(errors, dataSection);
}
else if (mType == EX_QUALIFY && mLeft->mType == EX_VARIABLE && mLeft->mDecValue->mType == DT_VARIABLE && (mLeft->mDecValue->mFlags & DTF_GLOBAL) && mLeft->mDecType->mType == DT_TYPE_STRUCT)
{
@ -833,6 +835,44 @@ Expression* Expression::ConstantFold(Errors * errors)
ex->mDecType = mDecType;
return ex;
}
else if (mType == EX_CALL && mLeft->mType == EX_CONSTANT && (mLeft->mDecValue->mFlags & DTF_INTRINSIC) && mRight->mType == EX_CONSTANT)
{
Declaration* decf = mLeft->mDecValue, * decp = mRight->mDecValue;
const Ident* iname = decf->mQualIdent;
if (decp->mType == DT_TYPE_FLOAT || decp->mType == DT_TYPE_INTEGER)
{
double d = decp->mType == DT_TYPE_FLOAT ? decp->mNumber : decp->mInteger;
bool check = false;
if (!strcmp(iname->mString, "fabs"))
d = fabs(d);
else if (!strcmp(iname->mString, "floor"))
d = floor(d);
else if (!strcmp(iname->mString, "ceil"))
d = ceil(d);
else if (!strcmp(iname->mString, "sin"))
d = sin(d);
else if (!strcmp(iname->mString, "cos"))
d = cos(d);
else
return this;
Expression* ex = new Expression(mLocation, EX_CONSTANT);
Declaration* dec = new Declaration(mLocation, DT_CONST_FLOAT);
dec->mBase = TheFloatTypeDeclaration;
dec->mNumber = d;
ex->mDecValue = dec;
ex->mDecType = dec->mBase;
return ex;
}
}
else if (mType == EX_CALL && mLeft->mType == EX_CONSTANT && (mLeft->mDecValue->mFlags & DTF_CONSTEXPR))
{
ConstexprInterpreter cinter(mLocation, errors, dataSection);
return cinter.EvalCall(this);
}
return this;
}
@ -1195,7 +1235,7 @@ bool Declaration::ResolveTemplate(Declaration* fdec, Declaration* tdec)
Declaration *ftdec = tdec->mTemplate;
while (ftdec)
{
if (ftdec->mBase == fdec)
if (ftdec->mBase->IsConstSame(fdec))
{
Declaration* fpdec = ftdec->mParams;
Declaration* tpdec = tdec->mTemplate->mParams;
@ -1361,6 +1401,7 @@ Declaration* Declaration::ToConstType(void)
ndec->mParams = mParams;
ndec->mIdent = mIdent;
ndec->mQualIdent = mQualIdent;
ndec->mTemplate = mTemplate;
ndec->mDefaultConstructor = mDefaultConstructor;
ndec->mCopyConstructor = mCopyConstructor;
@ -1392,6 +1433,7 @@ Declaration* Declaration::ToMutableType(void)
ndec->mParams = mParams;
ndec->mIdent = mIdent;
ndec->mQualIdent = mQualIdent;
ndec->mTemplate = mTemplate;
ndec->mDefaultConstructor = mDefaultConstructor;
ndec->mCopyConstructor = mCopyConstructor;
@ -1926,6 +1968,7 @@ Declaration* TheVoidTypeDeclaration, * TheConstVoidTypeDeclaration, * TheSignedI
Declaration* TheBoolTypeDeclaration, * TheFloatTypeDeclaration, * TheConstVoidPointerTypeDeclaration, * TheVoidPointerTypeDeclaration, * TheSignedLongTypeDeclaration, * TheUnsignedLongTypeDeclaration;
Declaration* TheVoidFunctionTypeDeclaration, * TheConstVoidValueDeclaration;
Declaration* TheCharPointerTypeDeclaration, * TheConstCharPointerTypeDeclaration;
Expression* TheVoidExpression;
void InitDeclarations(void)
{
@ -2004,4 +2047,8 @@ void InitDeclarations(void)
TheConstCharPointerTypeDeclaration->mBase = TheConstCharTypeDeclaration;
TheConstCharPointerTypeDeclaration->mSize = 2;
TheConstCharPointerTypeDeclaration->mFlags = DTF_DEFINED;
TheVoidExpression = new Expression(noloc, EX_CONSTANT);
TheVoidExpression->mDecType = TheConstVoidTypeDeclaration;
TheVoidExpression->mDecValue = TheConstVoidValueDeclaration;
}

View File

@ -93,6 +93,7 @@ static const uint64 DTF_PROTECTED = (1ULL << 27);
static const uint64 DTF_VIRTUAL = (1ULL << 28);
static const uint64 DTF_TEMPORARY = (1ULL << 29);
static const uint64 DTF_COMPLETED = (1ULL << 30);
static const uint64 DTF_CONSTEXPR = (1ULL << 31);
static const uint64 DTF_FUNC_VARIABLE = (1ULL << 32);
static const uint64 DTF_FUNC_ASSEMBLER = (1ULL << 33);
@ -236,7 +237,7 @@ public:
bool mConst;
Expression* LogicInvertExpression(void);
Expression* ConstantFold(Errors * errors);
Expression* ConstantFold(Errors * errors, LinkerSection* dataSection);
bool HasSideEffects(void) const;
bool IsSame(const Expression* exp) const;
@ -328,4 +329,5 @@ extern Declaration* TheVoidTypeDeclaration, * TheConstVoidTypeDeclaration, * The
extern Declaration* TheBoolTypeDeclaration, * TheFloatTypeDeclaration, * TheVoidPointerTypeDeclaration, * TheConstVoidPointerTypeDeclaration, * TheSignedLongTypeDeclaration, * TheUnsignedLongTypeDeclaration;
extern Declaration* TheVoidFunctionTypeDeclaration, * TheConstVoidValueDeclaration;
extern Declaration* TheCharPointerTypeDeclaration, * TheConstCharPointerTypeDeclaration;
extern Expression* TheVoidExpression;

View File

@ -84,6 +84,8 @@ enum ErrorID
EERR_TEMPLATE_PARAMS,
EERR_FUNCTION_TEMPLATE,
EERR_INVALID_CONSTEXPR,
ERRR_STACK_OVERFLOW,
ERRR_INVALID_NUMBER,
EERR_OVERLAPPING_DATA_SECTIONS,

View File

@ -16921,7 +16921,7 @@ void InterCodeProcedure::Close(void)
{
GrowingTypeArray tstack(IT_NONE);
CheckFunc = !strcmp(mIdent->mString, "opp::sort<struct bindexlist<i16,10>::iterator,>");
CheckFunc = !strcmp(mIdent->mString, "main");
mEntryBlock = mBlocks[0];
@ -18444,7 +18444,7 @@ void InterCodeProcedure::Disassemble(FILE* file)
void InterCodeProcedure::Disassemble(const char* name, bool dumpSets)
{
#if 1
#if 0
#ifdef _WIN32
FILE* file;
static bool initial = true;

View File

@ -100,6 +100,13 @@ InterCodeGenerator::ExValue InterCodeGenerator::CoerceType(InterCodeProcedure* p
return v;
}
if (v.mType->IsReference() && type->IsSimpleType())
{
v.mReference++;
v.mType = v.mType->mBase;
v = Dereference(proc, exp, block, v);
}
if (v.mType->IsIntegerType() && type->mType == DT_TYPE_FLOAT)
{
if (v.mType->mSize == 1)
@ -2878,6 +2885,12 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
return ExValue(TheFloatTypeDeclaration, ins->mDst.mTemp);
}
else if (!strcmp(iname->mString, "sin"))
{
}
else if (!strcmp(iname->mString, "cos"))
{
}
else if (!strcmp(iname->mString, "malloc"))
{
vr = TranslateExpression(procType, proc, block, exp->mRight, destack, breakBlock, continueBlock, inlineMapper);
@ -4734,7 +4747,7 @@ InterCodeProcedure* InterCodeGenerator::TranslateProcedure(InterCodeModule * mod
InterCodeProcedure* proc = new InterCodeProcedure(mod, dec->mLocation, dec->mQualIdent, mLinker->AddObject(dec->mLocation, dec->mQualIdent, dec->mSection, LOT_BYTE_CODE, dec->mAlignment));
#if 0
if (proc->mIdent && !strcmp(proc->mIdent->mString, "test"))
if (proc->mIdent && !strcmp(proc->mIdent->mString, "main"))
exp->Dump(0);
#endif
#if 0

View File

@ -508,6 +508,31 @@ Declaration* Parser::ParseStructDeclaration(uint64 flags, DecType dt, Declaratio
return dec;
}
Declaration* Parser::ParseBaseTypeQualify(bool qualified, Declaration* dec, const Ident*& pident)
{
while (dec && (dec->mType == DT_NAMESPACE || (qualified && (dec->mType == DT_TYPE_STRUCT || dec->mType == DT_TYPE_TEMPLATE))) && ConsumeTokenIf(TK_COLCOLON))
{
if (ExpectToken(TK_IDENT))
{
pident = mScanner->mTokenIdent;
if (dec->mType == DT_TYPE_TEMPLATE)
{
Declaration* ndec = new Declaration(mScanner->mLocation, DT_TYPE_TEMPLATE);
ndec->mFlags |= DTF_DEFINED;
ndec->mBase = dec;
ndec->mIdent = pident;
dec = ndec;
}
else
dec = dec->mScope->Lookup(pident);
mScanner->NextToken();
}
}
return dec;
}
Declaration* Parser::ParseBaseTypeDeclaration(uint64 flags, bool qualified, Declaration* ptempl)
{
Declaration* dec = nullptr;
@ -633,31 +658,15 @@ Declaration* Parser::ParseBaseTypeDeclaration(uint64 flags, bool qualified, Decl
mScanner->NextToken();
dec = ParseBaseTypeQualify(qualified, dec, pident);
if (dec && dec->mTemplate)
dec = ParseTemplateExpansion(dec->mTemplate, nullptr);
}
else
mScanner->NextToken();
while (qualified && dec && (dec->mType == DT_TYPE_STRUCT || dec->mType == DT_NAMESPACE || dec->mType == DT_TYPE_TEMPLATE) && ConsumeTokenIf(TK_COLCOLON))
{
if (ExpectToken(TK_IDENT))
{
pident = mScanner->mTokenIdent;
if (dec->mType == DT_TYPE_TEMPLATE)
{
Declaration* ndec = new Declaration(mScanner->mLocation, DT_TYPE_TEMPLATE);
ndec->mFlags |= DTF_DEFINED;
ndec->mBase = dec;
ndec->mIdent = mScanner->mTokenIdent;
dec = ndec;
}
else
dec = dec->mScope->Lookup(mScanner->mTokenIdent);
mScanner->NextToken();
}
}
dec = ParseBaseTypeQualify(qualified, dec, pident);
if (dec && dec->mType <= DT_TYPE_FUNCTION)
{
@ -3341,6 +3350,11 @@ Declaration* Parser::ParseDeclaration(Declaration * pdec, bool variable, bool ex
storageFlags |= DTF_STATIC;
mScanner->NextToken();
}
else if (mScanner->mToken == TK_CONSTEXPR)
{
storageFlags |= DTF_CONSTEXPR;
mScanner->NextToken();
}
else if (mScanner->mToken == TK_EXTERN)
{
storageFlags |= DTF_EXTERN;
@ -4035,7 +4049,11 @@ Declaration* Parser::ParseDeclaration(Declaration * pdec, bool variable, bool ex
ndec->mValue = ParseInitExpression(ndec->mBase);
if (ndec->mBase->mType == DT_TYPE_AUTO)
{
if (ndec->mBase->mFlags & DTF_CONST)
ndec->mBase = ndec->mValue->mDecType->ToConstType();
else
ndec->mBase = ndec->mValue->mDecType;
if (ndec->mBase->mType == DT_TYPE_ARRAY)
{
ndec->mBase = ndec->mBase->Clone();
@ -4603,7 +4621,7 @@ Expression* Parser::ParseSimpleExpression(bool lhs)
dexp->mDecType = texp->mDecType->mBase;
dexp->mLeft = texp;
dexp = dexp->ConstantFold(mErrors);
dexp = dexp->ConstantFold(mErrors, mDataSection);
exp = ParseQualify(dexp);
}
@ -4750,7 +4768,7 @@ Expression* Parser::ParseSimpleExpression(bool lhs)
Expression* nexp = new Expression(mScanner->mLocation, EX_TYPECAST);
nexp->mDecType = exp->mDecType;
nexp->mLeft = ParsePrefixExpression(false);
exp = nexp->ConstantFold(mErrors);
exp = nexp->ConstantFold(mErrors, mDataSection);
}
}
break;
@ -4830,7 +4848,7 @@ Expression* Parser::ParseQualify(Expression* exp)
{
Declaration* dtype = exp->mDecType;
exp = exp->ConstantFold(mErrors);
exp = exp->ConstantFold(mErrors, mDataSection);
if (dtype->mType == DT_TYPE_REFERENCE || dtype->mType == DT_TYPE_RVALUEREF)
dtype = dtype->mBase;
@ -4896,14 +4914,14 @@ Expression* Parser::ParseQualify(Expression* exp)
if (exp->mDecType->mFlags & DTF_CONST)
nexp->mDecType = nexp->mDecType->ToConstType();
exp = nexp->ConstantFold(mErrors);
exp = nexp->ConstantFold(mErrors, mDataSection);
}
else if (mdec->mType == DT_VARIABLE)
{
nexp = new Expression(mScanner->mLocation, EX_VARIABLE);
nexp->mDecValue = mdec;
nexp->mDecType = mdec->mBase;
exp = nexp->ConstantFold(mErrors);
exp = nexp->ConstantFold(mErrors, mDataSection);
}
else if (mdec->mType == DT_CONST_FUNCTION)
{
@ -5264,7 +5282,7 @@ Expression* Parser::CoerceExpression(Expression* exp, Declaration* type)
{
if (!type->IsConstSame(tdec))
{
Declaration* fcons = type->mScope->Lookup(type->mIdent->PreMangle("+"));
Declaration* fcons = type->mScope ? type->mScope->Lookup(type->mIdent->PreMangle("+")) : nullptr;
if (fcons)
{
while (fcons && !(fcons->mBase->mParams && fcons->mBase->mParams->mNext && !fcons->mBase->mParams->mNext->mNext && fcons->mBase->mParams->mNext->mBase->CanAssign(tdec)))
@ -5595,7 +5613,7 @@ Expression* Parser::ParsePostfixExpression(bool lhs)
Expression* nexp = new Expression(mScanner->mLocation, EX_TYPECAST);
nexp->mDecType = exp->mDecType;
nexp->mLeft = pexp;
exp = nexp->ConstantFold(mErrors);
exp = nexp->ConstantFold(mErrors, mDataSection);
}
else
{
@ -6162,7 +6180,7 @@ Expression* Parser::ParsePrefixExpression(bool lhs)
nexp->mDecType = nexp->mLeft->mDecType;
}
nexp = CheckOperatorOverload(nexp);
return nexp->ConstantFold(mErrors);
return nexp->ConstantFold(mErrors, mDataSection);
}
else
return ParsePostfixExpression(lhs);
@ -6187,7 +6205,7 @@ Expression* Parser::ParseMulExpression(bool lhs)
exp = CheckOperatorOverload(nexp);
exp = exp->ConstantFold(mErrors);
exp = exp->ConstantFold(mErrors, mDataSection);
}
return exp;
@ -6235,7 +6253,7 @@ Expression* Parser::ParseAddExpression(bool lhs)
exp = CheckOperatorOverload(nexp);
exp = exp->ConstantFold(mErrors);
exp = exp->ConstantFold(mErrors, mDataSection);
}
return exp;
@ -6254,7 +6272,7 @@ Expression* Parser::ParseShiftExpression(bool lhs)
nexp->mRight = ParseAddExpression(false);
nexp->mDecType = exp->mDecType;
exp = nexp->ConstantFold(mErrors);
exp = nexp->ConstantFold(mErrors, mDataSection);
exp = CheckOperatorOverload(exp);
}
@ -6275,7 +6293,7 @@ Expression* Parser::ParseRelationalExpression(bool lhs)
nexp->mRight = ParseShiftExpression(false);
nexp->mDecType = TheBoolTypeDeclaration;
exp = nexp->ConstantFold(mErrors);
exp = nexp->ConstantFold(mErrors, mDataSection);
exp = CheckOperatorOverload(exp);
}
@ -6296,7 +6314,7 @@ Expression* Parser::ParseBinaryAndExpression(bool lhs)
nexp->mRight = ParseRelationalExpression(false);
nexp->mDecType = exp->mDecType;
exp = nexp->ConstantFold(mErrors);
exp = nexp->ConstantFold(mErrors, mDataSection);
exp = CheckOperatorOverload(exp);
}
@ -6316,7 +6334,7 @@ Expression* Parser::ParseBinaryXorExpression(bool lhs)
mScanner->NextToken();
nexp->mRight = ParseBinaryAndExpression(false);
nexp->mDecType = exp->mDecType;
exp = nexp->ConstantFold(mErrors);
exp = nexp->ConstantFold(mErrors, mDataSection);
exp = CheckOperatorOverload(exp);
}
@ -6336,7 +6354,7 @@ Expression* Parser::ParseBinaryOrExpression(bool lhs)
mScanner->NextToken();
nexp->mRight = ParseBinaryXorExpression(false);
nexp->mDecType = exp->mDecType;
exp = nexp->ConstantFold(mErrors);
exp = nexp->ConstantFold(mErrors, mDataSection);
exp = CheckOperatorOverload(exp);
}
@ -6356,7 +6374,7 @@ Expression* Parser::ParseLogicAndExpression(bool lhs)
mScanner->NextToken();
nexp->mRight = CoerceExpression(ParseBinaryOrExpression(false), TheBoolTypeDeclaration);
nexp->mDecType = TheBoolTypeDeclaration;
exp = nexp->ConstantFold(mErrors);
exp = nexp->ConstantFold(mErrors, mDataSection);
}
return exp;
@ -6374,7 +6392,7 @@ Expression* Parser::ParseLogicOrExpression(bool lhs)
mScanner->NextToken();
nexp->mRight = CoerceExpression(ParseLogicAndExpression(false), TheBoolTypeDeclaration);
nexp->mDecType = TheBoolTypeDeclaration;
exp = nexp->ConstantFold(mErrors);
exp = nexp->ConstantFold(mErrors, mDataSection);
}
return exp;
@ -6397,7 +6415,7 @@ Expression* Parser::ParseConditionalExpression(bool lhs)
texp->mRight = ParseConditionalExpression(false);
nexp->mDecType = texp->mLeft->mDecType;
exp = nexp->ConstantFold(mErrors);
exp = nexp->ConstantFold(mErrors, mDataSection);
}
return exp;
@ -6405,7 +6423,7 @@ Expression* Parser::ParseConditionalExpression(bool lhs)
Expression* Parser::ParseRExpression(void)
{
return ParseConditionalExpression(false);
return ParseConditionalExpression(false)->ConstantFold(mErrors, mDataSection);
}
Expression* Parser::ParseParenthesisExpression(void)
@ -6515,7 +6533,7 @@ Expression* Parser::CheckOperatorOverload(Expression* exp)
texp->mDecType->mSize = 2;
Expression* lexp = new Expression(nexp->mLocation, EX_LIST);
lexp->mLeft = texp->ConstantFold(mErrors);
lexp->mLeft = texp->ConstantFold(mErrors, mDataSection);
lexp->mRight = nexp->mRight;
nexp->mRight = lexp;
@ -6533,7 +6551,7 @@ Expression* Parser::CheckOperatorOverload(Expression* exp)
while (tdec->mType == DT_TYPE_REFERENCE || tdec->mType == DT_TYPE_RVALUEREF)
tdec = tdec->mBase;
if (tdec->mType == DT_TYPE_STRUCT)
if (tdec->mType == DT_TYPE_STRUCT && tdec->mScope)
{
const Ident* opident = Ident::Unique("operator[]");
@ -6558,7 +6576,7 @@ Expression* Parser::CheckOperatorOverload(Expression* exp)
texp->mDecType->mSize = 2;
Expression* lexp = new Expression(nexp->mLocation, EX_LIST);
lexp->mLeft = texp->ConstantFold(mErrors);
lexp->mLeft = texp->ConstantFold(mErrors, mDataSection);
lexp->mRight = nexp->mRight;
nexp->mRight = lexp;
@ -6585,7 +6603,7 @@ Expression* Parser::CheckOperatorOverload(Expression* exp)
if (opident)
{
Declaration* tdec = exp->mLeft->mDecType;
if (tdec->mType == DT_TYPE_STRUCT)
if (tdec->mType == DT_TYPE_STRUCT && tdec->mScope)
{
Declaration* mdec = tdec->mScope->Lookup(opident);
if (mdec)
@ -6607,7 +6625,7 @@ Expression* Parser::CheckOperatorOverload(Expression* exp)
texp->mDecType->mBase = exp->mLeft->mDecType;
texp->mDecType->mSize = 2;
nexp->mRight = texp->ConstantFold(mErrors);
nexp->mRight = texp->ConstantFold(mErrors, mDataSection);
nexp = ResolveOverloadCall(nexp);
nexp->mDecType = nexp->mLeft->mDecType->mBase;
@ -6656,7 +6674,7 @@ Expression* Parser::CheckOperatorOverload(Expression* exp)
texp->mDecType->mSize = 2;
Expression* lexp = new Expression(nexp->mLocation, EX_LIST);
lexp->mLeft = texp->ConstantFold(mErrors);
lexp->mLeft = texp->ConstantFold(mErrors, mDataSection);
lexp->mRight = new Expression(nexp->mLocation, EX_CONSTANT);
lexp->mRight->mDecType = TheSignedIntTypeDeclaration;
lexp->mRight->mDecValue = new Declaration(nexp->mLocation, DT_CONST_INTEGER);
@ -6772,7 +6790,7 @@ Expression* Parser::CheckOperatorOverload(Expression* exp)
texp->mDecType->mSize = 2;
Expression* lexp = new Expression(nexp->mLocation, EX_LIST);
lexp->mLeft = texp->ConstantFold(mErrors);
lexp->mLeft = texp->ConstantFold(mErrors, mDataSection);
lexp->mRight = nexp->mRight;
nexp->mRight = lexp;
@ -6834,7 +6852,7 @@ Expression* Parser::CheckOperatorOverload(Expression* exp)
texp->mDecType->mBase = tdec;
texp->mDecType->mSize = 2;
nexp->mRight = texp->ConstantFold(mErrors);
nexp->mRight = texp->ConstantFold(mErrors, mDataSection);
nexp = ResolveOverloadCall(nexp);
nexp->mDecType = nexp->mLeft->mDecType->mBase;
@ -6873,7 +6891,7 @@ Expression* Parser::CheckOperatorOverload(Expression* exp)
texp->mDecType->mBase = tdec;
texp->mDecType->mSize = 2;
nexp->mRight = texp->ConstantFold(mErrors);
nexp->mRight = texp->ConstantFold(mErrors, mDataSection);
nexp = ResolveOverloadCall(nexp);
nexp->mDecType = nexp->mLeft->mDecType->mBase;
@ -7578,6 +7596,7 @@ Declaration* Parser::ParseTemplateExpansion(Declaration* tmpld, Declaration* exp
bdec->mTemplate = tdec;
bdec->mBase = tmpld->mBase;
tdec->mNext = tmpld;
bdec->mIdent = tdec->MangleIdent();
return bdec;
}
@ -7754,8 +7773,9 @@ void Parser::ParseTemplateDeclaration(void)
mTemplateScope = tdec->mScope;
ConsumeTokenIf(TK_INLINE);
ConsumeTokenIf(TK_CONSTEXPR);
Declaration* bdec = ParseBaseTypeDeclaration(0, false);
Declaration* bdec = ParseBaseTypeDeclaration(0, true);
Declaration* adec = ParsePostfixDeclaration();
adec = ReverseDeclaration(adec, bdec);
@ -7991,7 +8011,7 @@ Expression* Parser::ParseAssemblerMulOperand(Declaration* pcasm, int pcoffset)
nexp->mLeft = exp;
mScanner->NextToken();
nexp->mRight = ParseAssemblerBaseOperand(pcasm, pcoffset);
exp = nexp->ConstantFold(mErrors);
exp = nexp->ConstantFold(mErrors, mDataSection);
}
return exp;
}
@ -8050,7 +8070,7 @@ Expression* Parser::ParseAssemblerAddOperand(Declaration* pcasm, int pcoffset)
mErrors->Error(mScanner->mLocation, EERR_INCOMPATIBLE_OPERATOR, "Integer offset expected");
}
else
exp = nexp->ConstantFold(mErrors);
exp = nexp->ConstantFold(mErrors, mDataSection);
}
return exp;
}
@ -8065,7 +8085,7 @@ Expression* Parser::ParseAssemblerShiftOperand(Declaration* pcasm, int pcoffset)
nexp->mLeft = exp;
mScanner->NextToken();
nexp->mRight = ParseAssemblerAddOperand(pcasm, pcoffset);
exp = nexp->ConstantFold(mErrors);
exp = nexp->ConstantFold(mErrors, mDataSection);
}
return exp;
}
@ -8081,7 +8101,7 @@ Expression* Parser::ParseAssemblerAndOperand(Declaration* pcasm, int pcoffset)
nexp->mLeft = exp;
mScanner->NextToken();
nexp->mRight = ParseAssemblerShiftOperand(pcasm, pcoffset);
exp = nexp->ConstantFold(mErrors);
exp = nexp->ConstantFold(mErrors, mDataSection);
}
return exp;
}
@ -8096,7 +8116,7 @@ Expression* Parser::ParseAssemblerOrOperand(Declaration* pcasm, int pcoffset)
nexp->mLeft = exp;
mScanner->NextToken();
nexp->mRight = ParseAssemblerAndOperand(pcasm, pcoffset);
exp = nexp->ConstantFold(mErrors);
exp = nexp->ConstantFold(mErrors, mDataSection);
}
return exp;
}

View File

@ -57,6 +57,7 @@ protected:
Expression * AddFunctionCallRefReturned(Expression * exp);
Expression* CleanupExpression(Expression* exp);
Declaration* ParseBaseTypeQualify(bool qualified, Declaration* dec, const Ident *& pident);
Declaration* ParseBaseTypeDeclaration(uint64 flags, bool qualified, Declaration* ptempl = nullptr);
Declaration* ParseDeclaration(Declaration* pdec, bool variable, bool expression, Declaration * pthis = nullptr, Declaration * ptempl = nullptr);
Declaration* ParseStructDeclaration(uint64 flags, DecType dt, Declaration* ptempl = nullptr);

View File

@ -164,6 +164,7 @@ const char* TokenNames[] =
"'operator'",
"'template'",
"'friend'",
"'constexpr'",
};
@ -1514,6 +1515,8 @@ void Scanner::NextRawToken(void)
mToken = TK_TEMPLATE;
else if ((mCompilerOptions & COPT_CPLUSPLUS) && !strcmp(tkident, "friend"))
mToken = TK_FRIEND;
else if ((mCompilerOptions & COPT_CPLUSPLUS) && !strcmp(tkident, "constexpr"))
mToken = TK_CONSTEXPR;
else if ((mCompilerOptions & COPT_CPLUSPLUS) && !strcmp(tkident, "operator"))
{
NextRawToken();

View File

@ -163,6 +163,7 @@ enum Token
TK_OPERATOR,
TK_TEMPLATE,
TK_FRIEND,
TK_CONSTEXPR,
NUM_TOKENS
};

View File

@ -158,6 +158,7 @@
<ClCompile Include="ByteCodeGenerator.cpp" />
<ClCompile Include="CompilationUnits.cpp" />
<ClCompile Include="Compiler.cpp" />
<ClCompile Include="Constexpr.cpp" />
<ClCompile Include="Declaration.cpp" />
<ClCompile Include="Disassembler.cpp" />
<ClCompile Include="DiskImage.cpp" />
@ -184,6 +185,7 @@
<ClInclude Include="CompilationUnits.h" />
<ClInclude Include="Compiler.h" />
<ClInclude Include="CompilerTypes.h" />
<ClInclude Include="Constexpr.h" />
<ClInclude Include="Declaration.h" />
<ClInclude Include="Disassembler.h" />
<ClInclude Include="DiskImage.h" />

View File

@ -78,6 +78,9 @@
<ClCompile Include="DiskImage.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="Constexpr.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="Array.h">
@ -152,6 +155,9 @@
<ClInclude Include="DiskImage.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="Constexpr.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="oscar64.rc">