First shot implementing constexpr
This commit is contained in:
parent
cb352fcc7c
commit
ab273181f5
|
@ -30,6 +30,9 @@ bool isfinite(float f);
|
|||
#pragma intrinsic(floor)
|
||||
#pragma intrinsic(ceil)
|
||||
|
||||
#pragma intrinsic(sin)
|
||||
#pragma intrinsic(cos)
|
||||
|
||||
#pragma compile("math.c")
|
||||
|
||||
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -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;
|
||||
};
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -163,6 +163,7 @@ enum Token
|
|||
TK_OPERATOR,
|
||||
TK_TEMPLATE,
|
||||
TK_FRIEND,
|
||||
TK_CONSTEXPR,
|
||||
|
||||
NUM_TOKENS
|
||||
};
|
||||
|
|
|
@ -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" />
|
||||
|
|
|
@ -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">
|
||||
|
|
Loading…
Reference in New Issue