Add lambda
This commit is contained in:
parent
c926456560
commit
2b51f20b1c
|
@ -7,8 +7,8 @@
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
CompilationUnits::CompilationUnits(Errors * errors)
|
CompilationUnits::CompilationUnits(Errors* errors)
|
||||||
: mErrors(errors), mReferenced(nullptr)
|
: mErrors(errors), mReferenced(nullptr), mUniqueID(0)
|
||||||
{
|
{
|
||||||
mCompilationUnits = nullptr;
|
mCompilationUnits = nullptr;
|
||||||
mPendingUnits = nullptr;
|
mPendingUnits = nullptr;
|
||||||
|
@ -27,6 +27,12 @@ CompilationUnits::~CompilationUnits(void)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int CompilationUnits::UniqueID(void)
|
||||||
|
{
|
||||||
|
return mUniqueID++;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void CompilationUnits::AddReferenced(Declaration* ref)
|
void CompilationUnits::AddReferenced(Declaration* ref)
|
||||||
{
|
{
|
||||||
mReferenced.Push(ref);
|
mReferenced.Push(ref);
|
||||||
|
|
|
@ -31,6 +31,10 @@ public:
|
||||||
LinkerSection* mSectionCode, * mSectionData, * mSectionBSS, * mSectionHeap, * mSectionStack, * mSectionZeroPage, * mSectionLowCode, * mSectionBoot;
|
LinkerSection* mSectionCode, * mSectionData, * mSectionBSS, * mSectionHeap, * mSectionStack, * mSectionZeroPage, * mSectionLowCode, * mSectionBoot;
|
||||||
Linker* mLinker;
|
Linker* mLinker;
|
||||||
|
|
||||||
|
int mUniqueID;
|
||||||
|
|
||||||
|
int UniqueID(void);
|
||||||
|
|
||||||
bool AddUnit(Location & location, const char* name, const char * from);
|
bool AddUnit(Location & location, const char* name, const char * from);
|
||||||
CompilationUnit* PendingUnit(void);
|
CompilationUnit* PendingUnit(void);
|
||||||
|
|
||||||
|
|
|
@ -839,7 +839,7 @@ ConstexprInterpreter::Value ConstexprInterpreter::EvalUnary(Expression* exp, con
|
||||||
case TK_MUL:
|
case TK_MUL:
|
||||||
return vl.GetPtr();
|
return vl.GetPtr();
|
||||||
case TK_NEW:
|
case TK_NEW:
|
||||||
v.PutPtr(Value(NewValue(exp, exp->mDecType->mBase, vl.GetInt())));
|
v.PutPtr(Value(NewValue(exp, exp->mDecType->mBase, int(vl.GetInt()))));
|
||||||
break;
|
break;
|
||||||
case TK_DELETE:
|
case TK_DELETE:
|
||||||
DeleteValue(vl.GetPtr().mBaseValue);
|
DeleteValue(vl.GetPtr().mBaseValue);
|
||||||
|
@ -1266,7 +1266,9 @@ ConstexprInterpreter::Flow ConstexprInterpreter::Execute(Expression* exp)
|
||||||
if (exp->mLeft->mRight)
|
if (exp->mLeft->mRight)
|
||||||
mDestructStack.Push(exp->mLeft->mRight);
|
mDestructStack.Push(exp->mLeft->mRight);
|
||||||
|
|
||||||
return Execute(exp->mRight);
|
if (exp->mRight)
|
||||||
|
return Execute(exp->mRight);
|
||||||
|
return FLOW_NEXT;
|
||||||
|
|
||||||
case EX_VOID:
|
case EX_VOID:
|
||||||
return FLOW_NEXT;
|
return FLOW_NEXT;
|
||||||
|
|
|
@ -84,6 +84,7 @@ enum ErrorID
|
||||||
EERR_TEMPLATE_PARAMS,
|
EERR_TEMPLATE_PARAMS,
|
||||||
EERR_FUNCTION_TEMPLATE,
|
EERR_FUNCTION_TEMPLATE,
|
||||||
EERR_INVALID_BITFIELD,
|
EERR_INVALID_BITFIELD,
|
||||||
|
EERR_INVALID_CAPTURE,
|
||||||
|
|
||||||
EERR_INVALID_CONSTEXPR,
|
EERR_INVALID_CONSTEXPR,
|
||||||
EERR_DOUBLE_FREE,
|
EERR_DOUBLE_FREE,
|
||||||
|
|
|
@ -919,7 +919,9 @@ Declaration * GlobalAnalyzer::Analyze(Expression* exp, Declaration* procDec, boo
|
||||||
Analyze(exp->mLeft->mLeft, procDec, false);
|
Analyze(exp->mLeft->mLeft, procDec, false);
|
||||||
if (exp->mLeft->mRight)
|
if (exp->mLeft->mRight)
|
||||||
Analyze(exp->mLeft->mRight, procDec, false);
|
Analyze(exp->mLeft->mRight, procDec, false);
|
||||||
return Analyze(exp->mRight, procDec, false);
|
if (exp->mRight)
|
||||||
|
return Analyze(exp->mRight, procDec, false);
|
||||||
|
break;
|
||||||
|
|
||||||
case EX_CLEANUP:
|
case EX_CLEANUP:
|
||||||
Analyze(exp->mRight, procDec, false);
|
Analyze(exp->mRight, procDec, false);
|
||||||
|
|
|
@ -53,6 +53,13 @@ const Ident* Ident::PreMangle(const char* str) const
|
||||||
return Unique(buffer);
|
return Unique(buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const Ident* Ident::Unique(const char* str, int id)
|
||||||
|
{
|
||||||
|
char buffer[200];
|
||||||
|
sprintf_s(buffer, "%s#%d", str, id);
|
||||||
|
return Unique(buffer);
|
||||||
|
}
|
||||||
|
|
||||||
const Ident* Ident::Mangle(const char* str) const
|
const Ident* Ident::Mangle(const char* str) const
|
||||||
{
|
{
|
||||||
char buffer[200];
|
char buffer[200];
|
||||||
|
|
|
@ -9,6 +9,7 @@ public:
|
||||||
unsigned int mHash;
|
unsigned int mHash;
|
||||||
|
|
||||||
static const Ident* Unique(const char* str);
|
static const Ident* Unique(const char* str);
|
||||||
|
static const Ident* Unique(const char* str, int id);
|
||||||
const Ident* Mangle(const char* str) const;
|
const Ident* Mangle(const char* str) const;
|
||||||
const Ident* PreMangle(const char* str) const;
|
const Ident* PreMangle(const char* str) const;
|
||||||
protected:
|
protected:
|
||||||
|
|
|
@ -17081,7 +17081,7 @@ void InterCodeProcedure::Close(void)
|
||||||
{
|
{
|
||||||
GrowingTypeArray tstack(IT_NONE);
|
GrowingTypeArray tstack(IT_NONE);
|
||||||
|
|
||||||
CheckFunc = !strcmp(mIdent->mString, "test");
|
CheckFunc = !strcmp(mIdent->mString, "main");
|
||||||
|
|
||||||
mEntryBlock = mBlocks[0];
|
mEntryBlock = mBlocks[0];
|
||||||
|
|
||||||
|
|
|
@ -1635,6 +1635,8 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
|
||||||
}
|
}
|
||||||
|
|
||||||
exp = exp->mRight;
|
exp = exp->mRight;
|
||||||
|
if (!exp)
|
||||||
|
return ExValue(TheVoidTypeDeclaration);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -2054,6 +2056,7 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
|
||||||
ins->mSrc[1].mMemory = IM_INDIRECT;
|
ins->mSrc[1].mMemory = IM_INDIRECT;
|
||||||
ins->mSrc[1].mOperandSize = 2;
|
ins->mSrc[1].mOperandSize = 2;
|
||||||
ins->mSrc[1].mStride = vl.mType->mStripe;
|
ins->mSrc[1].mStride = vl.mType->mStripe;
|
||||||
|
ins->mNumOperands = 2;
|
||||||
|
|
||||||
block->Append(ins);
|
block->Append(ins);
|
||||||
}
|
}
|
||||||
|
@ -2345,7 +2348,10 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
|
||||||
ains->mDst.mTemp = proc->AddTemporary(ains->mDst.mType);
|
ains->mDst.mTemp = proc->AddTemporary(ains->mDst.mType);
|
||||||
block->Append(ains);
|
block->Append(ains);
|
||||||
|
|
||||||
return ExValue(exp->mDecValue->mBase, ains->mDst.mTemp, 1, exp->mDecValue->mBits, exp->mDecValue->mShift);
|
if (exp->mDecType->IsReference())
|
||||||
|
return ExValue(exp->mDecValue->mBase->mBase, ains->mDst.mTemp, 2);
|
||||||
|
else
|
||||||
|
return ExValue(exp->mDecValue->mBase, ains->mDst.mTemp, 1, exp->mDecValue->mBits, exp->mDecValue->mShift);
|
||||||
}
|
}
|
||||||
|
|
||||||
case EX_BINARY:
|
case EX_BINARY:
|
||||||
|
|
|
@ -21,6 +21,8 @@ Parser::Parser(Errors* errors, Scanner* scanner, CompilationUnits* compilationUn
|
||||||
mThisPointer = nullptr;
|
mThisPointer = nullptr;
|
||||||
mFunction = nullptr;
|
mFunction = nullptr;
|
||||||
mFunctionType = nullptr;
|
mFunctionType = nullptr;
|
||||||
|
mLambda = nullptr;
|
||||||
|
mCaptureScope = nullptr;
|
||||||
|
|
||||||
for (int i = 0; i < 256; i++)
|
for (int i = 0; i < 256; i++)
|
||||||
mCharMap[i] = i;
|
mCharMap[i] = i;
|
||||||
|
@ -4514,6 +4516,280 @@ Declaration* Parser::ParseQualIdent(void)
|
||||||
return dec;
|
return dec;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Expression* Parser::ParseLambdaExpression(void)
|
||||||
|
{
|
||||||
|
Declaration* cdec = new Declaration(mScanner->mLocation, DT_TYPE_STRUCT);
|
||||||
|
cdec->mIdent = Ident::Unique("lambda", mCompilationUnits->UniqueID());
|
||||||
|
cdec->mQualIdent = mScope->Mangle(cdec->mIdent);
|
||||||
|
cdec->mFlags |= DTF_DEFINED;
|
||||||
|
|
||||||
|
cdec->mScope = new DeclarationScope(nullptr, SLEVEL_CLASS, cdec->mIdent);
|
||||||
|
|
||||||
|
Declaration* olambda = mLambda;
|
||||||
|
mLambda = cdec;
|
||||||
|
|
||||||
|
Token octoken = mCaptureToken;
|
||||||
|
mCaptureToken = TK_NONE;
|
||||||
|
|
||||||
|
Declaration* vdec = new Declaration(mScanner->mLocation, DT_VARIABLE);
|
||||||
|
|
||||||
|
Declaration* cpdec = cdec->BuildConstPointer(mScanner->mLocation);
|
||||||
|
|
||||||
|
Declaration* fdec = new Declaration(mScanner->mLocation, DT_CONST_FUNCTION);
|
||||||
|
fdec->mIdent = Ident::Unique("operator()");
|
||||||
|
fdec->mQualIdent = cdec->mScope->Mangle(fdec->mIdent);
|
||||||
|
cdec->mScope->Insert(fdec->mIdent, fdec);
|
||||||
|
|
||||||
|
Declaration* pdec = new Declaration(mScanner->mLocation, DT_ARGUMENT);
|
||||||
|
pdec->mBase = cpdec;
|
||||||
|
pdec->mSize = 2;
|
||||||
|
|
||||||
|
Expression* einit = nullptr;
|
||||||
|
|
||||||
|
ConsumeToken(TK_OPEN_BRACKET);
|
||||||
|
if (!ConsumeTokenIf(TK_CLOSE_BRACKET))
|
||||||
|
{
|
||||||
|
// Parse capture list list
|
||||||
|
do {
|
||||||
|
bool reference = false;
|
||||||
|
|
||||||
|
if (ConsumeTokenIf(TK_BINARY_AND))
|
||||||
|
{
|
||||||
|
if (mScanner->mToken == TK_IDENT)
|
||||||
|
reference = true;
|
||||||
|
else
|
||||||
|
mCaptureToken = TK_BINARY_AND;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ConsumeTokenIf(TK_ASSIGN))
|
||||||
|
mCaptureToken = TK_ASSIGN;
|
||||||
|
else if (ConsumeTokenIf(TK_THIS))
|
||||||
|
{
|
||||||
|
Declaration* mdec = new Declaration(mScanner->mLocation, DT_ELEMENT);
|
||||||
|
mdec->mIdent = Ident::Unique("this");
|
||||||
|
mdec->mQualIdent = cdec->mScope->Mangle(mdec->mIdent);
|
||||||
|
if (cdec->mScope->Insert(mdec->mIdent, mdec))
|
||||||
|
mErrors->Error(mdec->mLocation, EERR_DUPLICATE_DEFINITION, "Duplicate lambda capture", mdec->mIdent);
|
||||||
|
|
||||||
|
if (mThisPointer)
|
||||||
|
{
|
||||||
|
Expression* iexp = new Expression(mScanner->mLocation, EX_VARIABLE);
|
||||||
|
iexp->mDecType = mThisPointer->mBase;
|
||||||
|
iexp->mDecValue = mThisPointer;
|
||||||
|
|
||||||
|
mdec->mBase = iexp->mDecType;
|
||||||
|
mdec->mValue = iexp;
|
||||||
|
mdec->mNext = cdec->mParams;
|
||||||
|
cdec->mParams = mdec;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
mErrors->Error(mScanner->mLocation, ERRO_THIS_OUTSIDE_OF_METHOD, "Use of this outside of method");
|
||||||
|
|
||||||
|
mdec->mOffset = cdec->mSize;
|
||||||
|
mdec->mSize = mdec->mBase->mSize;
|
||||||
|
cdec->mSize += mdec->mSize;
|
||||||
|
}
|
||||||
|
else if (mScanner->mToken == TK_IDENT)
|
||||||
|
{
|
||||||
|
Declaration* mdec = new Declaration(mScanner->mLocation, DT_ELEMENT);
|
||||||
|
mdec->mIdent = mScanner->mTokenIdent;
|
||||||
|
mdec->mQualIdent = cdec->mScope->Mangle(mdec->mIdent);
|
||||||
|
if (cdec->mScope->Insert(mdec->mIdent, mdec))
|
||||||
|
mErrors->Error(mdec->mLocation, EERR_DUPLICATE_DEFINITION, "Duplicate lambda capture", mdec->mIdent);
|
||||||
|
|
||||||
|
Expression* iexp = nullptr;
|
||||||
|
|
||||||
|
mScanner->NextToken();
|
||||||
|
if (ConsumeTokenIf(TK_ASSIGN))
|
||||||
|
iexp = ParseExpression(false);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Declaration* mvdec = mScope->Lookup(mdec->mIdent);
|
||||||
|
if (mvdec && mvdec->mType == DT_VARIABLE)
|
||||||
|
{
|
||||||
|
iexp = new Expression(mdec->mLocation, EX_VARIABLE);
|
||||||
|
iexp->mDecType = mvdec->mBase;
|
||||||
|
iexp->mDecValue = mvdec;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
mErrors->Error(mdec->mLocation, EERR_INVALID_CAPTURE, "Invalid variable capture", mdec->mIdent);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (iexp)
|
||||||
|
{
|
||||||
|
if (reference)
|
||||||
|
mdec->mBase = iexp->mDecType->BuildReference(mdec->mLocation);
|
||||||
|
else
|
||||||
|
mdec->mBase = iexp->mDecType;
|
||||||
|
mdec->mValue = iexp;
|
||||||
|
mdec->mNext = cdec->mParams;
|
||||||
|
cdec->mParams = mdec;
|
||||||
|
}
|
||||||
|
|
||||||
|
mdec->mOffset = cdec->mSize;
|
||||||
|
mdec->mSize = mdec->mBase->mSize;
|
||||||
|
cdec->mSize += mdec->mSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
} while (ConsumeTokenIf(TK_COMMA));
|
||||||
|
|
||||||
|
ConsumeToken(TK_CLOSE_BRACKET);
|
||||||
|
}
|
||||||
|
|
||||||
|
Declaration* rtype = new Declaration(mScanner->mLocation, DT_TYPE_AUTO);
|
||||||
|
|
||||||
|
if (mScanner->mToken == TK_OPEN_PARENTHESIS)
|
||||||
|
{
|
||||||
|
fdec->mBase = ParseFunctionDeclaration(rtype);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ConsumeToken(TK_OPEN_PARENTHESIS);
|
||||||
|
fdec->mBase = TheConstVoidTypeDeclaration;
|
||||||
|
}
|
||||||
|
|
||||||
|
PrependThisArgument(fdec->mBase, cpdec);
|
||||||
|
|
||||||
|
fdec->mFlags |= fdec->mBase->mFlags & (DTF_CONST | DTF_VOLATILE);
|
||||||
|
|
||||||
|
fdec->mSection = mCodeSection;
|
||||||
|
|
||||||
|
if (mCompilerOptions & COPT_NATIVE)
|
||||||
|
fdec->mFlags |= DTF_NATIVE;
|
||||||
|
|
||||||
|
fdec->mCompilerOptions = mCompilerOptions;
|
||||||
|
fdec->mBase->mCompilerOptions = mCompilerOptions;
|
||||||
|
|
||||||
|
fdec->mVarIndex = -1;
|
||||||
|
|
||||||
|
int li = mLocalIndex;
|
||||||
|
|
||||||
|
DeclarationScope * oscope = mCaptureScope;
|
||||||
|
mCaptureScope = mScope;
|
||||||
|
|
||||||
|
while (mScope->mLevel >= SLEVEL_NAMESPACE)
|
||||||
|
mScope = mScope->mParent;
|
||||||
|
|
||||||
|
fdec->mValue = ParseFunction(fdec->mBase);
|
||||||
|
|
||||||
|
mScope = mCaptureScope;
|
||||||
|
mLambda = olambda;
|
||||||
|
mCaptureScope = oscope;
|
||||||
|
mCaptureToken = octoken;
|
||||||
|
|
||||||
|
Declaration* pmdec = cdec->mParams;
|
||||||
|
while (pmdec)
|
||||||
|
{
|
||||||
|
Declaration* fcons = pmdec->mBase->mType == DT_TYPE_STRUCT && pmdec->mBase->mScope ? pmdec->mBase->mScope->Lookup(pmdec->mBase->mIdent->PreMangle("+"), SLEVEL_CLASS) : nullptr;
|
||||||
|
|
||||||
|
Expression* ciexp;
|
||||||
|
|
||||||
|
if (fcons)
|
||||||
|
{
|
||||||
|
Expression* vexp = new Expression(pmdec->mLocation, EX_QUALIFY);
|
||||||
|
vexp->mLeft = new Expression(pmdec->mLocation, EX_VARIABLE);
|
||||||
|
vexp->mLeft->mDecType = cdec;
|
||||||
|
vexp->mLeft->mDecValue = vdec;
|
||||||
|
vexp->mDecValue = pmdec;
|
||||||
|
vexp->mDecType = pmdec->mBase;
|
||||||
|
|
||||||
|
Expression* cexp = new Expression(mScanner->mLocation, EX_CONSTANT);
|
||||||
|
cexp->mDecValue = fcons;
|
||||||
|
cexp->mDecType = cexp->mDecValue->mBase;
|
||||||
|
|
||||||
|
Expression* fexp = new Expression(mScanner->mLocation, EX_CALL);
|
||||||
|
fexp->mLeft = cexp;
|
||||||
|
fexp->mRight = pmdec->mValue;
|
||||||
|
|
||||||
|
Expression* texp = new Expression(mScanner->mLocation, EX_PREFIX);
|
||||||
|
texp->mToken = TK_BINARY_AND;
|
||||||
|
texp->mLeft = vexp;
|
||||||
|
texp->mDecType = pmdec->mBase->BuildPointer(mScanner->mLocation);
|
||||||
|
|
||||||
|
Expression* lexp = new Expression(mScanner->mLocation, EX_LIST);
|
||||||
|
lexp->mLeft = texp;
|
||||||
|
lexp->mRight = fexp->mRight;
|
||||||
|
fexp->mRight = lexp;
|
||||||
|
|
||||||
|
fexp = ResolveOverloadCall(fexp);
|
||||||
|
|
||||||
|
Expression* dexp = nullptr;
|
||||||
|
if (pmdec->mBase->mDestructor)
|
||||||
|
{
|
||||||
|
Expression* cexp = new Expression(mScanner->mLocation, EX_CONSTANT);
|
||||||
|
cexp->mDecValue = pmdec->mBase->mDestructor;
|
||||||
|
cexp->mDecType = cexp->mDecValue->mBase;
|
||||||
|
|
||||||
|
dexp = new Expression(mScanner->mLocation, EX_CALL);
|
||||||
|
dexp->mLeft = cexp;
|
||||||
|
dexp->mRight = texp;
|
||||||
|
}
|
||||||
|
|
||||||
|
ciexp = new Expression(mScanner->mLocation, EX_CONSTRUCT);
|
||||||
|
|
||||||
|
ciexp->mLeft = new Expression(mScanner->mLocation, EX_LIST);
|
||||||
|
ciexp->mLeft->mLeft = fexp;
|
||||||
|
ciexp->mLeft->mRight = dexp;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ciexp = new Expression(pmdec->mLocation, EX_INITIALIZATION);
|
||||||
|
ciexp->mToken = TK_ASSIGN;
|
||||||
|
ciexp->mDecType = pmdec->mValue->mDecType;
|
||||||
|
ciexp->mRight = pmdec->mValue;
|
||||||
|
ciexp->mLeft = new Expression(pmdec->mLocation, EX_QUALIFY);
|
||||||
|
ciexp->mLeft->mLeft = new Expression(pmdec->mLocation, EX_VARIABLE);
|
||||||
|
ciexp->mLeft->mLeft->mDecType = cdec;
|
||||||
|
ciexp->mLeft->mLeft->mDecValue = vdec;
|
||||||
|
ciexp->mLeft->mDecValue = pmdec;
|
||||||
|
ciexp->mLeft->mDecType = pmdec->mBase;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (einit)
|
||||||
|
{
|
||||||
|
Expression* lexp = new Expression(mScanner->mLocation, EX_LIST);
|
||||||
|
lexp->mLeft = einit;
|
||||||
|
lexp->mRight = ciexp;
|
||||||
|
einit = lexp;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
einit = ciexp;
|
||||||
|
|
||||||
|
pmdec = pmdec->mNext;
|
||||||
|
}
|
||||||
|
|
||||||
|
fdec->mFlags |= DTF_DEFINED | DTF_REQUEST_INLINE;
|
||||||
|
fdec->mNumVars = mLocalIndex;
|
||||||
|
|
||||||
|
mLocalIndex = li;
|
||||||
|
|
||||||
|
vdec->mBase = cdec;
|
||||||
|
vdec->mVarIndex = mLocalIndex++;
|
||||||
|
vdec->mSize = cdec->mSize;
|
||||||
|
vdec->mFlags |= DTF_DEFINED;
|
||||||
|
vdec->mIdent = cdec->mIdent;
|
||||||
|
|
||||||
|
Expression* vexp = new Expression(mScanner->mLocation, EX_VARIABLE);
|
||||||
|
vexp->mDecType = vdec->mBase;
|
||||||
|
vexp->mDecValue = vdec;
|
||||||
|
|
||||||
|
|
||||||
|
if (einit)
|
||||||
|
{
|
||||||
|
Expression* conex = new Expression(mScanner->mLocation, EX_CONSTRUCT);
|
||||||
|
conex->mRight = vexp;
|
||||||
|
conex->mDecType = vexp->mDecType;
|
||||||
|
|
||||||
|
conex->mLeft = new Expression(mScanner->mLocation, EX_LIST);
|
||||||
|
conex->mLeft->mLeft = einit;
|
||||||
|
conex->mLeft->mRight = nullptr;
|
||||||
|
|
||||||
|
return conex;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return vexp;
|
||||||
|
}
|
||||||
|
|
||||||
Expression* Parser::ParseSimpleExpression(bool lhs)
|
Expression* Parser::ParseSimpleExpression(bool lhs)
|
||||||
{
|
{
|
||||||
Declaration* dec = nullptr;
|
Declaration* dec = nullptr;
|
||||||
|
@ -4701,7 +4977,31 @@ Expression* Parser::ParseSimpleExpression(bool lhs)
|
||||||
mScanner->NextToken();
|
mScanner->NextToken();
|
||||||
break;
|
break;
|
||||||
case TK_THIS:
|
case TK_THIS:
|
||||||
if (mThisPointer)
|
if (mLambda)
|
||||||
|
{
|
||||||
|
dec = mLambda->mScope->Lookup(Ident::Unique("this"), SLEVEL_CLASS);
|
||||||
|
if (dec)
|
||||||
|
{
|
||||||
|
Expression* texp = new Expression(mScanner->mLocation, EX_VARIABLE);
|
||||||
|
texp->mDecType = mThisPointer->mBase;
|
||||||
|
texp->mDecValue = mThisPointer;
|
||||||
|
|
||||||
|
Expression* dexp = new Expression(mScanner->mLocation, EX_PREFIX);
|
||||||
|
dexp->mToken = TK_MUL;
|
||||||
|
dexp->mDecType = texp->mDecType->mBase;
|
||||||
|
dexp->mLeft = texp;
|
||||||
|
|
||||||
|
dexp = dexp->ConstantFold(mErrors, mDataSection);
|
||||||
|
|
||||||
|
exp = new Expression(mScanner->mLocation, EX_QUALIFY);
|
||||||
|
exp->mLeft = dexp;
|
||||||
|
exp->mDecType = dec->mBase;
|
||||||
|
exp->mDecValue = dec;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
mErrors->Error(mScanner->mLocation, ERRO_THIS_OUTSIDE_OF_METHOD, "Use of this outside of method");
|
||||||
|
}
|
||||||
|
else if (mThisPointer)
|
||||||
{
|
{
|
||||||
exp = new Expression(mScanner->mLocation, EX_VARIABLE);
|
exp = new Expression(mScanner->mLocation, EX_VARIABLE);
|
||||||
exp->mDecType = mThisPointer->mBase;
|
exp->mDecType = mThisPointer->mBase;
|
||||||
|
@ -4713,6 +5013,35 @@ Expression* Parser::ParseSimpleExpression(bool lhs)
|
||||||
mScanner->NextToken();
|
mScanner->NextToken();
|
||||||
break;
|
break;
|
||||||
case TK_IDENT:
|
case TK_IDENT:
|
||||||
|
if (mLambda && mCaptureToken != TK_NONE && !mScope->Lookup(mScanner->mTokenIdent, SLEVEL_CLASS) && !mLambda->mScope->Lookup(mScanner->mTokenIdent, SLEVEL_CLASS))
|
||||||
|
{
|
||||||
|
Declaration * mvdec = mCaptureScope->Lookup(mScanner->mTokenIdent, SLEVEL_CLASS);
|
||||||
|
if (mvdec && mvdec->mType == DT_VARIABLE)
|
||||||
|
{
|
||||||
|
Declaration* mdec = new Declaration(mScanner->mLocation, DT_ELEMENT);
|
||||||
|
mdec->mIdent = mScanner->mTokenIdent;
|
||||||
|
mdec->mQualIdent = mLambda->mScope->Mangle(mdec->mIdent);
|
||||||
|
if (mLambda->mScope->Insert(mdec->mIdent, mdec))
|
||||||
|
mErrors->Error(mdec->mLocation, EERR_DUPLICATE_DEFINITION, "Duplicate lambda capture", mdec->mIdent);
|
||||||
|
|
||||||
|
Expression* iexp = new Expression(mdec->mLocation, EX_VARIABLE);
|
||||||
|
iexp->mDecType = mvdec->mBase;
|
||||||
|
iexp->mDecValue = mvdec;
|
||||||
|
|
||||||
|
if (mCaptureToken == TK_BINARY_AND)
|
||||||
|
mdec->mBase = iexp->mDecType->BuildReference(mdec->mLocation);
|
||||||
|
else
|
||||||
|
mdec->mBase = iexp->mDecType;
|
||||||
|
mdec->mValue = iexp;
|
||||||
|
mdec->mNext = mLambda->mParams;
|
||||||
|
mLambda->mParams = mdec;
|
||||||
|
|
||||||
|
mdec->mOffset = mLambda->mSize;
|
||||||
|
mdec->mSize = mdec->mBase->mSize;
|
||||||
|
mLambda->mSize += mdec->mSize;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (mThisPointer && mThisPointer->mType == DT_ARGUMENT && !mScope->Lookup(mScanner->mTokenIdent, SLEVEL_FUNCTION))
|
if (mThisPointer && mThisPointer->mType == DT_ARGUMENT && !mScope->Lookup(mScanner->mTokenIdent, SLEVEL_FUNCTION))
|
||||||
{
|
{
|
||||||
int offset;
|
int offset;
|
||||||
|
@ -4883,6 +5212,9 @@ Expression* Parser::ParseSimpleExpression(bool lhs)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case TK_OPEN_BRACKET:
|
||||||
|
exp = ParseLambdaExpression();
|
||||||
|
break;
|
||||||
case TK_ASM:
|
case TK_ASM:
|
||||||
mScanner->NextToken();
|
mScanner->NextToken();
|
||||||
if (mScanner->mToken == TK_OPEN_BRACE)
|
if (mScanner->mToken == TK_OPEN_BRACE)
|
||||||
|
@ -7108,6 +7440,8 @@ Expression* Parser::ParseListExpression(bool lhs)
|
||||||
Expression* Parser::ParseFunction(Declaration * dec)
|
Expression* Parser::ParseFunction(Declaration * dec)
|
||||||
{
|
{
|
||||||
Declaration* othis = mThisPointer;
|
Declaration* othis = mThisPointer;
|
||||||
|
Declaration* ofunc = mFunctionType;
|
||||||
|
|
||||||
if (dec->mFlags & DTF_FUNC_THIS)
|
if (dec->mFlags & DTF_FUNC_THIS)
|
||||||
mThisPointer = dec->mParams;
|
mThisPointer = dec->mParams;
|
||||||
|
|
||||||
|
@ -7182,6 +7516,7 @@ Expression* Parser::ParseFunction(Declaration * dec)
|
||||||
mScope = oscope;
|
mScope = oscope;
|
||||||
|
|
||||||
mThisPointer = othis;
|
mThisPointer = othis;
|
||||||
|
mFunctionType = ofunc;
|
||||||
|
|
||||||
return exp;
|
return exp;
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,10 +12,11 @@ public:
|
||||||
|
|
||||||
Parser* Clone(void);
|
Parser* Clone(void);
|
||||||
|
|
||||||
DeclarationScope * mGlobals, * mScope, * mTemplateScope;
|
DeclarationScope * mGlobals, * mScope, * mTemplateScope, * mCaptureScope;
|
||||||
int mLocalIndex;
|
int mLocalIndex;
|
||||||
CompilationUnits * mCompilationUnits;
|
CompilationUnits * mCompilationUnits;
|
||||||
Declaration * mThisPointer, * mFunctionType, * mFunction;
|
Declaration * mThisPointer, * mFunctionType, * mFunction, * mLambda;
|
||||||
|
Token mCaptureToken;
|
||||||
|
|
||||||
LinkerSection * mCodeSection, * mDataSection, * mBSSection;
|
LinkerSection * mCodeSection, * mDataSection, * mBSSection;
|
||||||
|
|
||||||
|
@ -105,6 +106,7 @@ protected:
|
||||||
void CompleteTemplateExpansion(Declaration* tmpld);
|
void CompleteTemplateExpansion(Declaration* tmpld);
|
||||||
|
|
||||||
Expression* ParseNewOperator(void);
|
Expression* ParseNewOperator(void);
|
||||||
|
Expression* ParseLambdaExpression(void);
|
||||||
|
|
||||||
Expression* ParseSimpleExpression(bool lhs);
|
Expression* ParseSimpleExpression(bool lhs);
|
||||||
Expression* ParsePrefixExpression(bool lhs);
|
Expression* ParsePrefixExpression(bool lhs);
|
||||||
|
|
Loading…
Reference in New Issue