Fix pointers in constexpr

This commit is contained in:
drmortalwombat 2023-09-20 14:19:56 +02:00
parent e20c098ab1
commit a0409002b6
16 changed files with 1216 additions and 306 deletions

View File

@ -18,6 +18,9 @@ rem @echo off
@call :test opp_streamtest.cpp
@if %errorlevel% neq 0 goto :error
@call :test opp_pairtest.cpp
@if %errorlevel% neq 0 goto :error
@call :test operatoroverload.cpp
@if %errorlevel% neq 0 goto :error

28
autotest/opp_pairtest.cpp Normal file
View File

@ -0,0 +1,28 @@
#include <assert.h>
#include <opp/vector.h>
#include <opp/utility.h>
#include <opp/iostream.h>
using namespace opp;
int main(void)
{
vector<pair<int, int> > vii;
for(int i=0; i<100; i++)
vii.push_back(make_pair(i, i * i));
int sum1 = 0;
long sum2 = 0;
for(const auto & v : vii)
{
sum1 += v.first;
sum2 += v.second;
}
assert(sum1 == 4950);
assert(sum2 == 328350l);
return 0;
}

View File

@ -1,14 +0,0 @@
#ifndef OPP_MOVE_H
#define OPP_MOVE_H
namespace opp {
template <class T>
T && move(T & m)
{
return (T &&)m;
}
}
#endif

34
include/opp/utility.h Normal file
View File

@ -0,0 +1,34 @@
#ifndef OPP_UTILITY_H
#define OPP_UTILITY_H
namespace opp {
template <class T>
T && move(T & m)
{
return (T &&)m;
}
template<class T1, class T2>
struct pair
{
T1 first;
T2 second;
pair(T1 && t1, T2 && t2)
: first(t1), second(t2)
{}
};
template<class T1, class T2>
constexpr pair<T1, T2> make_pair(T1 && t1, T2 && t2)
{
return pair<T1, T2>(t1, t2);
}
}
#endif

View File

