Example #1
0
//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();
    }
}
Example #2
0
/*
  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;
}