diff --git a/oscar64/Declaration.cpp b/oscar64/Declaration.cpp index 9e111b1..8fb23a2 100644 --- a/oscar64/Declaration.cpp +++ b/oscar64/Declaration.cpp @@ -956,6 +956,14 @@ Declaration* Declaration::BuildRValueRef(const Location& loc) return pdec; } +Declaration* Declaration::NonRefBase(void) +{ + if (IsReference()) + return mBase; + else + return this; +} + Declaration* Declaration::BuildConstRValueRef(const Location& loc) { Declaration* pdec = new Declaration(loc, DT_TYPE_RVALUEREF); diff --git a/oscar64/Declaration.h b/oscar64/Declaration.h index 4b5e7bb..a4d1b70 100644 --- a/oscar64/Declaration.h +++ b/oscar64/Declaration.h @@ -309,6 +309,7 @@ public: Declaration* BuildConstReference(const Location& loc); Declaration* BuildRValueRef(const Location& loc); Declaration* BuildConstRValueRef(const Location& loc); + Declaration* NonRefBase(void); DecType ValueType(void) const; diff --git a/oscar64/GlobalAnalyzer.cpp b/oscar64/GlobalAnalyzer.cpp index 64d910e..609826b 100644 --- a/oscar64/GlobalAnalyzer.cpp +++ b/oscar64/GlobalAnalyzer.cpp @@ -155,12 +155,14 @@ void GlobalAnalyzer::AutoInline(void) Declaration* dec = f->mBase->mParams; while (dec) { - nparams++; + nparams += dec->mSize; dec = dec->mNext; } int cost = (f->mComplexity - 20 * nparams); +// printf("CHEK INLINING %s %d * (%d - 1)\n", f->mIdent->mString, cost, f->mCallers.Size()); + bool doinline = false; if ((f->mCompilerOptions & COPT_OPTIMIZE_INLINE) && (f->mFlags & DTF_REQUEST_INLINE)) doinline = true; @@ -171,9 +173,8 @@ void GlobalAnalyzer::AutoInline(void) if (doinline) { -#if 0 - printf("INLINING %s %d * (%d - 1)\n", f->mIdent->mString, cost, f->mCallers.Size()); -#endif +// printf("INLINING %s %d * (%d - 1)\n", f->mIdent->mString, cost, f->mCallers.Size()); + f->mFlags |= DTF_INLINE; for (int j = 0; j < f->mCallers.Size(); j++) { @@ -655,8 +656,6 @@ Declaration * GlobalAnalyzer::Analyze(Expression* exp, Declaration* procDec, boo { Declaration* ldec, * rdec; - procDec->mComplexity += 10; - switch (exp->mType) { case EX_ERROR: @@ -715,6 +714,8 @@ Declaration * GlobalAnalyzer::Analyze(Expression* exp, Declaration* procDec, boo return exp->mDecValue; case EX_INITIALIZATION: case EX_ASSIGNMENT: + procDec->mComplexity += 10 * exp->mLeft->mDecType->mSize; + ldec = Analyze(exp->mLeft, procDec, true); rdec = Analyze(exp->mRight, procDec, false); if (exp->mLeft->mType == EX_VARIABLE && exp->mRight->mType == EX_CALL && exp->mLeft->mDecType->mType == DT_TYPE_STRUCT) @@ -723,16 +724,22 @@ Declaration * GlobalAnalyzer::Analyze(Expression* exp, Declaration* procDec, boo return ldec; case EX_BINARY: + procDec->mComplexity += 10 * exp->mDecType->mSize; + ldec = Analyze(exp->mLeft, procDec, lhs); rdec = Analyze(exp->mRight, procDec, lhs); return ldec; case EX_RELATIONAL: + procDec->mComplexity += 10 * exp->mLeft->mDecType->mSize; + ldec = Analyze(exp->mLeft, procDec, false); rdec = Analyze(exp->mRight, procDec, false); return TheBoolTypeDeclaration; case EX_PREINCDEC: + procDec->mComplexity += 10 * exp->mLeft->mDecType->mSize; + return Analyze(exp->mLeft, procDec, true); case EX_PREFIX: if (exp->mToken == TK_BINARY_AND) @@ -751,13 +758,21 @@ Declaration * GlobalAnalyzer::Analyze(Expression* exp, Declaration* procDec, boo return exp->mDecType; } else + { + procDec->mComplexity += 10 * exp->mLeft->mDecType->mSize; return Analyze(exp->mLeft, procDec, false); + } break; case EX_POSTFIX: + procDec->mComplexity += 10 * exp->mLeft->mDecType->mSize; break; case EX_POSTINCDEC: + procDec->mComplexity += 10 * exp->mLeft->mDecType->mSize; + return Analyze(exp->mLeft, procDec, true); case EX_INDEX: + procDec->mComplexity += 10 * exp->mLeft->mDecType->mSize; + ldec = Analyze(exp->mLeft, procDec, lhs); if (ldec->mType == DT_VARIABLE || ldec->mType == DT_ARGUMENT) { @@ -786,6 +801,8 @@ Declaration * GlobalAnalyzer::Analyze(Expression* exp, Declaration* procDec, boo // intentional fall through case EX_CALL: case EX_INLINE: + procDec->mComplexity += 10; + ldec = Analyze(exp->mLeft, procDec, false); if ((ldec->mFlags & DTF_INTRINSIC) && !ldec->mValue) { @@ -813,6 +830,8 @@ Declaration * GlobalAnalyzer::Analyze(Expression* exp, Declaration* procDec, boo { Expression* pex = rex->mType == EX_LIST ? rex->mLeft : rex; + procDec->mComplexity += 5 * pex->mDecType->mSize; + if (pdec && !(ldec->mBase->mFlags & DTF_VARIADIC) && !(ldec->mFlags & (DTF_INTRINSIC | DTF_FUNC_ASSEMBLER))) { #if 1 @@ -930,10 +949,14 @@ Declaration * GlobalAnalyzer::Analyze(Expression* exp, Declaration* procDec, boo case EX_WHILE: procDec->mFlags &= ~DTF_FUNC_CONSTEXPR; + procDec->mComplexity += 20; + ldec = Analyze(exp->mLeft, procDec, false); rdec = Analyze(exp->mRight, procDec, false); break; case EX_IF: + procDec->mComplexity += 20; + ldec = Analyze(exp->mLeft, procDec, false); rdec = Analyze(exp->mRight->mLeft, procDec, false); if (exp->mRight->mRight) @@ -944,6 +967,8 @@ Declaration * GlobalAnalyzer::Analyze(Expression* exp, Declaration* procDec, boo case EX_FOR: procDec->mFlags &= ~DTF_FUNC_CONSTEXPR; + procDec->mComplexity += 30; + if (exp->mLeft->mRight) ldec = Analyze(exp->mLeft->mRight, procDec, false); if (exp->mLeft->mLeft->mLeft) @@ -953,6 +978,8 @@ Declaration * GlobalAnalyzer::Analyze(Expression* exp, Declaration* procDec, boo ldec = Analyze(exp->mLeft->mLeft->mRight, procDec, false); break; case EX_DO: + procDec->mComplexity += 20; + ldec = Analyze(exp->mLeft, procDec, false); rdec = Analyze(exp->mRight, procDec, false); break; @@ -989,6 +1016,8 @@ Declaration * GlobalAnalyzer::Analyze(Expression* exp, Declaration* procDec, boo exp = exp->mRight; while (exp) { + procDec->mComplexity += 10; + if (exp->mLeft->mRight) rdec = Analyze(exp->mLeft->mRight, procDec, false); exp = exp->mRight; @@ -999,6 +1028,8 @@ Declaration * GlobalAnalyzer::Analyze(Expression* exp, Declaration* procDec, boo case EX_DEFAULT: break; case EX_CONDITIONAL: + 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)); diff --git a/oscar64/InterCode.cpp b/oscar64/InterCode.cpp index 1189841..28be3a2 100644 --- a/oscar64/InterCode.cpp +++ b/oscar64/InterCode.cpp @@ -3425,11 +3425,32 @@ bool InterInstruction::PropagateConstTemps(const GrowingInstructionPtrArray& cte } } + if (!changed) + { + if (mSrc[0].mType == IT_POINTER && mSrc[1].mType == IT_POINTER && + mSrc[0].mTemp >= 0 && mSrc[1].mTemp >= 0 && + ctemps[mSrc[0].mTemp] && ctemps[mSrc[1].mTemp]) + { + InterInstruction* si0 = ctemps[mSrc[0].mTemp]; + InterInstruction* si1 = ctemps[mSrc[1].mTemp]; + + if (si0->mConst.mMemory != IM_INDIRECT && si1->mConst.mMemory != IM_INDIRECT) + { + mCode = IC_CONSTANT; + mConst.mIntConst = ::ConstantRelationalPointerFolding(mOperator, si1->mConst, si0->mConst); + mConst.mType = IT_BOOL; + mNumOperands = 0; + return true; + } + } + } + if (changed) { this->ConstantFolding(); return true; } + } break; case IC_FREE: diff --git a/oscar64/Parser.cpp b/oscar64/Parser.cpp index bdc857b..5629a23 100644 --- a/oscar64/Parser.cpp +++ b/oscar64/Parser.cpp @@ -2588,6 +2588,7 @@ void Parser::AddDefaultConstructors(Declaration* pthis) Expression* iexp = new Expression(mScanner->mLocation, EX_POSTINCDEC); iexp->mToken = TK_INC; iexp->mLeft = pexp; + iexp->mDecType = pexp->mDecType; Expression* fexp = new Expression(mScanner->mLocation, EX_CONSTANT); fexp->mDecValue = pthis->mBase->mDefaultConstructor; @@ -2664,6 +2665,7 @@ void Parser::AddDefaultConstructors(Declaration* pthis) Expression* iexp = new Expression(mScanner->mLocation, EX_POSTINCDEC); iexp->mToken = TK_INC; iexp->mLeft = pexp; + iexp->mDecType = pexp->mDecType; Expression* fexp = new Expression(mScanner->mLocation, EX_CONSTANT); fexp->mDecValue = pthis->mBase->mDestructor; @@ -2753,10 +2755,12 @@ void Parser::AddDefaultConstructors(Declaration* pthis) Expression* iexp = new Expression(mScanner->mLocation, EX_POSTINCDEC); iexp->mToken = TK_INC; iexp->mLeft = pexp; + iexp->mDecType = pexp->mDecType; Expression* isexp = new Expression(mScanner->mLocation, EX_POSTINCDEC); isexp->mToken = TK_INC; isexp->mLeft = psexp; + isexp->mDecType = psexp->mDecType; Expression* disexp = new Expression(mScanner->mLocation, EX_PREFIX); disexp->mToken = TK_MUL; @@ -2766,6 +2770,7 @@ void Parser::AddDefaultConstructors(Declaration* pthis) Expression* dexp = new Expression(mScanner->mLocation, EX_POSTINCDEC); dexp->mToken = TK_DEC; dexp->mLeft = aexp; + dexp->mDecType = aexp->mDecType; Expression* fexp = new Expression(mScanner->mLocation, EX_CONSTANT); fexp->mDecValue = pthis->mBase->mCopyConstructor; @@ -2854,10 +2859,12 @@ void Parser::AddDefaultConstructors(Declaration* pthis) Expression* iexp = new Expression(mScanner->mLocation, EX_POSTINCDEC); iexp->mToken = TK_INC; iexp->mLeft = pexp; + iexp->mDecType = pexp->mDecType; Expression* isexp = new Expression(mScanner->mLocation, EX_POSTINCDEC); isexp->mToken = TK_INC; isexp->mLeft = psexp; + isexp->mDecType = psexp->mDecType; Expression* disexp = new Expression(mScanner->mLocation, EX_PREFIX); disexp->mToken = TK_MUL; @@ -2867,6 +2874,7 @@ void Parser::AddDefaultConstructors(Declaration* pthis) Expression* dexp = new Expression(mScanner->mLocation, EX_POSTINCDEC); dexp->mToken = TK_DEC; dexp->mLeft = aexp; + dexp->mDecValue = aexp->mDecType; Expression* fexp = new Expression(mScanner->mLocation, EX_CONSTANT); fexp->mDecValue = pthis->mBase->mCopyAssignment; @@ -4146,7 +4154,7 @@ Declaration* Parser::ParseDeclaration(Declaration * pdec, bool variable, bool ex ldec = ndec; // ndec->mNext = nullptr; - if (ConsumeTokenIf(TK_COLON)) + if (!mFunctionType && ConsumeTokenIf(TK_COLON)) { Expression* exp = ParseRExpression(); if (!ndec->mBase->IsIntegerType()) @@ -4361,10 +4369,10 @@ Expression* Parser::ParseDeclarationExpression(Declaration * pdec) { while (dec) { + Expression* nexp; + if (dec->mValue && !(dec->mFlags & DTF_GLOBAL)) { - Expression* nexp; - if ((mCompilerOptions & COPT_CPLUSPLUS) && dec->mValue->mType == EX_CONSTRUCT) { nexp = dec->mValue; @@ -4446,21 +4454,27 @@ Expression* Parser::ParseDeclarationExpression(Declaration * pdec) nexp->mRight = dec->mValue; } + } + else + { + nexp = new Expression(dec->mLocation, EX_VARIABLE); + nexp->mDecValue = dec; + nexp->mDecType = dec->mBase; + } - if (!exp) - exp = nexp; - else + if (!exp) + exp = nexp; + else + { + if (!rexp) { - if (!rexp) - { - rexp = new Expression(nexp->mLocation, EX_SEQUENCE); - rexp->mLeft = exp; - exp = rexp; - } - rexp->mRight = new Expression(nexp->mLocation, EX_SEQUENCE); - rexp = rexp->mRight; - rexp->mLeft = nexp; + rexp = new Expression(nexp->mLocation, EX_SEQUENCE); + rexp->mLeft = exp; + exp = rexp; } + rexp->mRight = new Expression(nexp->mLocation, EX_SEQUENCE); + rexp = rexp->mRight; + rexp->mLeft = nexp; } dec = dec->mNext; @@ -5213,7 +5227,13 @@ Expression* Parser::ParseSimpleExpression(bool lhs) } break; case TK_OPEN_BRACKET: - exp = ParseLambdaExpression(); + if (mCompilerOptions & COPT_CPLUSPLUS) + exp = ParseLambdaExpression(); + else + { + mErrors->Error(mScanner->mLocation, EERR_SYNTAX, "Term starts with invalid token", TokenNames[mScanner->mToken]); + mScanner->NextToken(); + } break; case TK_ASM: mScanner->NextToken(); @@ -7646,32 +7666,216 @@ Expression* Parser::ParseStatement(void) Expression* initExp = nullptr, * iterateExp = nullptr, * conditionExp = nullptr, * bodyExp = nullptr, * finalExp = nullptr; - // Assignment if (mScanner->mToken != TK_SEMICOLON) initExp = CleanupExpression(ParseExpression(true)); - if (mScanner->mToken == TK_SEMICOLON) - mScanner->NextToken(); - else - mErrors->Error(mScanner->mLocation, EERR_SYNTAX, "';' expected"); - // Condition - if (mScanner->mToken != TK_SEMICOLON) - conditionExp = CoerceExpression(CleanupExpression(ParseExpression(false)), TheBoolTypeDeclaration); + if ((mCompilerOptions & COPT_CPLUSPLUS) && ConsumeTokenIf(TK_COLON)) + { + Expression* containerExp = ParseExpression(false); + if (initExp->mType == EX_VARIABLE) + { + if (containerExp->mDecType->mType == DT_TYPE_ARRAY) + { + Declaration* iterVarDec = new Declaration(mScanner->mLocation, DT_VARIABLE); + iterVarDec->mBase = containerExp->mDecType->mBase->BuildPointer(mScanner->mLocation); + iterVarDec->mVarIndex = mLocalIndex++; + iterVarDec->mSize = iterVarDec->mBase->mSize; + iterVarDec->mFlags |= DTF_DEFINED; - if (mScanner->mToken == TK_SEMICOLON) - mScanner->NextToken(); - else - mErrors->Error(mScanner->mLocation, EERR_SYNTAX, "';' expected"); + Declaration* endVarDec = new Declaration(mScanner->mLocation, DT_VARIABLE); + endVarDec->mBase = iterVarDec->mBase; + endVarDec->mVarIndex = mLocalIndex++; + endVarDec->mSize = endVarDec->mBase->mSize; + endVarDec->mFlags |= DTF_DEFINED; - // Iteration - if (mScanner->mToken != TK_CLOSE_PARENTHESIS) - iterateExp = CleanupExpression(ParseExpression(false)); - if (mScanner->mToken == TK_CLOSE_PARENTHESIS) - mScanner->NextToken(); + Declaration* valueVarDec = initExp->mDecValue; + if (valueVarDec->mBase->mType == DT_TYPE_AUTO) + valueVarDec->mBase = containerExp->mDecType->mBase; + + initExp = new Expression(mScanner->mLocation, EX_LIST); + initExp->mLeft = new Expression(mScanner->mLocation, EX_INITIALIZATION); + initExp->mLeft->mToken = TK_ASSIGN; + initExp->mLeft->mLeft = new Expression(mScanner->mLocation, EX_VARIABLE); + initExp->mLeft->mLeft->mDecType = iterVarDec->mBase; + initExp->mLeft->mLeft->mDecValue = iterVarDec; + initExp->mLeft->mRight = containerExp; + + initExp->mRight = new Expression(mScanner->mLocation, EX_INITIALIZATION); + initExp->mRight->mToken = TK_ASSIGN; + initExp->mRight->mLeft = new Expression(mScanner->mLocation, EX_VARIABLE); + initExp->mRight->mLeft->mDecType = endVarDec->mBase; + initExp->mRight->mLeft->mDecValue = endVarDec; + initExp->mRight->mRight = new Expression(mScanner->mLocation, EX_BINARY); + initExp->mRight->mRight->mToken = TK_ADD; + initExp->mRight->mRight->mDecType = iterVarDec->mBase; + initExp->mRight->mRight->mLeft = new Expression(mScanner->mLocation, EX_VARIABLE); + initExp->mRight->mRight->mLeft->mDecType = iterVarDec->mBase; + initExp->mRight->mRight->mLeft->mDecValue = iterVarDec; + initExp->mRight->mRight->mRight = new Expression(mScanner->mLocation, EX_CONSTANT); + initExp->mRight->mRight->mRight->mDecType = TheSignedIntTypeDeclaration; + initExp->mRight->mRight->mRight->mDecValue = new Declaration(mScanner->mLocation, DT_CONST_INTEGER); + initExp->mRight->mRight->mRight->mDecValue->mBase = TheSignedIntTypeDeclaration; + initExp->mRight->mRight->mRight->mDecValue->mSize = 2; + initExp->mRight->mRight->mRight->mDecValue->mInteger = containerExp->mDecType->mSize; + + iterateExp = new Expression(mScanner->mLocation, EX_PREINCDEC); + iterateExp->mToken = TK_INC; + iterateExp->mLeft = new Expression(mScanner->mLocation, EX_VARIABLE); + iterateExp->mLeft->mDecType = iterVarDec->mBase; + iterateExp->mLeft->mDecValue = iterVarDec; + + conditionExp = new Expression(mScanner->mLocation, EX_RELATIONAL); + conditionExp->mToken = TK_NOT_EQUAL; + conditionExp->mLeft = new Expression(mScanner->mLocation, EX_VARIABLE); + conditionExp->mLeft->mDecType = iterVarDec->mBase; + conditionExp->mLeft->mDecValue = iterVarDec; + conditionExp->mRight = new Expression(mScanner->mLocation, EX_VARIABLE); + conditionExp->mRight->mDecType = endVarDec->mBase; + conditionExp->mRight->mDecValue = endVarDec; + + bodyExp = new Expression(mScanner->mLocation, EX_ASSIGNMENT); + bodyExp->mToken = TK_ASSIGN; + bodyExp->mLeft = new Expression(mScanner->mLocation, EX_VARIABLE); + bodyExp->mLeft->mDecType = valueVarDec->mBase; + bodyExp->mLeft->mDecValue = valueVarDec; + bodyExp->mRight = new Expression(mScanner->mLocation, EX_PREFIX); + bodyExp->mRight->mToken = TK_MUL; + bodyExp->mRight->mDecType = containerExp->mDecType->mBase; + bodyExp->mRight->mLeft = new Expression(mScanner->mLocation, EX_VARIABLE); + bodyExp->mRight->mLeft->mDecType = iterVarDec->mBase; + bodyExp->mRight->mLeft->mDecValue = iterVarDec; + } + else if (containerExp->mDecType->mType == DT_TYPE_STRUCT) + { + Declaration* fbegin = containerExp->mDecType->mScope->Lookup(Ident::Unique("begin")); + Declaration* fend = containerExp->mDecType->mScope->Lookup(Ident::Unique("end")); + + if (fbegin && fend) + { + Expression* cexp = new Expression(mScanner->mLocation, EX_PREFIX); + cexp->mToken = TK_BINARY_AND; + cexp->mDecType = containerExp->mDecType->BuildPointer(mScanner->mLocation); + cexp->mLeft = containerExp; + + Declaration* iterVarDec = new Declaration(mScanner->mLocation, DT_VARIABLE); + iterVarDec->mBase = fbegin->mBase->mBase->NonRefBase(); + iterVarDec->mVarIndex = mLocalIndex++; + iterVarDec->mSize = iterVarDec->mBase->mSize; + iterVarDec->mFlags |= DTF_DEFINED; + + Declaration* endVarDec = new Declaration(mScanner->mLocation, DT_VARIABLE); + endVarDec->mBase = fend->mBase->mBase->NonRefBase(); + endVarDec->mVarIndex = mLocalIndex++; + endVarDec->mSize = endVarDec->mBase->mSize; + endVarDec->mFlags |= DTF_DEFINED; + + Declaration* valueVarDec = initExp->mDecValue; + + initExp = new Expression(mScanner->mLocation, EX_LIST); + initExp->mLeft = new Expression(mScanner->mLocation, EX_INITIALIZATION); + initExp->mLeft->mToken = TK_ASSIGN; + initExp->mLeft->mLeft = new Expression(mScanner->mLocation, EX_VARIABLE); + initExp->mLeft->mLeft->mDecType = iterVarDec->mBase; + initExp->mLeft->mLeft->mDecValue = iterVarDec; + initExp->mLeft->mRight = new Expression(mScanner->mLocation, EX_CALL); + initExp->mLeft->mRight->mDecType = fbegin->mBase->mBase; + initExp->mLeft->mRight->mLeft = new Expression(mScanner->mLocation, EX_CONSTANT); + initExp->mLeft->mRight->mLeft->mDecType = fbegin->mBase; + initExp->mLeft->mRight->mLeft->mDecValue = fbegin; + initExp->mLeft->mRight->mRight = cexp; + + initExp->mRight = new Expression(mScanner->mLocation, EX_INITIALIZATION); + initExp->mRight->mToken = TK_ASSIGN; + initExp->mRight->mLeft = new Expression(mScanner->mLocation, EX_VARIABLE); + initExp->mRight->mLeft->mDecType = endVarDec->mBase; + initExp->mRight->mLeft->mDecValue = endVarDec; + initExp->mRight->mRight = new Expression(mScanner->mLocation, EX_CALL); + initExp->mRight->mRight->mDecType = fend->mBase->mBase; + initExp->mRight->mRight->mLeft = new Expression(mScanner->mLocation, EX_CONSTANT); + initExp->mRight->mRight->mLeft->mDecType = fend->mBase; + initExp->mRight->mRight->mLeft->mDecValue = fend; + initExp->mRight->mRight->mRight = cexp; + + iterateExp = new Expression(mScanner->mLocation, EX_PREINCDEC); + iterateExp->mToken = TK_INC; + iterateExp->mLeft = new Expression(mScanner->mLocation, EX_VARIABLE); + iterateExp->mLeft->mDecType = iterVarDec->mBase; + iterateExp->mLeft->mDecValue = iterVarDec; + iterateExp = CheckOperatorOverload(iterateExp); + + conditionExp = new Expression(mScanner->mLocation, EX_RELATIONAL); + conditionExp->mToken = TK_NOT_EQUAL; + conditionExp->mLeft = new Expression(mScanner->mLocation, EX_VARIABLE); + conditionExp->mLeft->mDecType = iterVarDec->mBase; + conditionExp->mLeft->mDecValue = iterVarDec; + conditionExp->mRight = new Expression(mScanner->mLocation, EX_VARIABLE); + conditionExp->mRight->mDecType = endVarDec->mBase; + conditionExp->mRight->mDecValue = endVarDec; + conditionExp = CheckOperatorOverload(conditionExp); + + bodyExp = new Expression(mScanner->mLocation, EX_ASSIGNMENT); + bodyExp->mToken = TK_ASSIGN; + bodyExp->mLeft = new Expression(mScanner->mLocation, EX_VARIABLE); + + bodyExp->mRight = new Expression(mScanner->mLocation, EX_PREFIX); + bodyExp->mRight->mToken = TK_MUL; + bodyExp->mRight->mDecType = valueVarDec->mBase; + bodyExp->mRight->mLeft = new Expression(mScanner->mLocation, EX_VARIABLE); + bodyExp->mRight->mLeft->mDecType = iterVarDec->mBase; + bodyExp->mRight->mLeft->mDecValue = iterVarDec; + bodyExp->mRight = CheckOperatorOverload(bodyExp->mRight); + + if (valueVarDec->mBase->mType == DT_TYPE_AUTO) + valueVarDec->mBase = bodyExp->mRight->mDecType->NonRefBase(); + + bodyExp->mLeft->mDecType = valueVarDec->mBase; + bodyExp->mLeft->mDecValue = valueVarDec; + bodyExp = CheckOperatorOverload(bodyExp); + } + else + mErrors->Error(containerExp->mLocation, EERR_INCOMPATIBLE_TYPES, "Array or container expected"); + } + else + mErrors->Error(containerExp->mLocation, EERR_INCOMPATIBLE_TYPES, "Array or container expected"); + } + else + mErrors->Error(initExp->mLocation, EERR_INCOMPATIBLE_TYPES, "Variable expected"); + } else - mErrors->Error(mScanner->mLocation, EERR_SYNTAX, "')' expected"); - bodyExp = ParseStatement(); + { + if (mScanner->mToken == TK_SEMICOLON) + mScanner->NextToken(); + else + mErrors->Error(mScanner->mLocation, EERR_SYNTAX, "';' expected"); + + // Condition + if (mScanner->mToken != TK_SEMICOLON) + conditionExp = CoerceExpression(CleanupExpression(ParseExpression(false)), TheBoolTypeDeclaration); + + if (mScanner->mToken == TK_SEMICOLON) + mScanner->NextToken(); + else + mErrors->Error(mScanner->mLocation, EERR_SYNTAX, "';' expected"); + + // Iteration + if (mScanner->mToken != TK_CLOSE_PARENTHESIS) + iterateExp = CleanupExpression(ParseExpression(false)); + } + + ConsumeToken(TK_CLOSE_PARENTHESIS); + + Expression * innerExp = ParseStatement(); + if (bodyExp) + { + Expression* exp = new Expression(bodyExp->mLocation, EX_SEQUENCE); + exp->mLeft = bodyExp; + exp->mRight = innerExp; + bodyExp = exp; + } + else + bodyExp = innerExp; + mScope->End(mScanner->mLocation); exp->mLeft = new Expression(mScanner->mLocation, EX_SEQUENCE);