@ -2,7 +2,7 @@
#define OPP_VECTOR_H
#include <stdlib.h>
#include <opp/move.h>
#include <opp/utility.h>
namespace opp {

View File

@ -37,6 +37,7 @@ void ConstexprInterpreter::Value::PutConst(int offset, Declaration* dec)
switch (dec->mType)
{
case DT_CONST_INTEGER:
case DT_CONST_ADDRESS:
PutIntAt(dec->mInteger, offset, dec->mBase);
break;
case DT_CONST_FLOAT:
@ -46,6 +47,10 @@ void ConstexprInterpreter::Value::PutConst(int offset, Declaration* dec)
for (Declaration* pdec = dec->mParams; pdec; pdec = pdec->mNext)
PutConst(pdec->mOffset, pdec);
break;
case DT_CONST_DATA:
for (int i = 0; i < dec->mBase->mSize; i++)
PutIntAt(dec->mData[i], offset + i, TheConstCharTypeDeclaration);
break;
}
}
@ -116,8 +121,8 @@ ConstexprInterpreter::Value::Value(Value* value)
{
}
ConstexprInterpreter::Value::Value(Value* value, Declaration* type, int offset)
: mLocation(value->mLocation),
ConstexprInterpreter::Value::Value(const Location& location, Value* value, Declaration* type, int offset)
: mLocation(location),
mDecType(type),
mBaseValue(value), mOffset(offset),
mDataSize(0), mData(mShortData)
@ -331,7 +336,7 @@ ConstexprInterpreter::Value ConstexprInterpreter::Value::GetPtrAt(int at, Declar
{
const ValueItem* dp = GetAddr() + at;
return Value(dp->mBaseValue, type, uint16(dp[0].mByte | ((uint32)(dp[1].mByte) << 8)));
return Value(mLocation, dp->mBaseValue, type, uint16(dp[0].mByte | ((uint32)(dp[1].mByte) << 8)));
}
void ConstexprInterpreter::Value::PutIntAt(int64 v, int at, Declaration* type)
@ -448,19 +453,27 @@ Declaration* ConstexprInterpreter::Value::GetConst(int offset, Declaration* type
dec->mSize = type->mSize;
dec->mSection = dataSection;
dec->mOffset = offset;
Declaration* ldec = nullptr;
for (Declaration* mdec = type->mParams; mdec; mdec = mdec->mNext)
while (type)
{
Declaration * cdec = GetConst(offset + mdec->mOffset, mdec->mBase, dataSection);
cdec->mOffset = mdec->mOffset;
for (Declaration* mdec = type->mParams; mdec; mdec = mdec->mNext)
{
Declaration* cdec = GetConst(offset + mdec->mOffset, mdec->mBase, dataSection);
cdec->mOffset = mdec->mOffset;
if (ldec)
ldec->mNext = cdec;
if (ldec)
ldec->mNext = cdec;
else
dec->mParams = cdec;
ldec = cdec;
}
if (type->mBase)
type = type->mBase->mBase;
else
dec->mParams = cdec;
ldec = cdec;
type = nullptr;
}
break;
}
@ -486,6 +499,46 @@ Declaration* ConstexprInterpreter::Value::GetConst(int offset, Declaration* type
}
break;
}
case DT_TYPE_POINTER:
{
Value vp = GetPtrAt(offset, type);
if (vp.mBaseValue)
{
dec = new Declaration(mLocation, DT_CONST_POINTER);
dec->mBase = type;
dec->mSize = type->mSize;
Declaration* target;
if (vp.mBaseValue->mDecType->mType == DT_TYPE_ARRAY)
{
target = new Declaration(mLocation, DT_CONST_DATA);
target->mSize = vp.mBaseValue->mDataSize;
target->mBase = vp.mBaseValue->mDecType;
target->mSection = dataSection;
uint8* buffer = new uint8[target->mSize];
for (int i = 0; i < target->mSize; i++)
buffer[i] = uint8(vp.mBaseValue->GetIntAt(i, TheUnsignedCharTypeDeclaration));
target->mData = buffer;
}
else
target = vp.mBaseValue->GetConst(0, vp.mBaseValue->mDecType, dataSection);
dec->mValue = new Expression(mLocation, EX_CONSTANT);
dec->mValue->mDecType = target->mBase;
dec->mValue->mDecValue = target;
}
else
{
dec = new Declaration(mLocation, DT_CONST_ADDRESS);
dec->mBase = type;
dec->mFlags = 0;
dec->mSize = type->mSize;
dec->mInteger = vp.mOffset;
}
break;
}
}
@ -511,7 +564,8 @@ ConstexprInterpreter::ConstexprInterpreter(const Location & location, Errors* er
ConstexprInterpreter::~ConstexprInterpreter(void)
{
for (int i = 0; i < mTemps.Size(); i++)
delete mTemps[i];
}
ConstexprInterpreter::Value* ConstexprInterpreter::NewValue(Expression* exp, Declaration* type, int size)
@ -541,13 +595,30 @@ Expression* ConstexprInterpreter::EvalCall(Expression* exp)
Declaration* dec = exp->mLeft->mDecType->mParams;
int pos = 0;
if (mProcType->mBase && mProcType->mBase->mType == DT_TYPE_STRUCT)
{
mResult = Value(exp->mLocation, mProcType->mBase);
mParams[0] = Value(&mResult);
pos = 2;
}
while (pex && pex->mType == EX_LIST)
{
if (dec)
pos = dec->mVarIndex;
if (pex->mLeft->mType == EX_CONSTANT)
mParams[pos] = Value(pex->mLeft);
{
if (pex->mLeft->mDecType->mType == DT_TYPE_ARRAY)
{
Value * tmp = new Value(pex->mLeft);
mTemps.Push(tmp);
mParams[pos] = Value(pex->mLeft->mLocation, pex->mLeft->mDecType->BuildArrayPointer());
mParams[pos].PutPtr(Value(tmp));
}
else
mParams[pos] = Value(pex->mLeft);
}
else if (pex->mLeft->mType == EX_VARIABLE && (pex->mLeft->mDecValue->mFlags & DTF_CONST))
{
mParams[pos] = Value(pex->mLeft->mLocation, pex->mLeft->mDecValue->mBase);
@ -566,7 +637,17 @@ Expression* ConstexprInterpreter::EvalCall(Expression* exp)
pos = dec->mVarIndex;
if (pex->mType == EX_CONSTANT)
mParams[pos] = Value(pex);
{
if (pex->mDecType->mType == DT_TYPE_ARRAY)
{
Value* tmp = new Value(pex);
mTemps.Push(tmp);
mParams[pos] = Value(pex->mLocation, pex->mDecType->BuildArrayPointer());
mParams[pos].PutPtr(Value(tmp));
}
else
mParams[pos] = Value(pex);
}
else if (pex->mType == EX_VARIABLE && (pex->mDecValue->mFlags & DTF_CONST))
{
mParams[pos] = Value(pex->mLocation, pex->mDecValue->mBase);
@ -619,6 +700,12 @@ ConstexprInterpreter::Value ConstexprInterpreter::EvalBinary(Expression * exp, c
mErrors->Error(exp->mLocation, EERR_INCOMPATIBLE_OPERATOR, "Incompatible operator", TokenNames[exp->mToken]);
}
}
else if (exp->mDecType->mType == DT_TYPE_POINTER)
{
Value vlp = vl.GetPtr();
vlp.mOffset += int(vr.GetInt() * vl.mDecType->mBase->mSize);
v.PutPtr(vlp);
}
else
{
switch (exp->mToken)
@ -880,6 +967,13 @@ ConstexprInterpreter::Value ConstexprInterpreter::EvalCall(Expression* exp, Cons
Declaration* dec = exp->mLeft->mDecType->mParams;
int pos = 0;
if (mProcType->mBase && mProcType->mBase->mType == DT_TYPE_STRUCT)
{
mResult = Value(exp->mLocation, mProcType->mBase);
mParams[0] = Value(&mResult);
pos = 2;
}
while (pex && pex->mType == EX_LIST)
{
if (dec)
@ -1096,7 +1190,7 @@ ConstexprInterpreter::Value ConstexprInterpreter::Eval(Expression* exp)
{
Value v = Eval(exp->mLeft);
if (v.mBaseValue)
return Value(v.mBaseValue, exp->mDecType, v.mOffset + exp->mDecValue->mOffset);
return Value(exp->mLocation, v.mBaseValue, exp->mDecType, v.mOffset + exp->mDecValue->mOffset);
}
case EX_INDEX:
@ -1107,15 +1201,26 @@ ConstexprInterpreter::Value ConstexprInterpreter::Eval(Expression* exp)
if (v.mDecType->mType == DT_TYPE_ARRAY)
{
if (v.mBaseValue)
return Value(v.mBaseValue, exp->mDecType, v.mOffset + v.mDecType->mBase->mSize * int(vi.GetInt()));
return Value(exp->mLocation, v.mBaseValue, exp->mDecType, v.mOffset + v.mDecType->mBase->mSize * int(vi.GetInt()));
}
else if (v.mDecType->mType == DT_TYPE_POINTER)
{
Value p = v.GetPtr();
return Value(p.mBaseValue, exp->mDecType, p.mOffset + v.mDecType->mBase->mSize * int(vi.GetInt()));
return Value(exp->mLocation, p.mBaseValue, exp->mDecType, p.mOffset + v.mDecType->mBase->mSize * int(vi.GetInt()));
}
}
case EX_RESULT:
if (mParams[0].mBaseValue)
return mParams[0];
else
return Value(&mParams[0]);
case EX_CONSTRUCT:
if (exp->mLeft->mLeft)
Eval(exp->mLeft->mLeft);
return Eval(exp->mRight);
case EX_VOID:
return Value(exp->mLocation);
@ -1162,6 +1267,7 @@ ConstexprInterpreter::Flow ConstexprInterpreter::Execute(Expression* exp)
case EX_PREINCDEC:
case EX_QUALIFY:
case EX_INDEX:
case EX_RESULT:
Eval(exp);
return FLOW_NEXT;

View File

@ -29,7 +29,7 @@ protected:
Value(const Location& location, Declaration* dec, int count);
Value(const Value& value);
Value(Value&& value);
Value(Value * value, Declaration * type, int offset);
Value(const Location& location, 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);
@ -101,6 +101,7 @@ protected:
GrowingArray<Value> mParams, mLocals;
ExpandingArray<Expression*> mDestructStack;
ExpandingArray<Value *> * mHeap;
ExpandingArray<Value*> mTemps;
Errors * mErrors;
Value mResult;

View File

@ -303,6 +303,9 @@ void Expression::Dump(int ident) const
case EX_PACK:
printf("PACK");
break;
case EX_PACK_TYPE:
printf("PACK_TYPE");
break;
}
printf("\n");
@ -355,6 +358,16 @@ bool Expression::IsRValue(void) const
return true;
}
bool Expression::IsConstRef(void) const
{
if (mDecType->mType == DT_TYPE_RVALUEREF || mDecType->mType == DT_TYPE_REFERENCE)
return true;
else if (mType == EX_VARIABLE || mType == EX_QUALIFY || mType == EX_INDEX || mType == EX_PREFIX && mToken == TK_MUL)
return true;
else
return false;
}
bool Expression::IsLValue(void) const
{
if (mDecType->mFlags & DTF_CONST)
@ -996,7 +1009,7 @@ Declaration* Declaration::DeduceAuto(Declaration * dec)
if (dec->mType == DT_TYPE_ARRAY)
dec = dec->mBase->BuildPointer(mLocation);
if (mFlags & DTF_CONST)
if ((IsReference() ? mBase->mFlags : mFlags) & DTF_CONST)
dec = dec->ToConstType();
else
dec = dec->ToMutableType();
@ -1133,7 +1146,7 @@ const Ident* Declaration::MangleIdent(void)
}
else if (mType == DT_PACK_TYPE)
{
Declaration* dec = mBase;
Declaration* dec = mParams;
while (dec)
{
const Ident* id = dec->MangleIdent();
@ -1288,7 +1301,7 @@ bool Declaration::ResolveTemplate(Expression* pexp, Declaration* tdec)
tpdec->mIdent = pdec->mBase->mBase->mIdent;
else
tpdec->mIdent = pdec->mBase->mIdent;
tpdec->mBase = phead;
tpdec->mParams = phead;
mScope->Insert(tpdec->mIdent, tpdec);
}
else
@ -1434,25 +1447,66 @@ bool Declaration::ResolveTemplate(Declaration* fdec, Declaration* tdec)
Declaration *ftdec = tdec->mTemplate;
while (ftdec)
{
if (ftdec->mBase->IsConstSame(fdec))
if (ftdec->mBase->mQualIdent == fdec->mQualIdent)
{
Declaration* fpdec = ftdec->mParams;
Declaration* tpdec = tdec->mTemplate->mParams;
while (fpdec)
while (fpdec && tpdec)
{
if (tpdec->mBase->mType == DT_TYPE_TEMPLATE || tpdec->mBase->mType == DT_CONST_TEMPLATE)
{
Declaration * pdec = mScope->Insert(tpdec->mIdent, fpdec->mBase);
Declaration * pdec = mScope->Insert(tpdec->mBase->mIdent, fpdec->mBase);
if (pdec && !pdec->IsSame(fpdec->mBase))
return false;
}
else if (tpdec->mBase->mType == DT_PACK_TEMPLATE)
{
Declaration* tppack;
if (fpdec->mType == DT_PACK_TEMPLATE)
tppack = fpdec->mBase;
else
{
tppack = new Declaration(fpdec->mLocation, DT_PACK_TYPE);
Declaration* ppdec = nullptr;
while (fpdec)
{
if (fpdec->mType == DT_PACK_TEMPLATE)
{
if (ppdec)
ppdec->mNext = fpdec->mBase->mParams;
else
tppack->mParams = fpdec->mBase->mParams;
break;
}
Declaration* ndec = fpdec->mBase->Clone();
if (ppdec)
ppdec->mNext = ndec;
else
tppack->mParams = ndec;
ppdec = ndec;
fpdec = fpdec->mNext;
}
}
Declaration* pdec = mScope->Insert(tpdec->mBase->mIdent, tppack);
if (pdec && !pdec->IsSame(fpdec->mBase))
return false;
return true;
}
fpdec = fpdec->mNext;
tpdec = tpdec->mNext;
}
return true;
return !fpdec && !tpdec;
}
ftdec = ftdec->mNext;
@ -1604,6 +1658,7 @@ Declaration* Declaration::ToConstType(void)
ndec->mQualIdent = mQualIdent;
ndec->mTemplate = mTemplate;
ndec->mDestructor = mDestructor;
ndec->mDefaultConstructor = mDefaultConstructor;
ndec->mCopyConstructor = mCopyConstructor;
ndec->mMoveConstructor = mMoveConstructor;
@ -1636,6 +1691,7 @@ Declaration* Declaration::ToMutableType(void)
ndec->mQualIdent = mQualIdent;
ndec->mTemplate = mTemplate;
ndec->mDestructor = mDestructor;
ndec->mDefaultConstructor = mDefaultConstructor;
ndec->mCopyConstructor = mCopyConstructor;
ndec->mMoveConstructor = mMoveConstructor;
@ -1659,6 +1715,8 @@ bool Declaration::IsSameTemplate(const Declaration* dec) const
if (mType == DT_CONST_FUNCTION)
return mBase->IsSame(dec->mBase);
else if (mType == DT_TYPE_STRUCT)
return true;
return false;
}
@ -1673,7 +1731,7 @@ bool Declaration::IsSubType(const Declaration* dec) const
if (mType == DT_TYPE_POINTER || mType == DT_TYPE_ARRAY)
{
if (dec->mType == DT_TYPE_POINTER)
if (dec->mType == DT_TYPE_POINTER || dec->mType == DT_TYPE_ARRAY)
return /*this->Stride() == dec->Stride() &&*/ mBase->IsSubType(dec->mBase);
}
@ -1906,7 +1964,7 @@ bool Declaration::IsSameParams(const Declaration* dec) const
}
else if (mType == DT_PACK_TYPE && dec->mType == DT_PACK_TYPE)
{
Declaration* ld = mBase, * rd = dec->mBase;
Declaration* ld = mParams, * rd = dec->mParams;
while (ld && rd)
{
if (!ld->IsSame(rd))

View File

@ -222,7 +222,8 @@ enum ExpressionType
EX_CONSTRUCT,
EX_CLEANUP,
EX_RESULT,
EX_PACK
EX_PACK,
EX_PACK_TYPE,
};
class Expression
@ -247,6 +248,7 @@ public:
bool IsSame(const Expression* exp) const;
bool IsRValue(void) const;
bool IsLValue(void) const;
bool IsConstRef(void) const;
void Dump(int ident) const;
};

View File

@ -557,7 +557,7 @@ void GlobalAnalyzer::AnalyzeProcedure(Expression* exp, Declaration* dec)
while (pdec)
{
pdec->mVarIndex += vi;
if (pdec->mBase->mType == DT_TYPE_REFERENCE && pdec->mBase->mBase->IsSimpleType() && !(pdec->mBase->mFlags & DTF_VAR_ADDRESS) && (pdec->mBase->mBase->mFlags & DTF_CONST))
if (pdec->mBase->mType == DT_TYPE_REFERENCE && pdec->mBase->mBase->IsSimpleType() && !(pdec->mFlags & DTF_VAR_ADDRESS) && (pdec->mBase->mBase->mFlags & DTF_CONST))
{
pdec->mBase = pdec->mBase->mBase;
pdec->mSize = pdec->mBase->mSize;
@ -884,6 +884,8 @@ Declaration * GlobalAnalyzer::Analyze(Expression* exp, Declaration* procDec, boo
if (pex->mType == EX_CALL && IsStackParam(pex->mDecType) && !(pdec && (pdec->mBase->mType == DT_TYPE_REFERENCE || pdec->mBase->mType == DT_TYPE_RVALUEREF)))
ldec->mBase->mFlags |= DTF_STACKCALL;
RegisterProc(Analyze(pex, procDec, pdec && pdec->mBase->IsReference()));
if (pdec)
pdec = pdec->mNext;
@ -892,7 +894,6 @@ Declaration * GlobalAnalyzer::Analyze(Expression* exp, Declaration* procDec, boo
else
rex = nullptr;
}
RegisterProc(Analyze(exp->mRight, procDec, false));
}
break;
case EX_LIST:
@ -901,7 +902,7 @@ Declaration * GlobalAnalyzer::Analyze(Expression* exp, Declaration* procDec, boo
case EX_RETURN:
if (exp->mLeft)
{
RegisterProc(Analyze(exp->mLeft, procDec, false));
RegisterProc(Analyze(exp->mLeft, procDec, procDec->mBase->mBase->IsReference()));
if (procDec->mBase->mBase && procDec->mBase->mBase->mType == DT_TYPE_STRUCT && procDec->mBase->mBase->mCopyConstructor)
{
if (procDec->mBase->mBase->mMoveConstructor)
@ -1031,8 +1032,8 @@ Declaration * GlobalAnalyzer::Analyze(Expression* exp, Declaration* procDec, boo
procDec->mComplexity += exp->mDecType->mSize * 10;
ldec = Analyze(exp->mLeft, procDec, false);
RegisterProc(Analyze(exp->mRight->mLeft, procDec, false));
RegisterProc(Analyze(exp->mRight->mRight, procDec, false));
RegisterProc(Analyze(exp->mRight->mLeft, procDec, lhs));
RegisterProc(Analyze(exp->mRight->mRight, procDec, lhs));
break;
}

View File

@ -3679,6 +3679,34 @@ bool InterInstruction::RemoveUnusedStoreInstructions(const GrowingVariableArray&
}
}
}
else if (mCode == IC_SELECT)
{
if (mDst.mType == IT_POINTER)
{
if (mSrc[1].mTemp < 0)
{
if (mSrc[1].mMemory == IM_LOCAL)
{
requiredVars += mSrc[1].mVarIndex;
}
else if (mSrc[1].mMemory == paramMemory)
{
requiredParams += mSrc[1].mVarIndex;
}
}
if (mSrc[2].mTemp < 0)
{
if (mSrc[2].mMemory == IM_LOCAL)
{
requiredVars += mSrc[2].mVarIndex;
}
else if (mSrc[2].mMemory == paramMemory)
{
requiredParams += mSrc[2].mVarIndex;
}
}
}
}
else if (mCode == IC_CONSTANT)
{
if (mConst.mType == IT_POINTER)
@ -3809,6 +3837,22 @@ bool InterInstruction::RemoveUnusedStaticStoreInstructions(InterCodeBasicBlock*
}
}
}
else if (mCode == IC_SELECT)
{
if (mDst.mType == IT_POINTER)
{
if (mSrc[1].mTemp < 0)
{
if (mSrc[1].mMemory == IM_GLOBAL && mSrc[1].mVarIndex >= 0)
requiredVars += mSrc[1].mVarIndex;
}
if (mSrc[2].mTemp < 0)
{
if (mSrc[2].mMemory == IM_GLOBAL && mSrc[2].mVarIndex >= 0)
requiredVars += mSrc[2].mVarIndex;
}
}
}
else if (mCode == IC_COPY || mCode == IC_STRCPY)
{
requiredVars.Fill();
@ -5241,12 +5285,11 @@ void InterCodeBasicBlock::CheckValueUsage(InterInstruction * ins, const GrowingI
break;
case IC_SELECT:
for(int i=0; i<3; i++)
for (int i = 0; i < 3; i++)
{
if (ins->mSrc[i].mTemp >= 0 && tvalue[ins->mSrc[i].mTemp] && tvalue[ins->mSrc[i].mTemp]->mCode == IC_CONSTANT)
if (ins->mSrc[i].mTemp >= 0 && tvalue[ins->mSrc[i].mTemp] && tvalue[ins->mSrc[i].mTemp]->mCode == IC_CONSTANT && ins->mSrc[i].mType != IT_POINTER)
{
ins->mSrc[i] = tvalue[ins->mSrc[i].mTemp]->mConst;
ins->mSrc[i].mType = ins->mDst.mType;
ins->mSrc[i].mTemp = -1;
}
}
@ -16376,6 +16419,8 @@ void InterCodeProcedure::ResetVisited(void)
int InterCodeProcedure::AddTemporary(InterType type)
{
assert(type != IT_NONE);
int temp = mTemporaries.Size();
mTemporaries.Push(type);
return temp;
@ -17179,7 +17224,7 @@ void InterCodeProcedure::Close(void)
{
GrowingTypeArray tstack(IT_NONE);
CheckFunc = !strcmp(mIdent->mString, "bv");
CheckFunc = !strcmp(mIdent->mString, "main");
mEntryBlock = mBlocks[0];

View File

@ -63,6 +63,12 @@ InterCodeGenerator::ExValue InterCodeGenerator::Dereference(InterCodeProcedure*
ins->mSrc[0].mOperandSize = v.mReference == 1 ? v.mType->mSize : 2;
ins->mSrc[0].mStride = v.mReference == 1 ? v.mType->mStripe : 1;
if (ins->mDst.mType == IT_NONE)
{
mErrors->Error(exp->mLocation, EERR_INVALID_VALUE, "Not a simple type");
return v;
}
if (v.mReference == 1 && v.mType->mType == DT_TYPE_ENUM)
{
ins->mDst.mRange.LimitMin(v.mType->mMinValue);
@ -1641,6 +1647,7 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
break;
case EX_PACK:
case EX_PACK_TYPE:
mErrors->Error(exp->mLocation, EERR_INVALID_PACK_USAGE, "Invalid pack usage");
return ExValue(TheVoidTypeDeclaration);
@ -2032,7 +2039,10 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
if (exp->mToken == TK_ASSIGN || !(vl.mType->mType == DT_TYPE_POINTER && vr.mType->IsIntegerType() && (exp->mToken == TK_ASSIGN_ADD || exp->mToken == TK_ASSIGN_SUB)))
{
if (!vl.mType->CanAssign(vr.mType))
{
vl.mType->CanAssign(vr.mType);
mErrors->Error(exp->mLocation, EERR_INCOMPATIBLE_TYPES, "Cannot assign incompatible types");
}
}
if (exp->mType != EX_INITIALIZATION && (vl.mType->mFlags & DTF_CONST))
@ -3754,10 +3764,19 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
{
vr = TranslateExpression(procType, proc, block, exp->mLeft, destack, breakBlock, continueBlock, inlineMapper);
if (vr.mType->IsReference())
{
vr.mReference++;
vr.mType = vr.mType->mBase;
}
vr = Dereference(proc, exp, block, vr, 1);
vr = CoerceType(proc, exp, block, vr, procType->mBase);
if (vr.mReference == 0)
mErrors->Error(exp->mLocation, EERR_INVALID_VALUE, "Returning value as reference");
ins->mSrc[0].mType = IT_POINTER;
ins->mSrc[0].mTemp = vr.mTemp;
ins->mSrc[0].mMemory = IM_INDIRECT;
@ -3766,18 +3785,28 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
{
if (inlineMapper->mResultExp)
{
ins->mSrc[1].mType = IT_POINTER;
ins->mSrc[1].mTemp = inlineMapper->mResultExp->mTemp;
ins->mSrc[1].mMemory = IM_INDIRECT;
ins->mCode = IC_STORE;
ins->mSrc[1].mOperandSize = 2;
ins->mNumOperands = 2;
if (inlineMapper->mResultExp->mType->IsReference())
{
ins->mSrc[1].mType = IT_POINTER;
ins->mSrc[1].mTemp = inlineMapper->mResultExp->mTemp;
ins->mSrc[1].mMemory = IM_INDIRECT;
ins->mCode = IC_STORE;
ins->mSrc[1].mOperandSize = 2;
ins->mNumOperands = 2;
}
else
{
//bool moving = exp->mLeft->IsRValue() || exp->mLeft->mType == EX_VARIABLE && !(exp->mLeft->mDecValue->mFlags & (DTF_STATIC | DTF_GLOBAL)) && exp->mLeft->mDecType->mType != DT_TYPE_REFERENCE;
CopyStruct(proc, exp, block, *(inlineMapper->mResultExp), vr, inlineMapper, false);
ins->mCode = IC_NONE;
}
}
else
{
InterInstruction* ains = new InterInstruction(exp->mLocation, IC_CONSTANT);
ains->mDst.mType = IT_POINTER;
ains->mDst.mTemp = proc->AddTemporary(ins->mDst.mType);
ains->mDst.mTemp = proc->AddTemporary(ains->mDst.mType);
ains->mConst.mType = IT_POINTER;
ains->mConst.mOperandSize = procType->mBase->mSize;
ains->mConst.mIntConst = 0;
@ -4007,7 +4036,7 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
{
InterInstruction* ains = new InterInstruction(exp->mLocation, IC_CONSTANT);
ains->mDst.mType = IT_POINTER;
ains->mDst.mTemp = proc->AddTemporary(ins->mDst.mType);
ains->mDst.mTemp = proc->AddTemporary(ains->mDst.mType);
ains->mConst.mType = IT_POINTER;
ains->mConst.mOperandSize = procType->mBase->mSize;
ains->mConst.mIntConst = 0;
@ -4148,14 +4177,24 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
vc = Dereference(proc, exp, block, vc);
int ttemp;
int ttemp, tref = 0;
InterType ttype, stypel, styper;
stypel = InterTypeOf(vl.mType);
styper = InterTypeOf(vr.mType);
Declaration* dtype;
if (stypel == IT_POINTER || styper == IT_POINTER)
Declaration* dtype = exp->mDecType;
if (dtype->IsReference())
{
vl = Dereference(proc, exp, block, vl, 1);
vr = Dereference(proc, exp, block, vr, 1);
tref = 1;
dtype = dtype->mBase;
ttype = IT_POINTER;
}
else if (stypel == IT_POINTER || styper == IT_POINTER)
{
if (vl.mType->mType == DT_TYPE_ARRAY)
vl = Dereference(proc, exp, block, vl, 1);
@ -4224,7 +4263,7 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
sins->mDst.mTemp = ttemp;
block->Append(sins);
return ExValue(dtype, ttemp);
return ExValue(dtype, ttemp, tref);
}
else
#endif

File diff suppressed because it is too large Load Diff

View File

@ -91,6 +91,7 @@ protected:
Declaration* ParseQualIdent(void);
void SkipStatement(void);
Expression* ParseStatement(void);
Expression* ParseSwitchStatement(void);
@ -109,6 +110,7 @@ protected:
void ParseTemplateDeclarationBody(Declaration* tdec, Declaration* pthis);
Declaration* FunctionAutoParamsToTemplate(Declaration* fdec);
int ExpansionDistance(Declaration* tdec, Declaration* spec);
Declaration* ParseTemplateExpansion(Declaration* tmpld, Declaration* expd);
void CompleteTemplateExpansion(Declaration* tmpld);

View File

@ -148,6 +148,7 @@ const char* TokenNames[] =
"'#repeat'",
"'#until'",
"'#embed'",
"'#for'",
"'##'",
"'namespace'",
@ -596,6 +597,84 @@ void Scanner::NextPreToken(void)
mPreprocessor->CloseSource();
}
}
else if (mToken == TK_PREP_FOR)
{
NextRawToken();
if (mToken == TK_OPEN_PARENTHESIS)
{
NextRawToken();
Macro* macro = new Macro(Ident::Unique("@for"), nullptr);
if (mToken == TK_IDENT)
{
const Ident* loopindex = mTokenIdent;
NextRawToken();
if (mToken == TK_COMMA)
{
mPreprocessorMode = true;
NextToken();
int64 loopCount = PrepParseConditional();
mPreprocessorMode = false;
if (mToken == TK_CLOSE_PARENTHESIS)
{
int slen = mOffset;
bool quote = false;
while (mLine[slen] && (quote || mLine[slen] != '/' || mLine[slen + 1] != '/'))
{
if (mLine[slen] == '"')
quote = !quote;
slen++;
}
macro->SetString(mLine + mOffset, slen - mOffset);
mOffset = slen;
while (mLine[mOffset])
mOffset++;
if (loopCount > 0)
{
MacroExpansion* ex = new MacroExpansion();
MacroDict* scope = mDefineArguments;
mDefineArguments = new MacroDict();
Macro* arg = new Macro(loopindex, scope);
mDefineArguments->Insert(arg);
arg->SetString("0");
ex->mLine = mLine;
ex->mOffset = mOffset;
ex->mLink = mMacroExpansion;
ex->mChar = mTokenChar;
ex->mLoopCount = 0;
ex->mLoopIndex = arg;
ex->mLoopLimit = loopCount;
mMacroExpansion = ex;
mMacroExpansionDepth++;
if (mMacroExpansionDepth > 1024)
mErrors->Error(mLocation, EFATAL_MACRO_EXPANSION_DEPTH, "Maximum macro expansion depth exceeded", mTokenIdent);
mLine = macro->mString;
mOffset = 0;
NextChar();
}
}
else
mErrors->Error(mLocation, EERR_INVALID_PREPROCESSOR, "')' expected in defined parameter list");
}
else
mErrors->Error(mLocation, EERR_INVALID_PREPROCESSOR, "',' expected");
}
else
mErrors->Error(mLocation, EERR_INVALID_PREPROCESSOR, "'loop index variable expected");
}
else
mErrors->Error(mLocation, EERR_INVALID_PREPROCESSOR, "'('(' expected");
}
else if (mToken == TK_PREP_DEFINE)
{
NextRawToken();
@ -1313,6 +1392,8 @@ void Scanner::NextRawToken(void)
mToken = TK_PREP_UNTIL;
else if (!strcmp(tkprep, "embed"))
mToken = TK_PREP_EMBED;
else if (!strcmp(tkprep, "for"))
mToken = TK_PREP_FOR;
else
mErrors->Error(mLocation, EERR_INVALID_PREPROCESSOR, "Invalid preprocessor command", tkprep);
}
@ -1912,6 +1993,19 @@ bool Scanner::NextChar(void)
{
if (mMacroExpansion)
{
if (mMacroExpansion->mLoopIndex)
{
mMacroExpansion->mLoopCount++;
if (mMacroExpansion->mLoopCount < mMacroExpansion->mLoopLimit)
{
char buffer[20];
sprintf_s(buffer, "%d", int(mMacroExpansion->mLoopCount));
mMacroExpansion->mLoopIndex->SetString(buffer);
mOffset = 0;
continue;
}
}
MacroExpansion* mac = mMacroExpansion->mLink;
// delete mDefineArguments;

View File

@ -146,6 +146,7 @@ enum Token
TK_PREP_REPEAT,
TK_PREP_UNTIL,
TK_PREP_EMBED,
TK_PREP_FOR,
TK_PREP_CONCAT,
@ -284,7 +285,14 @@ protected:
const char * mLine;
int mOffset;
char mChar;
Macro * mLoopIndex;
int64 mLoopCount, mLoopLimit;
MacroDict* mDefinedArguments;
MacroExpansion(void)
: mLink(nullptr), mLine(nullptr), mOffset(0), mChar(0), mLoopIndex(nullptr), mLoopCount(0), mLoopLimit(0), mDefinedArguments(nullptr)
{}
} * mMacroExpansion;
int mMacroExpansionDepth;