void SemanticAnalyzer::visitForLoop(const ForLoopPtr& node) { ScopedCodeBlockPtr codeBlock = static_pointer_cast<ScopedCodeBlock>(node->getCodeBlock()); if(node->getInitializer()) { ScopeGuard guard(codeBlock.get(), this); node->getInitializer()->accept(this); } else { for(int i = 0; i < node->numInit(); i++) { node->getInit(i)->accept(this); } } { //condition and step expression should be evaluated under for statement's scope ScopeGuard guard(codeBlock.get(), this); //check condition node->getCondition()->accept(this); GlobalScope *global = symbolRegistry->getGlobalScope(); TypePtr conditionType = node->getCondition()->getType(); if (!conditionType->conformTo(global->BooleanType())) { error(node->getCondition(), Errors::E_TYPE_DOES_NOT_CONFORM_TO_PROTOCOL_2_, conditionType->toString(), L"BooleanType"); return; } //visit step expressions node->getStep()->accept(this); } //visit code block node->getCodeBlock()->accept(this); }
void SemanticAnalyzer::visitWhileLoop(const WhileLoopPtr& node) { node->getCondition()->accept(this); GlobalScope* global = symbolRegistry->getGlobalScope(); TypePtr conditionType = node->getCondition()->getType(); if(!conditionType->conformTo(global->BooleanType())) { error(node->getCondition(), Errors::E_TYPE_DOES_NOT_CONFORM_TO_PROTOCOL_2_, conditionType->toString(), L"BooleanType"); return; } node->getCodeBlock()->accept(this); }
void SemanticAnalyzer::visitForIn(const ForInLoopPtr& node) { ScopedCodeBlockPtr codeBlock = static_pointer_cast<ScopedCodeBlock>(node->getCodeBlock()); SCOPED_SET(ctx.contextualType, nullptr); if(node->getDeclaredType()) ctx.contextualType = lookupType(node->getDeclaredType()); node->getContainer()->accept(this); TypePtr sequenceType = node->getContainer()->getType(); GlobalScope* global = symbolRegistry->getGlobalScope(); if(!sequenceType->conformTo(global->SequenceType())) { error(node->getContainer(), Errors::E_TYPE_DOES_NOT_CONFORM_TO_PROTOCOL_2_, sequenceType->toString(), L"SequenceType"); return; } }