Ejemplo n.º 1
0
/*
  GRAMMAR OF A CONSTANT DECLARATION
 
 ‌ constant-declaration → attributes opt declaration-specifiers opt let pattern-initializer-list
 ‌ pattern-initializer-list → pattern-initializer | pattern-initializer,pattern-initializer-list
 ‌ pattern-initializer → pattern initializer opt
 ‌ initializer → =expression
*/
DeclarationPtr Parser::parseLet(const std::vector<AttributePtr>& attrs, int specifiers)
{
    Token token;
    Flags flag(this, UNDER_LET);
    expect(Keyword::Let, token);
    ValueBindingsPtr ret = nodeFactory->createValueBindings(token.state);
    ret->setReadOnly(true);
    ret->setAttributes(attrs);
    ret->setSpecifiers(specifiers);
    do
    {
        PatternPtr pattern = parsePattern();
        ExpressionPtr initializer = NULL;
        if(match(L"="))
        {
            initializer = parseExpression();
        }

        ValueBindingPtr constant = nodeFactory->createValueBinding(*pattern->getSourceInfo());
        constant->setAttributes(attrs);
        constant->setSpecifiers(specifiers);
        constant->setName(pattern);
        TypedPatternPtr typedPattern = std::dynamic_pointer_cast<TypedPattern>(pattern);
        if(typedPattern)
        {
            //promote typed pattern
            constant->setDeclaredType(typedPattern->getDeclaredType());
            constant->setName(typedPattern->getPattern());
        }
        constant->setInitializer(initializer);
        ret->add(constant);
    }while(match(L","));
    return ret;
}
Ejemplo n.º 2
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();
    }
}
Ejemplo n.º 3
0
void SemanticAnalyzer::validateTupleTypeDeclaration(const PatternPtr& name, const TypePtr& declType, const TypePtr& initType)
{
    switch(name->getNodeType())
    {
        case NodeType::Identifier:
        {
            if(initType && declType && !initType->canAssignTo(declType))
            {
                error(name, Errors::E_CANNOT_CONVERT_EXPRESSION_TYPE_2, initType->toString(), declType->toString());
            }
            break;
        }
        case NodeType::TypedPattern:
        {
            TypedPatternPtr pat = static_pointer_cast<TypedPattern>(name);
            assert(pat->getDeclaredType());
            TypePtr nameType = lookupType(pat->getDeclaredType());
            assert(nameType != nullptr);
            if(declType && !Type::equals(nameType, declType))
            {
                error(name, Errors::E_TYPE_ANNOTATION_DOES_NOT_MATCH_CONTEXTUAL_TYPE_A_1, declType->toString());
                abort();
                return;
            }

            break;
        }
        case NodeType::Tuple:
        {
            TuplePtr tuple = static_pointer_cast<Tuple>(name);
            if(declType)
            {
                if((declType->getCategory() != Type::Tuple) || (tuple->numElements() != declType->numElementTypes()))
                {
                    error(name, Errors::E_TYPE_ANNOTATION_DOES_NOT_MATCH_CONTEXTUAL_TYPE_A_1, declType->toString());
                    abort();
                    return;
                }
            }
            int elements = tuple->numElements();
            for(int i = 0; i < elements; i++)
            {
                PatternPtr element = tuple->getElement(i);
                TypePtr elementDecl = declType ? declType->getElementType(i) : nullptr;
                TypePtr elementInit = initType ? initType->getElementType(i) : nullptr;
                validateTupleTypeDeclaration(element, elementDecl, elementInit);
            }
            break;
        }
        case NodeType::ValueBindingPattern:
            break;
        case NodeType::EnumCasePattern:
        {
            
            break;
        }
        case NodeType::TypeCase:
        case NodeType::TypeCheck:
        default:
            error(name, Errors::E_EXPECT_TUPLE_OR_IDENTIFIER);
            break;
    }
    
}