//while-condition -> expression declaration ExpressionPtr Parser::parseConditionExpression() { Token token; expect_next(token); if(token.type == TokenType::Identifier && token.identifier.keyword != Keyword::_) { Keyword::T keyword = token.identifier.keyword; tassert(token, keyword == Keyword::Var || keyword == Keyword::Let, Errors::E_EXPECTED_EXPRESSION_VAR_OR_LET_IN_A_CONDITION_1, L"if"); ValueBindingPatternPtr value = nodeFactory->createValueBindingPattern(token.state); value->setReadOnly(keyword == Keyword::Let); PatternPtr binding = parsePattern(); value->setBinding(binding); if(binding->getNodeType() == NodeType::TypedPattern) { TypedPatternPtr tpattern = std::static_pointer_cast<TypedPattern>(binding); value->setBinding(tpattern->getPattern()); value->setDeclaredType(tpattern->getDeclaredType()); } if (!match(L"=", token)) { tassert(token, false, Errors::E_VARIABLE_BINDING_IN_A_CONDITION_REQUIRES_AN_INITIALIZER); } AssignmentPtr assignment = nodeFactory->createAssignment(token.state); ExpressionPtr expr = parseExpression(); assignment->setLHS(value); assignment->setRHS(expr); return assignment; } else { restore(token); return parseExpression(); } }
/* GRAMMAR OF A PATTERN pattern → wildcard-pattern type-annotation opt pattern → identifier-pattern type-annotation opt pattern → value-binding-pattern pattern → tuple-pattern type-annotation opt pattern → enum-case-pattern pattern → type-casting-pattern pattern → expression-pattern */ PatternPtr Parser::parsePattern() { Token token; expect_next(token); if(token.type == TokenType::Identifier) { switch(token.identifier.keyword) { // pattern → wildcard-pattern type-annotationopt // pattern → identifier-pattern type-annotationopt case Keyword::_: { IdentifierPtr id = nodeFactory->createIdentifier(token.state); id->setIdentifier(token.token); if((flags & UNDER_CASE) == 0)//type annotation is not parsed when it's inside a let/var { if(match(L":")) { TypedPatternPtr ret = nodeFactory->createTypedPattern(*id->getSourceInfo()); TypeNodePtr type = parseTypeAnnotation(); ret->setDeclaredType(type); ret->setPattern(id); return ret; } } return id; } // pattern → value-binding-pattern case Keyword::Var: case Keyword::Let: { ValueBindingPatternPtr ret = nodeFactory->createValueBindingPattern(token.state); PatternPtr binding = parsePattern(); if(TypedPatternPtr p = std::dynamic_pointer_cast<TypedPattern>(binding)) { ret->setBinding(p->getPattern()); ret->setDeclaredType(p->getDeclaredType()); } else { ret->setBinding(binding); } ret->setReadOnly(token.identifier.keyword == Keyword::Let); return ret; } default: break; } } restore(token); if(token.type == TokenType::OpenParen) { //pattern → tuple-pattern type-annotation opt TuplePtr ret = std::static_pointer_cast<Tuple>(parseTuple()); if(flags & (UNDER_LET | UNDER_VAR)) { //type-annotation only exists under let/var statement if(match(L":")) { TypeNodePtr type = parseTypeAnnotation(); TypedPatternPtr pattern = nodeFactory->createTypedPattern(*ret->getSourceInfo()); pattern->setDeclaredType(type); pattern->setPattern(ret); return pattern; } } return ret; } if(this->flags & UNDER_SWITCH_CASE) { //the following patterns are only exists in switch/case statement // pattern → enum-case-pattern if(token.type == TokenType::Attribute || token == L".") { return parseEnumPattern(); } // pattern → type-casting-pattern if(token.getKeyword() == Keyword::Is) { return parseTypeCastingPattern(); } } // pattern → expression-pattern PatternPtr ret = parseExpression(); if(this->flags & UNDER_SWITCH_CASE) { if(predicate(L"as")) { restore(token); ret = NULL; return parseTypeCastingPattern(); } } return ret; }