BNF:11: EXPRVALUE ::= 'void' | CONSTRUCTCALL | FUNCCALL | VARACCESS | CAST | LITERAL | '(' ASSIGN ')' | LAMBDA
| 1619 | |
| 1620 | // BNF:11: EXPRVALUE ::= 'void' | CONSTRUCTCALL | FUNCCALL | VARACCESS | CAST | LITERAL | '(' ASSIGN ')' | LAMBDA |
| 1621 | asCScriptNode *asCParser::ParseExprValue() |
| 1622 | { |
| 1623 | asCScriptNode *node = CreateNode(snExprValue); |
| 1624 | if( node == 0 ) return 0; |
| 1625 | |
| 1626 | sToken t1, t2; |
| 1627 | GetToken(&t1); |
| 1628 | GetToken(&t2); |
| 1629 | RewindTo(&t1); |
| 1630 | |
| 1631 | // 'void' is a special expression that doesn't do anything (normally used for skipping output arguments) |
| 1632 | if( t1.type == ttVoid ) |
| 1633 | node->AddChildLast(ParseToken(ttVoid)); |
| 1634 | else if( IsRealType(t1.type) ) |
| 1635 | node->AddChildLast(ParseConstructCall()); |
| 1636 | else if( t1.type == ttIdentifier || t1.type == ttScope ) |
| 1637 | { |
| 1638 | // Check if the expression is an anonymous function |
| 1639 | if( IsLambda() ) |
| 1640 | { |
| 1641 | node->AddChildLast(ParseLambda()); |
| 1642 | } |
| 1643 | else |
| 1644 | { |
| 1645 | // Determine the last identifier in order to check if it is a type |
| 1646 | FindIdentifierAfterScope(t2); |
| 1647 | RewindTo(&t2); |
| 1648 | |
| 1649 | // Get The token after the identifier to determine if it is an [ |
| 1650 | sToken t; |
| 1651 | GetToken(&t); |
| 1652 | GetToken(&t); |
| 1653 | |
| 1654 | bool isDataType = IsDataType(t2); |
| 1655 | bool isTemplateType = false; |
| 1656 | bool isTemplateFn = false; |
| 1657 | if( isDataType ) |
| 1658 | { |
| 1659 | // Is this a template type? |
| 1660 | tempString.Assign(&script->code[t2.pos], t2.length); |
| 1661 | if( engine->IsTemplateType(tempString.AddressOf()) ) |
| 1662 | isTemplateType = true; |
| 1663 | } |
| 1664 | else |
| 1665 | { |
| 1666 | tempString.Assign(&script->code[t2.pos], t2.length); |
| 1667 | if( engine->IsTemplateFn(tempString.AddressOf()) ) |
| 1668 | isTemplateFn = true; |
| 1669 | } |
| 1670 | GetToken(&t2); |
| 1671 | |
| 1672 | // Rewind so the real parsing can be done, after deciding what to parse |
| 1673 | RewindTo(&t1); |
| 1674 | |
| 1675 | // Check if this is a construct call |
| 1676 | // Just 'type()' isn't considered a construct call, because type may just be a function/method name. |
| 1677 | // The compiler will have to sort this out, since the parser doesn't have enough information. |
| 1678 | if( isDataType && (t.type == ttOpenBracket && t2.type == ttCloseBracket) ) // type[]() |
nothing calls this directly
no test coverage detected