Beispiel #1
0
TEST(TestDeclaration, testLet)
{
    PARSE_STATEMENT(L"let a : Int[] = [1, 2, 3]");
    ValueBindingsPtr c;
    IdentifierPtr id;
    ValueBindingPtr a;
    ArrayLiteralPtr value;
    ArrayTypePtr type;
    TypeIdentifierPtr Int;
    ASSERT_NOT_NULL(c = std::dynamic_pointer_cast<ValueBindings>(root));
    ASSERT_TRUE(c->isReadOnly());
    ASSERT_EQ(1, c->numBindings());
    ASSERT_NOT_NULL(a = c->get(0));
    ASSERT_NOT_NULL(id = std::dynamic_pointer_cast<Identifier>(a->getName()));
    ASSERT_EQ(L"a", id->getIdentifier());
    ASSERT_NOT_NULL(type = std::dynamic_pointer_cast<ArrayType>(a->getDeclaredType()));
    ASSERT_NOT_NULL(Int = std::dynamic_pointer_cast<TypeIdentifier>(type->getInnerType()));
    ASSERT_EQ(L"Int", Int->getName());

    ASSERT_NOT_NULL(value = std::dynamic_pointer_cast<ArrayLiteral>(c->get(0)->getInitializer()));
    ASSERT_EQ(3, value->numElements());
    ASSERT_EQ(L"1", std::dynamic_pointer_cast<IntegerLiteral>(value->getElement(0))->valueAsString);
    ASSERT_EQ(L"2", std::dynamic_pointer_cast<IntegerLiteral>(value->getElement(1))->valueAsString);
    ASSERT_EQ(L"3", std::dynamic_pointer_cast<IntegerLiteral>(value->getElement(2))->valueAsString);

}
/*
  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;
}
Beispiel #3
0
TEST(TestDeclaration, testLet_Tuple)
{
    PARSE_STATEMENT(L"let (a, b) : Int = (1, 2)");
    ValueBindingsPtr c;
    TuplePtr tuple;
    TypeIdentifierPtr type;
    ParenthesizedExpressionPtr p;
    ASSERT_NOT_NULL(c = std::dynamic_pointer_cast<ValueBindings>(root));
    ASSERT_TRUE(c->isReadOnly());
    ASSERT_NOT_NULL(tuple = std::dynamic_pointer_cast<Tuple>(c->get(0)->getName()));
    ASSERT_EQ(2, tuple->numElements());
    ASSERT_NOT_NULL(type = std::dynamic_pointer_cast<TypeIdentifier>(c->get(0)->getDeclaredType()));
    ASSERT_NOT_NULL(p = std::dynamic_pointer_cast<ParenthesizedExpression>(c->get(0)->getInitializer()));
    ASSERT_EQ(2, p->numExpressions());

}
Beispiel #4
0
TEST(TestDeclaration, testVar_Typed)
{
    PARSE_STATEMENT(L"var welcomeMessage: String");
    ValueBindingsPtr vars;
    ValueBindingPtr var;
    IdentifierPtr id;
    TypeIdentifierPtr t;

    ASSERT_NOT_NULL(vars = std::dynamic_pointer_cast<ValueBindings>(root));
    ASSERT_TRUE(!vars->isReadOnly());
    ASSERT_EQ(1, vars->numBindings());
    ASSERT_NOT_NULL(var = std::dynamic_pointer_cast<ValueBinding>(vars->get(0)));
    ASSERT_NOT_NULL(id = std::dynamic_pointer_cast<Identifier>(var->getName()));
    ASSERT_EQ(L"welcomeMessage", id->getIdentifier());

    ASSERT_NOT_NULL(t = std::dynamic_pointer_cast<TypeIdentifier>(var->getDeclaredType()));
    ASSERT_EQ(L"String", t->getName());


}
Beispiel #5
0
TEST(TestDeclaration, testVar)
{
    PARSE_STATEMENT(L"var currentLoginAttempt = 0");
    ValueBindingsPtr vars;
    ValueBindingPtr var;
    IdentifierPtr id;
    IntegerLiteralPtr i;

    ASSERT_NOT_NULL(vars = std::dynamic_pointer_cast<ValueBindings>(root));
    ASSERT_TRUE(!vars->isReadOnly());
    ASSERT_EQ(1, vars->numBindings());
    ASSERT_NOT_NULL(var = std::dynamic_pointer_cast<ValueBinding>(vars->get(0)));
    ASSERT_NOT_NULL(id = std::dynamic_pointer_cast<Identifier>(var->getName()));
    ASSERT_EQ(L"currentLoginAttempt", id->getIdentifier());

    ASSERT_NOT_NULL(i = std::dynamic_pointer_cast<IntegerLiteral>(var->getInitializer()));
    ASSERT_EQ(L"0", i->valueAsString);


}
Beispiel #6
0
TEST(TestDeclaration, testVar_Multiple)
{
    PARSE_STATEMENT(L"var x = 0.0, y = 0.0, z = 0.0");
    ValueBindingsPtr vars;
    ValueBindingPtr var;
    IdentifierPtr id;
    FloatLiteralPtr f;

    ASSERT_NOT_NULL(vars = std::dynamic_pointer_cast<ValueBindings>(root));
    ASSERT_TRUE(!vars->isReadOnly());
    ASSERT_EQ(3, vars->numBindings());

    ASSERT_NOT_NULL(var = std::dynamic_pointer_cast<ValueBinding>(vars->get(0)));
    ASSERT_NOT_NULL(id = std::dynamic_pointer_cast<Identifier>(var->getName()));
    ASSERT_EQ(L"x", id->getIdentifier());
    ASSERT_NOT_NULL(f = std::dynamic_pointer_cast<FloatLiteral>(var->getInitializer()));
    ASSERT_EQ(L"0.0", f->valueAsString);


    ASSERT_NOT_NULL(var = std::dynamic_pointer_cast<ValueBinding>(vars->get(1)));
    ASSERT_NOT_NULL(id = std::dynamic_pointer_cast<Identifier>(var->getName()));
    ASSERT_EQ(L"y", id->getIdentifier());
    ASSERT_NOT_NULL(f = std::dynamic_pointer_cast<FloatLiteral>(var->getInitializer()));
    ASSERT_EQ(L"0.0", f->valueAsString);


    ASSERT_NOT_NULL(var = std::dynamic_pointer_cast<ValueBinding>(vars->get(2)));
    ASSERT_NOT_NULL(id = std::dynamic_pointer_cast<Identifier>(var->getName()));
    ASSERT_EQ(L"z", id->getIdentifier());
    ASSERT_NOT_NULL(f = std::dynamic_pointer_cast<FloatLiteral>(var->getInitializer()));
    ASSERT_EQ(L"0.0", f->valueAsString);


}
Beispiel #7
0
TEST(TestDeclaration, testLet_Multiple)
{
    PARSE_STATEMENT(L"let a=[k1 : 1, k2 : 2], b : Int = 2");
    ValueBindingsPtr c;
    ValueBindingPtr b;
    IdentifierPtr id;
    TypeIdentifierPtr Int;
    DictionaryLiteralPtr dict;
    ASSERT_NOT_NULL(c = std::dynamic_pointer_cast<ValueBindings>(root));
    ASSERT_TRUE(c->isReadOnly());
    ASSERT_EQ(2, c->numBindings());
    ASSERT_NOT_NULL(id = std::dynamic_pointer_cast<Identifier>(c->get(0)->getName()));
    ASSERT_EQ(L"a", id->getIdentifier());
    ASSERT_NOT_NULL(dict = std::dynamic_pointer_cast<DictionaryLiteral>(c->get(0)->getInitializer()));
    ASSERT_EQ(2, dict->numElements());

    ASSERT_NOT_NULL(b = c->get(1));
    ASSERT_NOT_NULL(id = std::dynamic_pointer_cast<Identifier>(b->getName()));
    ASSERT_EQ(L"b", id->getIdentifier());
    ASSERT_NOT_NULL(Int = std::dynamic_pointer_cast<TypeIdentifier>(b->getDeclaredType()));
    ASSERT_EQ(L"Int", Int->getName());

}
/*
  GRAMMAR OF A VARIABLE DECLARATION
 
 ‌ variable-declaration → variable-declaration-head pattern-initializer-list
 ‌ variable-declaration → variable-declaration-head variable-name type-annotation code-block
 ‌ variable-declaration → variable-declaration-head variable-name type-annotation getter-setter-block
  variable-declaration → variable-declaration-head variable-name type-annotation getter-setter-keyword-block
 ‌ variable-declaration → variable-declaration-head variable-name type-annotation initializer opt willSet-didSet-block
 ‌ variable-declaration-head → attributes opt declaration-specifiers opt var
 ‌ variable-name → identifier
*/
DeclarationPtr Parser::parseVar(const std::vector<AttributePtr>& attrs, int specifiers)
{

    Token token;
    expect(Keyword::Var, token);
    Flags flags(this, UNDER_VAR);
    //try read it as pattern-initializer-list
    ValueBindingsPtr ret = nodeFactory->createValueBindings(token.state);
    ret->setReadOnly(false);
    ret->setAttributes(attrs);
    ret->setSpecifiers(specifiers);
    ValueBindingPtr var = parseVariableDeclaration();
    var->setSpecifiers(specifiers);
    ret->add(var);
    if(predicate(L","))
    {
        while(match(L","))
        {
            var = parseVariableDeclaration();
            var->setSpecifiers(specifiers);
            ret->add(var);
        }
        return ret;
    }

    if(!match(L"{"))
        return ret;
    peek(token);
    IdentifierPtr name = std::dynamic_pointer_cast<Identifier>(var->getName());
    tassert(token, name != nullptr, Errors::E_GETTER_SETTER_CAN_ONLY_BE_DEFINED_FOR_A_SINGLE_VARIABLE, L"");


    ComputedPropertyPtr prop = nodeFactory->createComputedProperty(*var->getSourceInfo());
    prop->setAttributes(attrs);
    prop->setSpecifiers(specifiers);
    prop->setTypeAttributes(var->getTypeAttributes());
    prop->setName(name->getIdentifier());
    prop->setDeclaredType(var->getDeclaredType());
    prop->setInitializer(var->getInitializer());
    var = nullptr;
    ret = nullptr;

    if(token.type != TokenType::CloseBrace)
    {
        Flags flags(this, SUPPRESS_TRAILING_CLOSURE);
        switch(token.getKeyword())
        {
            case Keyword::Get:
            case Keyword::Set:
                if(this->flags & UNDER_PROTOCOL)
                {
                    // variable-declaration → variable-declaration-head variable-name type-annotation getter-setter-keyword-block
                    //no code block for getter/setter for protocol
                    std::pair<CodeBlockPtr, CodeBlockPtr> r = parseGetterSetterKeywordBlock();
                    prop->setGetter(r.first);
                    prop->setSetter(r.second);
                }
                else
                {
                    //  variable-declaration → variable-declaration-head variable-name type-annotation getter-setter-block
                    std::pair<CodeBlockPtr, std::pair<std::wstring, CodeBlockPtr> > r = parseGetterSetterBlock();
                    prop->setGetter(r.first);
                    prop->setSetterName(r.second.first);
                    prop->setSetter(r.second.second);
                }
                break;
            case Keyword::WillSet:
            case Keyword::DidSet:
                //  variable-declaration → variable-declaration-head variable-name type-annotation initializer opt willSet-didSet-block
                parseWillSetDidSetBlock(prop);
                break;
            default:
                //‌ variable-declaration → variable-declaration-head variable-name type-annotation code-block
                CodeBlockPtr getter = nodeFactory->createCodeBlock(token.state);
                prop->setGetter(getter);
                do
                {
                    StatementPtr st = parseStatement();
                    getter->addStatement(st);
                }while(!predicate(L"}"));
                break;
        }
        
    }
    expect(L"}");
    return prop;
}
Beispiel #9
0
void NodeSerializer::visitValueBindings(const ValueBindingsPtr &node)
{
    append(node->isReadOnly() ? L"let " : L"var ");
    NodeVisitor::visitValueBindings(node);
}