Array constructors
This commit is contained in:
parent
0f67f7150f
commit
0b1b4a7d9b
15
README.md
15
README.md
|
@ -48,6 +48,18 @@ There are still several open areas, but most targets have been reached. The cur
|
||||||
|
|
||||||
### Native code generation
|
### Native code generation
|
||||||
|
|
||||||
|
### C++ support level
|
||||||
|
|
||||||
|
The compiler will most likely not support a current C++ standard in the near future, but several C++ features are already implemented. The compiler can be switched into C++ mode with the command line option -pp or by providing a source file with a .cpp extension.
|
||||||
|
|
||||||
|
Supported Features:
|
||||||
|
|
||||||
|
* namespaces
|
||||||
|
* reference types
|
||||||
|
* member functions
|
||||||
|
* constructors and destructors
|
||||||
|
* operator overloading (assignment)
|
||||||
|
|
||||||
## Installation and Usage
|
## Installation and Usage
|
||||||
|
|
||||||
### Installing on windows
|
### Installing on windows
|
||||||
|
@ -62,7 +74,7 @@ The compiler can also be built using MSVC or GCC. A visual studio project and a
|
||||||
|
|
||||||
The compiler is command line driven, and creates an executable .prg file.
|
The compiler is command line driven, and creates an executable .prg file.
|
||||||
|
|
||||||
oscar64 {-i=includePath} [-o=output.prg] [-rt=runtime.c] [-tf=format] [-tm=machine] [-e] [-n] [-dSYMBOL[=value]] {source.c}
|
oscar64 {-i=includePath} [-o=output.prg] [-rt=runtime.c] [-tf=format] [-tm=machine] [-e] [-n] [-dSYMBOL[=value]] {source.c|source.cpp}
|
||||||
|
|
||||||
* -v : verbose output for diagnostics
|
* -v : verbose output for diagnostics
|
||||||
* -v2 : more verbose output
|
* -v2 : more verbose output
|
||||||
|
@ -90,6 +102,7 @@ The compiler is command line driven, and creates an executable .prg file.
|
||||||
* -fz : add a compressed binary file to the disk image
|
* -fz : add a compressed binary file to the disk image
|
||||||
* -xz : extended zero page usage, more zero page space, but no return to basic
|
* -xz : extended zero page usage, more zero page space, but no return to basic
|
||||||
* -cid : cartridge type ID, used by vice emulator
|
* -cid : cartridge type ID, used by vice emulator
|
||||||
|
* -pp : compile in C++ mode
|
||||||
|
|
||||||
A list of source files can be provided.
|
A list of source files can be provided.
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,151 @@
|
||||||
|
#include <assert.h>
|
||||||
|
|
||||||
|
int t, n, m, k;
|
||||||
|
|
||||||
|
struct C1
|
||||||
|
{
|
||||||
|
int a;
|
||||||
|
|
||||||
|
C1(void);
|
||||||
|
~C1(void);
|
||||||
|
C1(const C1 & c);
|
||||||
|
C1 & operator=(const C1 & c);
|
||||||
|
};
|
||||||
|
|
||||||
|
struct C2
|
||||||
|
{
|
||||||
|
C1 nc[10], mc[20];
|
||||||
|
};
|
||||||
|
|
||||||
|
C1::C1(void)
|
||||||
|
{
|
||||||
|
a = 1;
|
||||||
|
n++;
|
||||||
|
t++;
|
||||||
|
}
|
||||||
|
|
||||||
|
C1::C1(const C1 & c)
|
||||||
|
{
|
||||||
|
a = c.a;
|
||||||
|
k++;
|
||||||
|
t++;
|
||||||
|
}
|
||||||
|
|
||||||
|
C1 & C1::operator=(const C1 & c)
|
||||||
|
{
|
||||||
|
a = c.a;
|
||||||
|
m++;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
C1::~C1(void)
|
||||||
|
{
|
||||||
|
t--;
|
||||||
|
}
|
||||||
|
|
||||||
|
void test_local_init(void)
|
||||||
|
{
|
||||||
|
n = 0;
|
||||||
|
|
||||||
|
{
|
||||||
|
C1 c[10];
|
||||||
|
}
|
||||||
|
|
||||||
|
assert(n == 10 && t == 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void test_member_init(void)
|
||||||
|
{
|
||||||
|
n = 0;
|
||||||
|
|
||||||
|
{
|
||||||
|
C2 d;
|
||||||
|
}
|
||||||
|
|
||||||
|
assert(n == 30 && t == 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void test_member_array_init(void)
|
||||||
|
{
|
||||||
|
n = 0;
|
||||||
|
|
||||||
|
{
|
||||||
|
C2 d[5];
|
||||||
|
}
|
||||||
|
|
||||||
|
assert(n == 150 && t == 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void test_local_copy(void)
|
||||||
|
{
|
||||||
|
n = 0;
|
||||||
|
k = 0;
|
||||||
|
|
||||||
|
{
|
||||||
|
C1 c[10];
|
||||||
|
C1 d(c[4]);
|
||||||
|
}
|
||||||
|
|
||||||
|
assert(n == 10 && k == 1 && t == 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void test_member_copy(void)
|
||||||
|
{
|
||||||
|
n = 0;
|
||||||
|
k = 0;
|
||||||
|
|
||||||
|
{
|
||||||
|
C2 d;
|
||||||
|
C2 e(d);
|
||||||
|
}
|
||||||
|
|
||||||
|
assert(n == 30 && k == 30 && t == 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void test_local_assign(void)
|
||||||
|
{
|
||||||
|
n = 0;
|
||||||
|
k = 0;
|
||||||
|
m = 0;
|
||||||
|
|
||||||
|
{
|
||||||
|
C1 c[10];
|
||||||
|
C1 d[5];
|
||||||
|
|
||||||
|
d[4] = c[2];
|
||||||
|
}
|
||||||
|
|
||||||
|
assert(n == 15 && k == 0 && m == 1 && t == 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void test_member_assign(void)
|
||||||
|
{
|
||||||
|
n = 0;
|
||||||
|
k = 0;
|
||||||
|
m = 0;
|
||||||
|
|
||||||
|
{
|
||||||
|
C2 d;
|
||||||
|
C2 e;
|
||||||
|
e = d;
|
||||||
|
}
|
||||||
|
|
||||||
|
assert(n == 60 && k == 0 && m == 30 && t == 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int main(void)
|
||||||
|
{
|
||||||
|
test_local_init();
|
||||||
|
test_member_init();
|
||||||
|
test_member_array_init();
|
||||||
|
|
||||||
|
test_local_copy();
|
||||||
|
test_member_copy();
|
||||||
|
|
||||||
|
test_local_assign();
|
||||||
|
test_member_assign();
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
|
@ -9,6 +9,9 @@ rem @echo off
|
||||||
@call :test copyassign.cpp
|
@call :test copyassign.cpp
|
||||||
@if %errorlevel% neq 0 goto :error
|
@if %errorlevel% neq 0 goto :error
|
||||||
|
|
||||||
|
@call :test arrayconstruct.cpp
|
||||||
|
@if %errorlevel% neq 0 goto :error
|
||||||
|
|
||||||
@call :test stdlibtest.c
|
@call :test stdlibtest.c
|
||||||
@if %errorlevel% neq 0 goto :error
|
@if %errorlevel% neq 0 goto :error
|
||||||
|
|
||||||
|
|
|
@ -778,7 +778,8 @@ Declaration::Declaration(const Location& loc, DecType type)
|
||||||
: mLocation(loc), mEndLocation(loc), mType(type), mScope(nullptr), mData(nullptr), mIdent(nullptr), mQualIdent(nullptr),
|
: mLocation(loc), mEndLocation(loc), mType(type), mScope(nullptr), mData(nullptr), mIdent(nullptr), mQualIdent(nullptr),
|
||||||
mSize(0), mOffset(0), mFlags(0), mComplexity(0), mLocalSize(0),
|
mSize(0), mOffset(0), mFlags(0), mComplexity(0), mLocalSize(0),
|
||||||
mBase(nullptr), mParams(nullptr), mValue(nullptr), mNext(nullptr), mPrev(nullptr), mConst(nullptr),
|
mBase(nullptr), mParams(nullptr), mValue(nullptr), mNext(nullptr), mPrev(nullptr), mConst(nullptr),
|
||||||
mConstructor(nullptr), mDestructor(nullptr), mCopyConstructor(nullptr),
|
mConstructor(nullptr), mDestructor(nullptr), mCopyConstructor(nullptr), mCopyAssignment(nullptr),
|
||||||
|
mVectorConstructor(nullptr), mVectorDestructor(nullptr), mVectorCopyConstructor(nullptr), mVectorCopyAssignment(nullptr),
|
||||||
mVarIndex(-1), mLinkerObject(nullptr), mCallers(nullptr), mCalled(nullptr), mAlignment(1),
|
mVarIndex(-1), mLinkerObject(nullptr), mCallers(nullptr), mCalled(nullptr), mAlignment(1),
|
||||||
mInteger(0), mNumber(0), mMinValue(-0x80000000LL), mMaxValue(0x7fffffffLL), mFastCallBase(0), mFastCallSize(0), mStride(0), mStripe(1),
|
mInteger(0), mNumber(0), mMinValue(-0x80000000LL), mMaxValue(0x7fffffffLL), mFastCallBase(0), mFastCallSize(0), mStride(0), mStripe(1),
|
||||||
mCompilerOptions(0), mUseCount(0)
|
mCompilerOptions(0), mUseCount(0)
|
||||||
|
|
|
@ -222,7 +222,10 @@ public:
|
||||||
Location mLocation, mEndLocation;
|
Location mLocation, mEndLocation;
|
||||||
DecType mType;
|
DecType mType;
|
||||||
Token mToken;
|
Token mToken;
|
||||||
Declaration* mBase, *mParams, * mNext, * mPrev, * mConst, * mConstructor, * mDestructor, * mCopyConstructor, * mCopyAssignment;
|
Declaration * mBase, * mParams, * mNext, * mPrev, * mConst;
|
||||||
|
Declaration * mConstructor, * mDestructor, * mCopyConstructor, * mCopyAssignment;
|
||||||
|
Declaration * mVectorConstructor, * mVectorDestructor, * mVectorCopyConstructor, * mVectorCopyAssignment;
|
||||||
|
|
||||||
Expression* mValue;
|
Expression* mValue;
|
||||||
DeclarationScope* mScope;
|
DeclarationScope* mScope;
|
||||||
int mOffset, mSize, mVarIndex, mNumVars, mComplexity, mLocalSize, mAlignment, mFastCallBase, mFastCallSize, mStride, mStripe;
|
int mOffset, mSize, mVarIndex, mNumVars, mComplexity, mLocalSize, mAlignment, mFastCallBase, mFastCallSize, mStride, mStripe;
|
||||||
|
|
|
@ -16017,7 +16017,7 @@ void InterCodeProcedure::Close(void)
|
||||||
{
|
{
|
||||||
GrowingTypeArray tstack(IT_NONE);
|
GrowingTypeArray tstack(IT_NONE);
|
||||||
|
|
||||||
CheckFunc = !strcmp(mIdent->mString, "test_retparam_value");
|
CheckFunc = !strcmp(mIdent->mString, "test");
|
||||||
|
|
||||||
mEntryBlock = mBlocks[0];
|
mEntryBlock = mBlocks[0];
|
||||||
|
|
||||||
|
|
|
@ -4329,6 +4329,13 @@ InterCodeProcedure* InterCodeGenerator::TranslateProcedure(InterCodeModule * mod
|
||||||
if (proc->mIdent && !strcmp(proc->mIdent->mString, "test_retparam_value"))
|
if (proc->mIdent && !strcmp(proc->mIdent->mString, "test_retparam_value"))
|
||||||
exp->Dump(0);
|
exp->Dump(0);
|
||||||
#endif
|
#endif
|
||||||
|
#if 0
|
||||||
|
if (proc->mIdent)
|
||||||
|
{
|
||||||
|
printf("TRANS %s\n", proc->mIdent->mString);
|
||||||
|
exp->Dump(0);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
uint64 outerCompilerOptions = mCompilerOptions;
|
uint64 outerCompilerOptions = mCompilerOptions;
|
||||||
mCompilerOptions = dec->mCompilerOptions;
|
mCompilerOptions = dec->mCompilerOptions;
|
||||||
|
|
|
@ -36463,6 +36463,7 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(NativeCodeProcedure* proc, int pass
|
||||||
mIns[i + 2].mType == ASMIT_LDA && mIns[i + 2].mMode == ASMIM_ZERO_PAGE &&
|
mIns[i + 2].mType == ASMIT_LDA && mIns[i + 2].mMode == ASMIM_ZERO_PAGE &&
|
||||||
mIns[i + 3].mType == ASMIT_ORA && mIns[i + 3].SameEffectiveAddress(mIns[i + 0]) && mIns[i + 3].mMode != ASMIM_IMMEDIATE)
|
mIns[i + 3].mType == ASMIT_ORA && mIns[i + 3].SameEffectiveAddress(mIns[i + 0]) && mIns[i + 3].mMode != ASMIM_IMMEDIATE)
|
||||||
{
|
{
|
||||||
|
mIns[i + 1].mLive |= LIVE_CPU_REG_A;
|
||||||
mIns[i + 2].mType = ASMIT_ORA; mIns[i + 2].mLive |= mIns[i + 3].mLive & LIVE_CPU_REG_Z;
|
mIns[i + 2].mType = ASMIT_ORA; mIns[i + 2].mLive |= mIns[i + 3].mLive & LIVE_CPU_REG_Z;
|
||||||
mIns[i + 3].mType = ASMIT_NOP; mIns[i + 3].mMode = ASMIM_IMPLIED;
|
mIns[i + 3].mType = ASMIT_NOP; mIns[i + 3].mMode = ASMIM_IMPLIED;
|
||||||
|
|
||||||
|
|
|
@ -1243,43 +1243,79 @@ void Parser::PrependMemberConstructor(Declaration* pthis, Declaration* cfunc)
|
||||||
sexp->mRight = cfunc->mValue;
|
sexp->mRight = cfunc->mValue;
|
||||||
cfunc->mValue = sexp;
|
cfunc->mValue = sexp;
|
||||||
}
|
}
|
||||||
else if (dec->mBase->mType == DT_TYPE_STRUCT && dec->mBase->mConstructor)
|
else
|
||||||
{
|
{
|
||||||
Expression* qexp = new Expression(pthis->mLocation, EX_QUALIFY);
|
Declaration* bdec = dec->mBase;
|
||||||
qexp->mLeft = thisexp;
|
while (bdec->mType == DT_TYPE_ARRAY)
|
||||||
qexp->mDecValue = dec;
|
bdec = bdec->mBase;
|
||||||
qexp->mDecType = dec->mBase;
|
|
||||||
|
|
||||||
Expression* pexp = new Expression(pthis->mLocation, EX_PREFIX);
|
if (bdec->mType == DT_TYPE_STRUCT && bdec->mConstructor)
|
||||||
pexp->mLeft = qexp;
|
|
||||||
pexp->mToken = TK_BINARY_AND;
|
|
||||||
pexp->mDecType = new Declaration(pthis->mLocation, DT_TYPE_POINTER);
|
|
||||||
pexp->mDecType->mFlags |= DTF_CONST | DTF_DEFINED;
|
|
||||||
pexp->mDecType->mBase = dec->mBase;
|
|
||||||
pexp->mDecType->mSize = 2;
|
|
||||||
|
|
||||||
Declaration* mdec = dec->mBase->mConstructor;
|
|
||||||
while (mdec && mdec->mBase->mParams->mNext)
|
|
||||||
mdec = mdec->mNext;
|
|
||||||
|
|
||||||
Expression* cexp = new Expression(pthis->mLocation, EX_CONSTANT);
|
|
||||||
if (mdec)
|
|
||||||
{
|
{
|
||||||
cexp->mDecValue = mdec;
|
Expression* qexp = new Expression(pthis->mLocation, EX_QUALIFY);
|
||||||
cexp->mDecType = cexp->mDecValue->mBase;
|
qexp->mLeft = thisexp;
|
||||||
|
qexp->mDecValue = dec;
|
||||||
|
|
||||||
|
Expression* dexp;
|
||||||
|
|
||||||
|
if (dec->mSize == bdec->mSize)
|
||||||
|
{
|
||||||
|
qexp->mDecType = bdec;
|
||||||
|
|
||||||
|
Expression* pexp = new Expression(pthis->mLocation, EX_PREFIX);
|
||||||
|
pexp->mLeft = qexp;
|
||||||
|
pexp->mToken = TK_BINARY_AND;
|
||||||
|
pexp->mDecType = new Declaration(pthis->mLocation, DT_TYPE_POINTER);
|
||||||
|
pexp->mDecType->mFlags |= DTF_CONST | DTF_DEFINED;
|
||||||
|
pexp->mDecType->mBase = bdec;
|
||||||
|
pexp->mDecType->mSize = 2;
|
||||||
|
|
||||||
|
Declaration* mdec = bdec->mConstructor;
|
||||||
|
while (mdec && mdec->mBase->mParams->mNext)
|
||||||
|
mdec = mdec->mNext;
|
||||||
|
|
||||||
|
Expression* cexp = new Expression(pthis->mLocation, EX_CONSTANT);
|
||||||
|
if (mdec)
|
||||||
|
{
|
||||||
|
cexp->mDecValue = mdec;
|
||||||
|
cexp->mDecType = cexp->mDecValue->mBase;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
mErrors->Error(dec->mLocation, EERR_NO_DEFAULT_CONSTRUCTOR, "No default constructor");
|
||||||
|
|
||||||
|
dexp = new Expression(mScanner->mLocation, EX_CALL);
|
||||||
|
dexp->mLeft = cexp;
|
||||||
|
dexp->mRight = pexp;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
qexp->mDecType = new Declaration(pthis->mLocation, DT_TYPE_POINTER);
|
||||||
|
qexp->mDecType->mFlags |= DTF_CONST | DTF_DEFINED;
|
||||||
|
qexp->mDecType->mBase = bdec;
|
||||||
|
qexp->mDecType->mSize = 2;
|
||||||
|
|
||||||
|
Expression* cexp = new Expression(pthis->mLocation, EX_CONSTANT);
|
||||||
|
cexp->mDecValue = bdec->mVectorConstructor;
|
||||||
|
cexp->mDecType = cexp->mDecValue->mBase;
|
||||||
|
|
||||||
|
Declaration* ncdec = new Declaration(mScanner->mLocation, DT_CONST_INTEGER);
|
||||||
|
ncdec->mBase = TheUnsignedIntTypeDeclaration;
|
||||||
|
ncdec->mInteger = dec->mSize / bdec->mSize;
|
||||||
|
|
||||||
|
dexp = new Expression(mScanner->mLocation, EX_CALL);
|
||||||
|
dexp->mLeft = cexp;
|
||||||
|
dexp->mRight = new Expression(mScanner->mLocation, EX_LIST);
|
||||||
|
dexp->mRight->mLeft = qexp;
|
||||||
|
dexp->mRight->mRight = new Expression(mScanner->mLocation, EX_CONSTANT);
|
||||||
|
dexp->mRight->mRight->mDecType = ncdec->mBase;
|
||||||
|
dexp->mRight->mRight->mDecValue = ncdec;
|
||||||
|
}
|
||||||
|
|
||||||
|
Expression* sexp = new Expression(mScanner->mLocation, EX_SEQUENCE);
|
||||||
|
|
||||||
|
sexp->mLeft = dexp;
|
||||||
|
sexp->mRight = cfunc->mValue;
|
||||||
|
cfunc->mValue = sexp;
|
||||||
}
|
}
|
||||||
else
|
|
||||||
mErrors->Error(dec->mLocation, EERR_NO_DEFAULT_CONSTRUCTOR, "No default constructor");
|
|
||||||
|
|
||||||
Expression* dexp = new Expression(mScanner->mLocation, EX_CALL);
|
|
||||||
dexp->mLeft = cexp;
|
|
||||||
dexp->mRight = pexp;
|
|
||||||
|
|
||||||
Expression* sexp = new Expression(mScanner->mLocation, EX_SEQUENCE);
|
|
||||||
|
|
||||||
sexp->mLeft = dexp;
|
|
||||||
sexp->mRight = cfunc->mValue;
|
|
||||||
cfunc->mValue = sexp;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1352,12 +1388,21 @@ void Parser::AddDefaultConstructors(Declaration* pthis)
|
||||||
Declaration* dec = pthis->mBase->mParams;
|
Declaration* dec = pthis->mBase->mParams;
|
||||||
while (dec)
|
while (dec)
|
||||||
{
|
{
|
||||||
if (dec->mType == DT_ELEMENT && dec->mBase->mType == DT_TYPE_STRUCT)
|
if (dec->mType == DT_ELEMENT)
|
||||||
{
|
{
|
||||||
if (dec->mBase->mDestructor)
|
Declaration* bdec = dec->mBase;
|
||||||
simpleDestructor = false;
|
int nitems = 1;
|
||||||
if (dec->mBase->mCopyAssignment)
|
|
||||||
simpleAssignment = false;
|
while (bdec->mType == DT_TYPE_ARRAY)
|
||||||
|
bdec = bdec->mBase;
|
||||||
|
|
||||||
|
if (bdec->mType == DT_TYPE_STRUCT)
|
||||||
|
{
|
||||||
|
if (bdec->mDestructor)
|
||||||
|
simpleDestructor = false;
|
||||||
|
if (bdec->mCopyAssignment)
|
||||||
|
simpleAssignment = false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
dec = dec->mNext;
|
dec = dec->mNext;
|
||||||
}
|
}
|
||||||
|
@ -1521,27 +1566,65 @@ void Parser::AddDefaultConstructors(Declaration* pthis)
|
||||||
|
|
||||||
Expression* mexp;
|
Expression* mexp;
|
||||||
|
|
||||||
if (dec->mBase->mType == DT_TYPE_STRUCT && dec->mBase->mCopyConstructor)
|
Declaration* bdec = dec->mBase;
|
||||||
|
while (bdec->mType == DT_TYPE_ARRAY)
|
||||||
|
bdec = bdec->mBase;
|
||||||
|
|
||||||
|
if (bdec->mType == DT_TYPE_STRUCT && bdec->mCopyConstructor)
|
||||||
{
|
{
|
||||||
Expression* pexp = new Expression(pthis->mLocation, EX_PREFIX);
|
if (dec->mSize == bdec->mSize)
|
||||||
pexp->mLeft = lexp;
|
{
|
||||||
pexp->mToken = TK_BINARY_AND;
|
Expression* pexp = new Expression(pthis->mLocation, EX_PREFIX);
|
||||||
pexp->mDecType = new Declaration(pthis->mLocation, DT_TYPE_POINTER);
|
pexp->mLeft = lexp;
|
||||||
pexp->mDecType->mFlags |= DTF_CONST | DTF_DEFINED;
|
pexp->mToken = TK_BINARY_AND;
|
||||||
pexp->mDecType->mBase = dec->mBase;
|
pexp->mDecType = new Declaration(pthis->mLocation, DT_TYPE_POINTER);
|
||||||
pexp->mDecType->mSize = 2;
|
pexp->mDecType->mFlags |= DTF_CONST | DTF_DEFINED;
|
||||||
|
pexp->mDecType->mBase = dec->mBase;
|
||||||
|
pexp->mDecType->mSize = 2;
|
||||||
|
|
||||||
Declaration* mdec = dec->mBase->mCopyConstructor;
|
Declaration* mdec = dec->mBase->mCopyConstructor;
|
||||||
|
|
||||||
Expression* cexp = new Expression(pthis->mLocation, EX_CONSTANT);
|
Expression* cexp = new Expression(pthis->mLocation, EX_CONSTANT);
|
||||||
cexp->mDecValue = mdec;
|
cexp->mDecValue = mdec;
|
||||||
cexp->mDecType = cexp->mDecValue->mBase;
|
cexp->mDecType = cexp->mDecValue->mBase;
|
||||||
|
|
||||||
mexp = new Expression(mScanner->mLocation, EX_CALL);
|
mexp = new Expression(mScanner->mLocation, EX_CALL);
|
||||||
mexp->mLeft = cexp;
|
mexp->mLeft = cexp;
|
||||||
mexp->mRight = new Expression(mScanner->mLocation, EX_LIST);
|
mexp->mRight = new Expression(mScanner->mLocation, EX_LIST);
|
||||||
mexp->mRight->mLeft = pexp;
|
mexp->mRight->mLeft = pexp;
|
||||||
mexp->mRight->mRight = rexp;
|
mexp->mRight->mRight = rexp;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
lexp->mDecType = new Declaration(pthis->mLocation, DT_TYPE_POINTER);
|
||||||
|
lexp->mDecType->mFlags |= DTF_CONST | DTF_DEFINED;
|
||||||
|
lexp->mDecType->mBase = bdec;
|
||||||
|
lexp->mDecType->mSize = 2;
|
||||||
|
|
||||||
|
rexp->mDecType = new Declaration(pthis->mLocation, DT_TYPE_POINTER);
|
||||||
|
rexp->mDecType->mFlags |= DTF_CONST | DTF_DEFINED;
|
||||||
|
rexp->mDecType->mBase = bdec;
|
||||||
|
rexp->mDecType->mSize = 2;
|
||||||
|
|
||||||
|
Expression* cexp = new Expression(pthis->mLocation, EX_CONSTANT);
|
||||||
|
cexp->mDecValue = bdec->mVectorCopyConstructor;
|
||||||
|
cexp->mDecType = cexp->mDecValue->mBase;
|
||||||
|
|
||||||
|
Declaration* ncdec = new Declaration(mScanner->mLocation, DT_CONST_INTEGER);
|
||||||
|
ncdec->mBase = TheUnsignedIntTypeDeclaration;
|
||||||
|
ncdec->mInteger = dec->mSize / bdec->mSize;
|
||||||
|
|
||||||
|
mexp = new Expression(mScanner->mLocation, EX_CALL);
|
||||||
|
mexp->mLeft = cexp;
|
||||||
|
mexp->mRight = new Expression(mScanner->mLocation, EX_LIST);
|
||||||
|
mexp->mRight->mLeft = lexp;
|
||||||
|
mexp->mRight->mRight = new Expression(mScanner->mLocation, EX_LIST);
|
||||||
|
mexp->mRight->mRight->mLeft = rexp;
|
||||||
|
mexp->mRight->mRight->mRight = new Expression(mScanner->mLocation, EX_CONSTANT);
|
||||||
|
mexp->mRight->mRight->mRight->mDecType = ncdec->mBase;
|
||||||
|
mexp->mRight->mRight->mRight->mDecValue = ncdec;
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -1661,27 +1744,64 @@ void Parser::AddDefaultConstructors(Declaration* pthis)
|
||||||
|
|
||||||
Expression* mexp;
|
Expression* mexp;
|
||||||
|
|
||||||
if (dec->mBase->mType == DT_TYPE_STRUCT && dec->mBase->mCopyAssignment)
|
Declaration* bdec = dec->mBase;
|
||||||
|
while (bdec->mType == DT_TYPE_ARRAY)
|
||||||
|
bdec = bdec->mBase;
|
||||||
|
|
||||||
|
if (bdec->mType == DT_TYPE_STRUCT && bdec->mCopyAssignment)
|
||||||
{
|
{
|
||||||
Expression* pexp = new Expression(pthis->mLocation, EX_PREFIX);
|
if (dec->mSize == bdec->mSize)
|
||||||
pexp->mLeft = lexp;
|
{
|
||||||
pexp->mToken = TK_BINARY_AND;
|
Expression* pexp = new Expression(pthis->mLocation, EX_PREFIX);
|
||||||
pexp->mDecType = new Declaration(pthis->mLocation, DT_TYPE_POINTER);
|
pexp->mLeft = lexp;
|
||||||
pexp->mDecType->mFlags |= DTF_CONST | DTF_DEFINED;
|
pexp->mToken = TK_BINARY_AND;
|
||||||
pexp->mDecType->mBase = dec->mBase;
|
pexp->mDecType = new Declaration(pthis->mLocation, DT_TYPE_POINTER);
|
||||||
pexp->mDecType->mSize = 2;
|
pexp->mDecType->mFlags |= DTF_CONST | DTF_DEFINED;
|
||||||
|
pexp->mDecType->mBase = dec->mBase;
|
||||||
|
pexp->mDecType->mSize = 2;
|
||||||
|
|
||||||
Declaration* mdec = dec->mBase->mCopyAssignment;
|
Declaration* mdec = bdec->mCopyAssignment;
|
||||||
|
|
||||||
Expression* cexp = new Expression(pthis->mLocation, EX_CONSTANT);
|
Expression* cexp = new Expression(pthis->mLocation, EX_CONSTANT);
|
||||||
cexp->mDecValue = mdec;
|
cexp->mDecValue = mdec;
|
||||||
cexp->mDecType = cexp->mDecValue->mBase;
|
cexp->mDecType = cexp->mDecValue->mBase;
|
||||||
|
|
||||||
mexp = new Expression(mScanner->mLocation, EX_CALL);
|
mexp = new Expression(mScanner->mLocation, EX_CALL);
|
||||||
mexp->mLeft = cexp;
|
mexp->mLeft = cexp;
|
||||||
mexp->mRight = new Expression(mScanner->mLocation, EX_LIST);
|
mexp->mRight = new Expression(mScanner->mLocation, EX_LIST);
|
||||||
mexp->mRight->mLeft = pexp;
|
mexp->mRight->mLeft = pexp;
|
||||||
mexp->mRight->mRight = rexp;
|
mexp->mRight->mRight = rexp;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
lexp->mDecType = new Declaration(pthis->mLocation, DT_TYPE_POINTER);
|
||||||
|
lexp->mDecType->mFlags |= DTF_CONST | DTF_DEFINED;
|
||||||
|
lexp->mDecType->mBase = bdec;
|
||||||
|
lexp->mDecType->mSize = 2;
|
||||||
|
|
||||||
|
rexp->mDecType = new Declaration(pthis->mLocation, DT_TYPE_POINTER);
|
||||||
|
rexp->mDecType->mFlags |= DTF_CONST | DTF_DEFINED;
|
||||||
|
rexp->mDecType->mBase = bdec;
|
||||||
|
rexp->mDecType->mSize = 2;
|
||||||
|
|
||||||
|
Expression* cexp = new Expression(pthis->mLocation, EX_CONSTANT);
|
||||||
|
cexp->mDecValue = bdec->mVectorCopyAssignment;
|
||||||
|
cexp->mDecType = cexp->mDecValue->mBase;
|
||||||
|
|
||||||
|
Declaration* ncdec = new Declaration(mScanner->mLocation, DT_CONST_INTEGER);
|
||||||
|
ncdec->mBase = TheUnsignedIntTypeDeclaration;
|
||||||
|
ncdec->mInteger = dec->mSize / bdec->mSize;
|
||||||
|
|
||||||
|
mexp = new Expression(mScanner->mLocation, EX_CALL);
|
||||||
|
mexp->mLeft = cexp;
|
||||||
|
mexp->mRight = new Expression(mScanner->mLocation, EX_LIST);
|
||||||
|
mexp->mRight->mLeft = lexp;
|
||||||
|
mexp->mRight->mRight = new Expression(mScanner->mLocation, EX_LIST);
|
||||||
|
mexp->mRight->mRight->mLeft = rexp;
|
||||||
|
mexp->mRight->mRight->mRight = new Expression(mScanner->mLocation, EX_CONSTANT);
|
||||||
|
mexp->mRight->mRight->mRight->mDecType = ncdec->mBase;
|
||||||
|
mexp->mRight->mRight->mRight->mDecValue = ncdec;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -1707,6 +1827,373 @@ void Parser::AddDefaultConstructors(Declaration* pthis)
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Declaration* dcons = pthis->mBase->mConstructor;
|
||||||
|
while (dcons && dcons->mBase->mParams->mNext)
|
||||||
|
dcons = dcons->mNext;
|
||||||
|
|
||||||
|
if (dcons && !pthis->mBase->mVectorConstructor)
|
||||||
|
{
|
||||||
|
Declaration* ctdec = new Declaration(mScanner->mLocation, DT_TYPE_FUNCTION);
|
||||||
|
ctdec->mSize = 0;
|
||||||
|
Declaration* pdec = nullptr;
|
||||||
|
ctdec->mBase = TheVoidTypeDeclaration;
|
||||||
|
ctdec->mFlags |= DTF_DEFINED;
|
||||||
|
|
||||||
|
Declaration* adec = new Declaration(mScanner->mLocation, DT_ARGUMENT);
|
||||||
|
adec->mVarIndex = 0;
|
||||||
|
adec->mOffset = 0;
|
||||||
|
adec->mBase = TheUnsignedIntTypeDeclaration;
|
||||||
|
adec->mSize = adec->mBase->mSize;
|
||||||
|
adec->mIdent = adec->mQualIdent = Ident::Unique("n");
|
||||||
|
|
||||||
|
ctdec->mParams = adec;
|
||||||
|
|
||||||
|
Declaration* vthis = pthis->Clone();
|
||||||
|
vthis->mFlags &= ~DTF_CONST;
|
||||||
|
PrependThisArgument(ctdec, vthis);
|
||||||
|
|
||||||
|
Declaration* cdec = new Declaration(ctdec->mLocation, DT_CONST_FUNCTION);
|
||||||
|
cdec->mBase = ctdec;
|
||||||
|
|
||||||
|
cdec->mFlags |= cdec->mBase->mFlags & (DTF_CONST | DTF_VOLATILE);
|
||||||
|
cdec->mFlags |= DTF_FUNC_CONSTRUCTOR;
|
||||||
|
|
||||||
|
cdec->mSection = mCodeSection;
|
||||||
|
|
||||||
|
if (mCompilerOptions & COPT_NATIVE)
|
||||||
|
cdec->mFlags |= DTF_NATIVE;
|
||||||
|
|
||||||
|
pthis->mBase->mVectorConstructor = cdec;
|
||||||
|
|
||||||
|
cdec->mIdent = pthis->mBase->mIdent;
|
||||||
|
cdec->mQualIdent = pthis->mBase->mScope->Mangle(cdec->mIdent);
|
||||||
|
|
||||||
|
cdec->mCompilerOptions = mCompilerOptions;
|
||||||
|
cdec->mBase->mCompilerOptions = mCompilerOptions;
|
||||||
|
|
||||||
|
cdec->mVarIndex = -1;
|
||||||
|
|
||||||
|
cdec->mFlags |= DTF_DEFINED;
|
||||||
|
cdec->mNumVars = mLocalIndex;
|
||||||
|
|
||||||
|
Expression* pexp = new Expression(mScanner->mLocation, EX_VARIABLE);
|
||||||
|
pexp->mDecType = vthis;
|
||||||
|
pexp->mDecValue = ctdec->mParams;
|
||||||
|
|
||||||
|
Expression* aexp = new Expression(mScanner->mLocation, EX_VARIABLE);
|
||||||
|
aexp->mDecType = TheUnsignedIntTypeDeclaration;
|
||||||
|
aexp->mDecValue = adec;
|
||||||
|
|
||||||
|
Expression* iexp = new Expression(mScanner->mLocation, EX_POSTINCDEC);
|
||||||
|
iexp->mToken = TK_INC;
|
||||||
|
iexp->mLeft = pexp;
|
||||||
|
|
||||||
|
Expression* dexp = new Expression(mScanner->mLocation, EX_POSTINCDEC);
|
||||||
|
dexp->mToken = TK_DEC;
|
||||||
|
dexp->mLeft = aexp;
|
||||||
|
|
||||||
|
Expression* fexp = new Expression(mScanner->mLocation, EX_CONSTANT);
|
||||||
|
fexp->mDecValue = dcons;
|
||||||
|
fexp->mDecType = fexp->mDecValue->mBase;
|
||||||
|
|
||||||
|
Expression*cexp = new Expression(mScanner->mLocation, EX_CALL);
|
||||||
|
cexp->mLeft = fexp;
|
||||||
|
cexp->mRight = iexp;
|
||||||
|
|
||||||
|
Expression * wexp = new Expression(mScanner->mLocation, EX_WHILE);
|
||||||
|
wexp->mLeft = aexp;
|
||||||
|
wexp->mRight = new Expression(mScanner->mLocation, EX_SEQUENCE);
|
||||||
|
wexp->mRight->mLeft = cexp;
|
||||||
|
wexp->mRight->mRight = dexp;
|
||||||
|
|
||||||
|
cdec->mValue = wexp;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pthis->mBase->mDestructor && !pthis->mBase->mVectorDestructor)
|
||||||
|
{
|
||||||
|
Declaration* ctdec = new Declaration(mScanner->mLocation, DT_TYPE_FUNCTION);
|
||||||
|
ctdec->mSize = 0;
|
||||||
|
Declaration* pdec = nullptr;
|
||||||
|
ctdec->mBase = TheVoidTypeDeclaration;
|
||||||
|
ctdec->mFlags |= DTF_DEFINED;
|
||||||
|
|
||||||
|
Declaration* adec = new Declaration(mScanner->mLocation, DT_ARGUMENT);
|
||||||
|
adec->mVarIndex = 0;
|
||||||
|
adec->mOffset = 0;
|
||||||
|
adec->mBase = TheUnsignedIntTypeDeclaration;
|
||||||
|
adec->mSize = adec->mBase->mSize;
|
||||||
|
adec->mIdent = adec->mQualIdent = Ident::Unique("n");
|
||||||
|
|
||||||
|
ctdec->mParams = adec;
|
||||||
|
|
||||||
|
Declaration* vthis = pthis->Clone();
|
||||||
|
vthis->mFlags &= ~DTF_CONST;
|
||||||
|
PrependThisArgument(ctdec, vthis);
|
||||||
|
|
||||||
|
Declaration* cdec = new Declaration(ctdec->mLocation, DT_CONST_FUNCTION);
|
||||||
|
cdec->mBase = ctdec;
|
||||||
|
|
||||||
|
cdec->mFlags |= cdec->mBase->mFlags & (DTF_CONST | DTF_VOLATILE);
|
||||||
|
cdec->mFlags |= DTF_FUNC_CONSTRUCTOR;
|
||||||
|
|
||||||
|
cdec->mSection = mCodeSection;
|
||||||
|
|
||||||
|
if (mCompilerOptions & COPT_NATIVE)
|
||||||
|
cdec->mFlags |= DTF_NATIVE;
|
||||||
|
|
||||||
|
pthis->mBase->mVectorDestructor = cdec;
|
||||||
|
|
||||||
|
char dname[100];
|
||||||
|
strcpy_s(dname, "~");
|
||||||
|
strcat_s(dname, pthis->mBase->mIdent->mString);
|
||||||
|
cdec->mIdent = Ident::Unique(dname);
|
||||||
|
cdec->mQualIdent = pthis->mBase->mScope->Mangle(cdec->mIdent);
|
||||||
|
|
||||||
|
cdec->mCompilerOptions = mCompilerOptions;
|
||||||
|
cdec->mBase->mCompilerOptions = mCompilerOptions;
|
||||||
|
|
||||||
|
cdec->mVarIndex = -1;
|
||||||
|
|
||||||
|
cdec->mFlags |= DTF_DEFINED;
|
||||||
|
cdec->mNumVars = mLocalIndex;
|
||||||
|
|
||||||
|
Expression* pexp = new Expression(mScanner->mLocation, EX_VARIABLE);
|
||||||
|
pexp->mDecType = vthis;
|
||||||
|
pexp->mDecValue = ctdec->mParams;
|
||||||
|
|
||||||
|
Expression* aexp = new Expression(mScanner->mLocation, EX_VARIABLE);
|
||||||
|
aexp->mDecType = TheUnsignedIntTypeDeclaration;
|
||||||
|
aexp->mDecValue = adec;
|
||||||
|
|
||||||
|
Expression* iexp = new Expression(mScanner->mLocation, EX_POSTINCDEC);
|
||||||
|
iexp->mToken = TK_INC;
|
||||||
|
iexp->mLeft = pexp;
|
||||||
|
|
||||||
|
Expression* dexp = new Expression(mScanner->mLocation, EX_POSTINCDEC);
|
||||||
|
dexp->mToken = TK_DEC;
|
||||||
|
dexp->mLeft = aexp;
|
||||||
|
|
||||||
|
Expression* fexp = new Expression(mScanner->mLocation, EX_CONSTANT);
|
||||||
|
fexp->mDecValue = pthis->mBase->mDestructor;
|
||||||
|
fexp->mDecType = fexp->mDecValue->mBase;
|
||||||
|
|
||||||
|
Expression* cexp = new Expression(mScanner->mLocation, EX_CALL);
|
||||||
|
cexp->mLeft = fexp;
|
||||||
|
cexp->mRight = iexp;
|
||||||
|
|
||||||
|
Expression* wexp = new Expression(mScanner->mLocation, EX_WHILE);
|
||||||
|
wexp->mLeft = aexp;
|
||||||
|
wexp->mRight = new Expression(mScanner->mLocation, EX_SEQUENCE);
|
||||||
|
wexp->mRight->mLeft = cexp;
|
||||||
|
wexp->mRight->mRight = dexp;
|
||||||
|
|
||||||
|
cdec->mValue = wexp;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pthis->mBase->mCopyConstructor && !pthis->mBase->mVectorCopyConstructor)
|
||||||
|
{
|
||||||
|
Declaration* ctdec = new Declaration(mScanner->mLocation, DT_TYPE_FUNCTION);
|
||||||
|
ctdec->mSize = 0;
|
||||||
|
Declaration* pdec = nullptr;
|
||||||
|
ctdec->mBase = TheVoidTypeDeclaration;
|
||||||
|
ctdec->mFlags |= DTF_DEFINED;
|
||||||
|
|
||||||
|
Declaration* sdec = new Declaration(mScanner->mLocation, DT_ARGUMENT);
|
||||||
|
sdec->mVarIndex = 0;
|
||||||
|
sdec->mOffset = 0;
|
||||||
|
sdec->mBase = pthis->Clone();
|
||||||
|
sdec->mBase->mFlags &= ~DTF_CONST;
|
||||||
|
sdec->mSize = sdec->mBase->mSize;
|
||||||
|
sdec->mIdent = sdec->mQualIdent = Ident::Unique("_");
|
||||||
|
|
||||||
|
Declaration* adec = new Declaration(mScanner->mLocation, DT_ARGUMENT);
|
||||||
|
adec->mVarIndex = 2;
|
||||||
|
adec->mOffset = 0;
|
||||||
|
adec->mBase = TheUnsignedIntTypeDeclaration;
|
||||||
|
adec->mSize = adec->mBase->mSize;
|
||||||
|
adec->mIdent = adec->mQualIdent = Ident::Unique("n");
|
||||||
|
|
||||||
|
sdec->mNext = adec;
|
||||||
|
ctdec->mParams = sdec;
|
||||||
|
|
||||||
|
Declaration* vthis = pthis->Clone();
|
||||||
|
vthis->mFlags &= ~DTF_CONST;
|
||||||
|
PrependThisArgument(ctdec, vthis);
|
||||||
|
|
||||||
|
Declaration* cdec = new Declaration(ctdec->mLocation, DT_CONST_FUNCTION);
|
||||||
|
cdec->mBase = ctdec;
|
||||||
|
|
||||||
|
cdec->mFlags |= cdec->mBase->mFlags & (DTF_CONST | DTF_VOLATILE);
|
||||||
|
cdec->mFlags |= DTF_FUNC_CONSTRUCTOR;
|
||||||
|
|
||||||
|
cdec->mSection = mCodeSection;
|
||||||
|
|
||||||
|
if (mCompilerOptions & COPT_NATIVE)
|
||||||
|
cdec->mFlags |= DTF_NATIVE;
|
||||||
|
|
||||||
|
pthis->mBase->mVectorCopyConstructor = cdec;
|
||||||
|
|
||||||
|
cdec->mIdent = pthis->mBase->mIdent;
|
||||||
|
cdec->mQualIdent = pthis->mBase->mScope->Mangle(cdec->mIdent);
|
||||||
|
|
||||||
|
cdec->mCompilerOptions = mCompilerOptions;
|
||||||
|
cdec->mBase->mCompilerOptions = mCompilerOptions;
|
||||||
|
|
||||||
|
cdec->mVarIndex = -1;
|
||||||
|
|
||||||
|
cdec->mFlags |= DTF_DEFINED;
|
||||||
|
cdec->mNumVars = mLocalIndex;
|
||||||
|
|
||||||
|
Expression* pexp = new Expression(mScanner->mLocation, EX_VARIABLE);
|
||||||
|
pexp->mDecType = vthis;
|
||||||
|
pexp->mDecValue = ctdec->mParams;
|
||||||
|
|
||||||
|
Expression* psexp = new Expression(mScanner->mLocation, EX_VARIABLE);
|
||||||
|
psexp->mDecType = vthis;
|
||||||
|
psexp->mDecValue = sdec;
|
||||||
|
|
||||||
|
Expression* aexp = new Expression(mScanner->mLocation, EX_VARIABLE);
|
||||||
|
aexp->mDecType = TheUnsignedIntTypeDeclaration;
|
||||||
|
aexp->mDecValue = adec;
|
||||||
|
|
||||||
|
Expression* iexp = new Expression(mScanner->mLocation, EX_POSTINCDEC);
|
||||||
|
iexp->mToken = TK_INC;
|
||||||
|
iexp->mLeft = pexp;
|
||||||
|
|
||||||
|
Expression* isexp = new Expression(mScanner->mLocation, EX_POSTINCDEC);
|
||||||
|
isexp->mToken = TK_INC;
|
||||||
|
isexp->mLeft = psexp;
|
||||||
|
|
||||||
|
Expression* disexp = new Expression(mScanner->mLocation, EX_PREFIX);
|
||||||
|
disexp->mToken = TK_MUL;
|
||||||
|
disexp->mLeft = isexp;
|
||||||
|
disexp->mDecType = vthis->mBase;
|
||||||
|
|
||||||
|
Expression* dexp = new Expression(mScanner->mLocation, EX_POSTINCDEC);
|
||||||
|
dexp->mToken = TK_DEC;
|
||||||
|
dexp->mLeft = aexp;
|
||||||
|
|
||||||
|
Expression* fexp = new Expression(mScanner->mLocation, EX_CONSTANT);
|
||||||
|
fexp->mDecValue = pthis->mBase->mCopyConstructor;
|
||||||
|
fexp->mDecType = fexp->mDecValue->mBase;
|
||||||
|
|
||||||
|
Expression* cexp = new Expression(mScanner->mLocation, EX_CALL);
|
||||||
|
cexp->mLeft = fexp;
|
||||||
|
cexp->mRight = new Expression(mScanner->mLocation, EX_LIST);
|
||||||
|
cexp->mRight->mLeft = iexp;
|
||||||
|
cexp->mRight->mRight = disexp;
|
||||||
|
|
||||||
|
Expression* wexp = new Expression(mScanner->mLocation, EX_WHILE);
|
||||||
|
wexp->mLeft = aexp;
|
||||||
|
wexp->mRight = new Expression(mScanner->mLocation, EX_SEQUENCE);
|
||||||
|
wexp->mRight->mLeft = cexp;
|
||||||
|
wexp->mRight->mRight = dexp;
|
||||||
|
|
||||||
|
cdec->mValue = wexp;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pthis->mBase->mCopyAssignment && !pthis->mBase->mVectorCopyAssignment)
|
||||||
|
{
|
||||||
|
Declaration* ctdec = new Declaration(mScanner->mLocation, DT_TYPE_FUNCTION);
|
||||||
|
ctdec->mSize = 0;
|
||||||
|
Declaration* pdec = nullptr;
|
||||||
|
ctdec->mBase = TheVoidTypeDeclaration;
|
||||||
|
ctdec->mFlags |= DTF_DEFINED;
|
||||||
|
|
||||||
|
Declaration* sdec = new Declaration(mScanner->mLocation, DT_ARGUMENT);
|
||||||
|
sdec->mVarIndex = 0;
|
||||||
|
sdec->mOffset = 0;
|
||||||
|
sdec->mBase = pthis->Clone();
|
||||||
|
sdec->mBase->mFlags &= ~DTF_CONST;
|
||||||
|
sdec->mSize = sdec->mBase->mSize;
|
||||||
|
sdec->mIdent = sdec->mQualIdent = Ident::Unique("_");
|
||||||
|
|
||||||
|
Declaration* adec = new Declaration(mScanner->mLocation, DT_ARGUMENT);
|
||||||
|
adec->mVarIndex = 2;
|
||||||
|
adec->mOffset = 0;
|
||||||
|
adec->mBase = TheUnsignedIntTypeDeclaration;
|
||||||
|
adec->mSize = adec->mBase->mSize;
|
||||||
|
adec->mIdent = adec->mQualIdent = Ident::Unique("n");
|
||||||
|
|
||||||
|
sdec->mNext = adec;
|
||||||
|
ctdec->mParams = sdec;
|
||||||
|
|
||||||
|
Declaration* vthis = pthis->Clone();
|
||||||
|
vthis->mFlags &= ~DTF_CONST;
|
||||||
|
PrependThisArgument(ctdec, vthis);
|
||||||
|
|
||||||
|
Declaration* cdec = new Declaration(ctdec->mLocation, DT_CONST_FUNCTION);
|
||||||
|
cdec->mBase = ctdec;
|
||||||
|
|
||||||
|
cdec->mFlags |= cdec->mBase->mFlags & (DTF_CONST | DTF_VOLATILE);
|
||||||
|
cdec->mFlags |= DTF_FUNC_CONSTRUCTOR;
|
||||||
|
|
||||||
|
cdec->mSection = mCodeSection;
|
||||||
|
|
||||||
|
if (mCompilerOptions & COPT_NATIVE)
|
||||||
|
cdec->mFlags |= DTF_NATIVE;
|
||||||
|
|
||||||
|
pthis->mBase->mVectorCopyAssignment = cdec;
|
||||||
|
|
||||||
|
cdec->mIdent = pthis->mBase->mIdent;
|
||||||
|
cdec->mQualIdent = pthis->mBase->mScope->Mangle(cdec->mIdent);
|
||||||
|
|
||||||
|
cdec->mCompilerOptions = mCompilerOptions;
|
||||||
|
cdec->mBase->mCompilerOptions = mCompilerOptions;
|
||||||
|
|
||||||
|
cdec->mVarIndex = -1;
|
||||||
|
|
||||||
|
cdec->mFlags |= DTF_DEFINED;
|
||||||
|
cdec->mNumVars = mLocalIndex;
|
||||||
|
|
||||||
|
Expression* pexp = new Expression(mScanner->mLocation, EX_VARIABLE);
|
||||||
|
pexp->mDecType = vthis;
|
||||||
|
pexp->mDecValue = ctdec->mParams;
|
||||||
|
|
||||||
|
Expression* psexp = new Expression(mScanner->mLocation, EX_VARIABLE);
|
||||||
|
psexp->mDecType = vthis;
|
||||||
|
psexp->mDecValue = sdec;
|
||||||
|
|
||||||
|
Expression* aexp = new Expression(mScanner->mLocation, EX_VARIABLE);
|
||||||
|
aexp->mDecType = TheUnsignedIntTypeDeclaration;
|
||||||
|
aexp->mDecValue = adec;
|
||||||
|
|
||||||
|
Expression* iexp = new Expression(mScanner->mLocation, EX_POSTINCDEC);
|
||||||
|
iexp->mToken = TK_INC;
|
||||||
|
iexp->mLeft = pexp;
|
||||||
|
|
||||||
|
Expression* isexp = new Expression(mScanner->mLocation, EX_POSTINCDEC);
|
||||||
|
isexp->mToken = TK_INC;
|
||||||
|
isexp->mLeft = psexp;
|
||||||
|
|
||||||
|
Expression* disexp = new Expression(mScanner->mLocation, EX_PREFIX);
|
||||||
|
disexp->mToken = TK_MUL;
|
||||||
|
disexp->mLeft = isexp;
|
||||||
|
disexp->mDecType = vthis->mBase;
|
||||||
|
|
||||||
|
Expression* dexp = new Expression(mScanner->mLocation, EX_POSTINCDEC);
|
||||||
|
dexp->mToken = TK_DEC;
|
||||||
|
dexp->mLeft = aexp;
|
||||||
|
|
||||||
|
Expression* fexp = new Expression(mScanner->mLocation, EX_CONSTANT);
|
||||||
|
fexp->mDecValue = pthis->mBase->mCopyAssignment;
|
||||||
|
fexp->mDecType = fexp->mDecValue->mBase;
|
||||||
|
|
||||||
|
Expression* cexp = new Expression(mScanner->mLocation, EX_CALL);
|
||||||
|
cexp->mLeft = fexp;
|
||||||
|
cexp->mRight = new Expression(mScanner->mLocation, EX_LIST);
|
||||||
|
cexp->mRight->mLeft = iexp;
|
||||||
|
cexp->mRight->mRight = disexp;
|
||||||
|
|
||||||
|
Expression* wexp = new Expression(mScanner->mLocation, EX_WHILE);
|
||||||
|
wexp->mLeft = aexp;
|
||||||
|
wexp->mRight = new Expression(mScanner->mLocation, EX_SEQUENCE);
|
||||||
|
wexp->mRight->mLeft = cexp;
|
||||||
|
wexp->mRight->mRight = dexp;
|
||||||
|
|
||||||
|
cdec->mValue = wexp;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Parser::AppendMemberDestructor(Declaration* pthis)
|
void Parser::AppendMemberDestructor(Declaration* pthis)
|
||||||
|
@ -1730,35 +2217,71 @@ void Parser::AppendMemberDestructor(Declaration* pthis)
|
||||||
dec = dec->Last();
|
dec = dec->Last();
|
||||||
while (dec)
|
while (dec)
|
||||||
{
|
{
|
||||||
if (dec->mType == DT_ELEMENT && dec->mBase->mType == DT_TYPE_STRUCT && dec->mBase->mDestructor)
|
if (dec->mType == DT_ELEMENT)
|
||||||
{
|
{
|
||||||
Expression* qexp = new Expression(pthis->mLocation, EX_QUALIFY);
|
Declaration* bdec = dec->mBase;
|
||||||
qexp->mLeft = thisexp;
|
while (bdec->mType == DT_TYPE_ARRAY)
|
||||||
qexp->mDecValue = dec;
|
bdec = bdec->mBase;
|
||||||
qexp->mDecType = dec->mBase;
|
|
||||||
|
|
||||||
Expression* pexp = new Expression(pthis->mLocation, EX_PREFIX);
|
if (bdec->mType == DT_TYPE_STRUCT && bdec->mConstructor)
|
||||||
pexp->mLeft = qexp;
|
{
|
||||||
pexp->mToken = TK_BINARY_AND;
|
Expression* qexp = new Expression(pthis->mLocation, EX_QUALIFY);
|
||||||
pexp->mDecType = new Declaration(pthis->mLocation, DT_TYPE_POINTER);
|
qexp->mLeft = thisexp;
|
||||||
pexp->mDecType->mFlags |= DTF_CONST | DTF_DEFINED;
|
qexp->mDecValue = dec;
|
||||||
pexp->mDecType->mBase = dec->mBase;
|
|
||||||
pexp->mDecType->mSize = 2;
|
|
||||||
|
|
||||||
Expression* cexp = new Expression(pthis->mLocation, EX_CONSTANT);
|
Expression* dexp;
|
||||||
cexp->mDecValue = dec->mBase->mDestructor;
|
|
||||||
cexp->mDecType = cexp->mDecValue->mBase;
|
|
||||||
|
|
||||||
Expression* dexp = new Expression(mScanner->mLocation, EX_CALL);
|
if (dec->mSize == bdec->mSize)
|
||||||
dexp->mLeft = cexp;
|
{
|
||||||
dexp->mRight = pexp;
|
qexp->mDecType = bdec;
|
||||||
|
|
||||||
Expression* sexp = new Expression(mScanner->mLocation, EX_SEQUENCE);
|
Expression* pexp = new Expression(pthis->mLocation, EX_PREFIX);
|
||||||
|
pexp->mLeft = qexp;
|
||||||
|
pexp->mToken = TK_BINARY_AND;
|
||||||
|
pexp->mDecType = new Declaration(pthis->mLocation, DT_TYPE_POINTER);
|
||||||
|
pexp->mDecType->mFlags |= DTF_CONST | DTF_DEFINED;
|
||||||
|
pexp->mDecType->mBase = bdec;
|
||||||
|
pexp->mDecType->mSize = 2;
|
||||||
|
|
||||||
sexp->mLeft = pthis->mBase->mDestructor->mValue;
|
Expression* cexp = new Expression(pthis->mLocation, EX_CONSTANT);
|
||||||
sexp->mRight = dexp;
|
cexp->mDecValue = bdec->mDestructor;
|
||||||
|
cexp->mDecType = cexp->mDecValue->mBase;
|
||||||
|
|
||||||
pthis->mBase->mDestructor->mValue = sexp;
|
dexp = new Expression(mScanner->mLocation, EX_CALL);
|
||||||
|
dexp->mLeft = cexp;
|
||||||
|
dexp->mRight = pexp;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
qexp->mDecType = new Declaration(pthis->mLocation, DT_TYPE_POINTER);
|
||||||
|
qexp->mDecType->mFlags |= DTF_CONST | DTF_DEFINED;
|
||||||
|
qexp->mDecType->mBase = bdec;
|
||||||
|
qexp->mDecType->mSize = 2;
|
||||||
|
|
||||||
|
Expression* cexp = new Expression(pthis->mLocation, EX_CONSTANT);
|
||||||
|
cexp->mDecValue = bdec->mVectorDestructor;
|
||||||
|
cexp->mDecType = cexp->mDecValue->mBase;
|
||||||
|
|
||||||
|
Declaration* ncdec = new Declaration(mScanner->mLocation, DT_CONST_INTEGER);
|
||||||
|
ncdec->mBase = TheUnsignedIntTypeDeclaration;
|
||||||
|
ncdec->mInteger = dec->mSize / bdec->mSize;
|
||||||
|
|
||||||
|
dexp = new Expression(mScanner->mLocation, EX_CALL);
|
||||||
|
dexp->mLeft = cexp;
|
||||||
|
dexp->mRight = new Expression(mScanner->mLocation, EX_LIST);
|
||||||
|
dexp->mRight->mLeft = qexp;
|
||||||
|
dexp->mRight->mRight = new Expression(mScanner->mLocation, EX_CONSTANT);
|
||||||
|
dexp->mRight->mRight->mDecType = ncdec->mBase;
|
||||||
|
dexp->mRight->mRight->mDecValue = ncdec;
|
||||||
|
}
|
||||||
|
|
||||||
|
Expression* sexp = new Expression(mScanner->mLocation, EX_SEQUENCE);
|
||||||
|
|
||||||
|
sexp->mLeft = pthis->mBase->mDestructor->mValue;
|
||||||
|
sexp->mRight = dexp;
|
||||||
|
|
||||||
|
pthis->mBase->mDestructor->mValue = sexp;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
dec = dec->mPrev;
|
dec = dec->mPrev;
|
||||||
|
@ -2615,62 +3138,116 @@ Declaration* Parser::ParseDeclaration(Declaration * pdec, bool variable, bool ex
|
||||||
{
|
{
|
||||||
ParseVariableInit(ndec);
|
ParseVariableInit(ndec);
|
||||||
}
|
}
|
||||||
else if ((mCompilerOptions & COPT_CPLUSPLUS) && ndec->mBase->mConstructor && ndec->mType == DT_VARIABLE && !pthis)
|
else if ((mCompilerOptions & COPT_CPLUSPLUS) && ndec->mType == DT_VARIABLE && !pthis)
|
||||||
{
|
{
|
||||||
// Find default constructor
|
// Find default constructor
|
||||||
|
|
||||||
Declaration* cdec = ndec->mBase->mConstructor;
|
Declaration* bdec = ndec->mBase;
|
||||||
while (cdec && cdec->mBase->mParams->mNext)
|
while (bdec && bdec->mType == DT_TYPE_ARRAY)
|
||||||
cdec = cdec->mNext;
|
bdec = bdec->mBase;
|
||||||
|
|
||||||
if (cdec)
|
if (bdec && bdec->mConstructor)
|
||||||
{
|
{
|
||||||
Expression* vexp = new Expression(ndec->mLocation, EX_VARIABLE);
|
Declaration* cdec = bdec->mConstructor;
|
||||||
vexp->mDecType = ndec->mBase;
|
while (cdec && cdec->mBase->mParams->mNext)
|
||||||
vexp->mDecValue = ndec;
|
cdec = cdec->mNext;
|
||||||
|
|
||||||
Expression* cexp = new Expression(mScanner->mLocation, EX_CONSTANT);
|
if (cdec)
|
||||||
cexp->mDecValue = cdec;
|
|
||||||
cexp->mDecType = cexp->mDecValue->mBase;
|
|
||||||
|
|
||||||
Expression* fexp = new Expression(mScanner->mLocation, EX_CALL);
|
|
||||||
fexp->mLeft = cexp;
|
|
||||||
|
|
||||||
Expression* texp = new Expression(mScanner->mLocation, EX_PREFIX);
|
|
||||||
texp->mToken = TK_BINARY_AND;
|
|
||||||
texp->mLeft = vexp;
|
|
||||||
texp->mDecType = new Declaration(mScanner->mLocation, DT_TYPE_POINTER);
|
|
||||||
texp->mDecType->mFlags |= DTF_CONST | DTF_DEFINED;
|
|
||||||
texp->mDecType->mBase = ndec->mBase;
|
|
||||||
texp->mDecType->mSize = 2;
|
|
||||||
|
|
||||||
fexp->mRight = texp;
|
|
||||||
|
|
||||||
Expression* dexp = nullptr;
|
|
||||||
if (ndec->mBase->mDestructor)
|
|
||||||
{
|
{
|
||||||
Expression* cexp = new Expression(mScanner->mLocation, EX_CONSTANT);
|
Expression* vexp = new Expression(ndec->mLocation, EX_VARIABLE);
|
||||||
cexp->mDecValue = ndec->mBase->mDestructor;
|
vexp->mDecType = ndec->mBase;
|
||||||
cexp->mDecType = cexp->mDecValue->mBase;
|
vexp->mDecValue = ndec;
|
||||||
|
|
||||||
dexp = new Expression(mScanner->mLocation, EX_CALL);
|
Expression* texp = new Expression(mScanner->mLocation, EX_PREFIX);
|
||||||
dexp->mLeft = cexp;
|
texp->mToken = TK_BINARY_AND;
|
||||||
dexp->mRight = texp;
|
texp->mLeft = vexp;
|
||||||
|
texp->mDecType = new Declaration(mScanner->mLocation, DT_TYPE_POINTER);
|
||||||
|
texp->mDecType->mFlags |= DTF_DEFINED;
|
||||||
|
texp->mDecType->mBase = bdec;
|
||||||
|
texp->mDecType->mSize = 2;
|
||||||
|
|
||||||
|
if (bdec->mSize == ndec->mBase->mSize)
|
||||||
|
{
|
||||||
|
Expression* cexp = new Expression(mScanner->mLocation, EX_CONSTANT);
|
||||||
|
cexp->mDecValue = cdec;
|
||||||
|
cexp->mDecType = cexp->mDecValue->mBase;
|
||||||
|
|
||||||
|
Expression* fexp = new Expression(mScanner->mLocation, EX_CALL);
|
||||||
|
fexp->mLeft = cexp;
|
||||||
|
fexp->mRight = texp;
|
||||||
|
|
||||||
|
Expression* dexp = nullptr;
|
||||||
|
if (ndec->mBase->mDestructor)
|
||||||
|
{
|
||||||
|
Expression* cexp = new Expression(mScanner->mLocation, EX_CONSTANT);
|
||||||
|
cexp->mDecValue = ndec->mBase->mDestructor;
|
||||||
|
cexp->mDecType = cexp->mDecValue->mBase;
|
||||||
|
|
||||||
|
dexp = new Expression(mScanner->mLocation, EX_CALL);
|
||||||
|
dexp->mLeft = cexp;
|
||||||
|
dexp->mRight = texp;
|
||||||
|
}
|
||||||
|
|
||||||
|
Expression* nexp = new Expression(mScanner->mLocation, EX_CONSTRUCT);
|
||||||
|
|
||||||
|
nexp->mLeft = new Expression(mScanner->mLocation, EX_LIST);
|
||||||
|
nexp->mLeft->mLeft = fexp;
|
||||||
|
nexp->mLeft->mRight = dexp;
|
||||||
|
|
||||||
|
nexp->mRight = vexp;
|
||||||
|
nexp->mDecType = vexp->mDecType;
|
||||||
|
|
||||||
|
ndec->mValue = nexp;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Declaration* ncdec = new Declaration(mScanner->mLocation, DT_CONST_INTEGER);
|
||||||
|
ncdec->mBase = TheUnsignedIntTypeDeclaration;
|
||||||
|
ncdec->mInteger = ndec->mSize / bdec->mSize;
|
||||||
|
|
||||||
|
Expression * ncexp = new Expression(mScanner->mLocation, EX_CONSTANT);
|
||||||
|
ncexp->mDecType = ncdec->mBase;
|
||||||
|
ncexp->mDecValue = ncdec;
|
||||||
|
|
||||||
|
Expression* cexp = new Expression(mScanner->mLocation, EX_CONSTANT);
|
||||||
|
cexp->mDecValue = bdec->mVectorConstructor;
|
||||||
|
cexp->mDecType = cexp->mDecValue->mBase;
|
||||||
|
|
||||||
|
Expression* fexp = new Expression(mScanner->mLocation, EX_CALL);
|
||||||
|
fexp->mLeft = cexp;
|
||||||
|
fexp->mRight = new Expression(mScanner->mLocation, EX_LIST);
|
||||||
|
fexp->mRight->mLeft = vexp;
|
||||||
|
fexp->mRight->mRight = ncexp;
|
||||||
|
|
||||||
|
Expression* dexp = nullptr;
|
||||||
|
if (bdec->mDestructor)
|
||||||
|
{
|
||||||
|
Expression* cexp = new Expression(mScanner->mLocation, EX_CONSTANT);
|
||||||
|
cexp->mDecValue = bdec->mVectorDestructor;
|
||||||
|
cexp->mDecType = cexp->mDecValue->mBase;
|
||||||
|
|
||||||
|
dexp = new Expression(mScanner->mLocation, EX_CALL);
|
||||||
|
dexp->mLeft = cexp;
|
||||||
|
dexp->mRight = new Expression(mScanner->mLocation, EX_LIST);
|
||||||
|
dexp->mRight->mLeft = vexp;
|
||||||
|
dexp->mRight->mRight = ncexp;
|
||||||
|
}
|
||||||
|
|
||||||
|
Expression* nexp = new Expression(mScanner->mLocation, EX_CONSTRUCT);
|
||||||
|
|
||||||
|
nexp->mLeft = new Expression(mScanner->mLocation, EX_LIST);
|
||||||
|
nexp->mLeft->mLeft = fexp;
|
||||||
|
nexp->mLeft->mRight = dexp;
|
||||||
|
|
||||||
|
nexp->mRight = vexp;
|
||||||
|
nexp->mDecType = vexp->mDecType;
|
||||||
|
|
||||||
|
ndec->mValue = nexp;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
else
|
||||||
Expression* nexp = new Expression(mScanner->mLocation, EX_CONSTRUCT);
|
mErrors->Error(ndec->mLocation, EERR_NO_DEFAULT_CONSTRUCTOR, "No default constructor for class", ndec->mBase->mIdent);
|
||||||
|
|
||||||
nexp->mLeft = new Expression(mScanner->mLocation, EX_LIST);
|
|
||||||
nexp->mLeft->mLeft = fexp;
|
|
||||||
nexp->mLeft->mRight = dexp;
|
|
||||||
|
|
||||||
nexp->mRight = vexp;
|
|
||||||
nexp->mDecType = vexp->mDecType;
|
|
||||||
|
|
||||||
ndec->mValue = nexp;
|
|
||||||
}
|
}
|
||||||
else
|
|
||||||
mErrors->Error(ndec->mLocation, EERR_NO_DEFAULT_CONSTRUCTOR, "No default constructor for class", ndec->mBase->mIdent);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (storageFlags & DTF_EXPORT)
|
if (storageFlags & DTF_EXPORT)
|
||||||
|
|
Loading…
Reference in New Issue