Exemple #1
0
/* Impl format:
 * "impl" [<type_bounds>] <qualified_ident>[<type_bounds>] ["for" <qualified_ident>[<type_bounds>]] "{" [<body>] "}"
 */
static void parseImpl (lexerState *lexer, vString *scope, int parent_kind)
{
	unsigned long line;
	fpos_t pos;
	vString *name;

	advanceToken(lexer, TRUE);

	line = lexer->line;
	pos = lexer->pos;

	skipTypeBlock(lexer);

	name = vStringNew();

	parseQualifiedType(lexer, name);

	if (lexer->cur_token == TOKEN_IDENT && strcmp(lexer->token_str->buffer, "for") == 0)
	{
		advanceToken(lexer, TRUE);
		parseQualifiedType(lexer, name);
	}

	addTag(name, NULL, K_IMPL, line, pos, scope, parent_kind);
	addToScope(scope, name);

	parseBlock(lexer, TRUE, K_IMPL, scope);

	vStringDelete(name);
}
Exemple #2
0
static struct exp *parseRelation()
/* Parse key=wildcard. */
{
    struct kxTok *key, *match;

    if (token == NULL)
        return NULL;
    if (token->type != kxtString)
        errAbort("Expecting key got %s", token->string);
    key = token;
    advanceToken();
    if (token->type == kxtEquals)
    {
        advanceToken();
        if (token->type == kxtString || token->type == kxtWildString)
        {
            struct exp *exp;
            match = token;
            advanceToken();
            AllocVar(exp);
            exp->left = key->string;
            exp->right = match->string;
            exp->type = (match->type == kxtString ? kxMatch : kxWildMatch);
            return exp;
        }
        else
        {
            errAbort("Expecting string to match in key=match expression,\ngot %s", token->string);
        }
    }
    else if (token->type == kxtGT || token->type == kxtGE || token->type == kxtLT || token->type == kxtLE)
    {
        enum kxTokType relation = token->type;
        advanceToken();
        if (isdigit(token->string[0]))
        {
            struct exp *exp;
            match = token;
            advanceToken();
            AllocVar(exp);
            exp->left = key->string;
            exp->right = match->string;
            if (relation == kxtGT) exp->type = kxGT;
            else if (relation == kxtGE) exp->type = kxGE;
            else if (relation == kxtLT) exp->type = kxLT;
            else if (relation == kxtLE) exp->type = kxLE;
            return exp;
        }
        else
        {
            errAbort("Expecting number got %s", token->string);
        }
    }
    else
        errAbort("Expecting = got %s", token->string);
    return NULL;
}
Exemple #3
0
/* Mod format:
 * "mod" <ident> "{" [<body>] "}"
 * "mod" <ident> ";"*/
static void parseMod (lexerState *lexer, vString *scope, int parent_kind)
{
	advanceToken(lexer, TRUE);
	if (lexer->cur_token != TOKEN_IDENT)
		return;

	addTag(lexer->token_str, NULL, K_MOD, lexer->line, lexer->pos, scope, parent_kind);
	addToScope(scope, lexer->token_str);

	advanceToken(lexer, TRUE);

	parseBlock(lexer, TRUE, K_MOD, scope);
}
Exemple #4
0
/* Static format:
 * "static" ["mut"] <ident>
 */
static void parseStatic (lexerState *lexer, vString *scope, int parent_kind)
{
	advanceToken(lexer, TRUE);
	if (lexer->cur_token != TOKEN_IDENT)
		return;
	if (strcmp(lexer->token_str->buffer, "mut") == 0)
	{
		advanceToken(lexer, TRUE);
	}
	if (lexer->cur_token != TOKEN_IDENT)
		return;

	addTag(lexer->token_str, NULL, K_STATIC, lexer->line, lexer->pos, scope, parent_kind);
}
Exemple #5
0
static struct exp *parseOrExp()
/* Parse lowest level of precedent expressions - or and xor. */
{
    struct exp *left;
    struct exp *right, *exp;
    struct kxTok *tok;
    enum kxTokType type;

    if ((left = parseAndExp()) == NULL)
        return NULL;
    if ((tok = token) == NULL)
        return left;
    type = token->type;
    if (type == kxtOr || type == kxtXor)
    {
        advanceToken();
        right = nextExp();
        if (right == NULL)
            errAbort("Expecting expression on the other side of %s", tok->string);
        AllocVar(exp);
        exp->left = left;
        exp->right = right;
        if (type == kxtOr)
            exp->type = kxOr;
        else
            exp->type = kxXor;
        return exp;
    }
    else
        return left;
}
Exemple #6
0
static struct exp *parseAndExp()
/* Parse and level expressions. */
{
    struct exp *left;
    struct exp *right, *exp;
    struct kxTok *tok;
    enum kxTokType type;

    if ((left = parseNot()) == NULL)
        return NULL;
    if ((tok = token) == NULL)
        return left;
    type = token->type;
    if (type == kxtAnd)
    {
        advanceToken();
        right = nextExp();
        if (right == NULL)
            errAbort("Expecting expression on the other side of %s", tok->string);
        AllocVar(exp);
        exp->left = left;
        exp->right = right;
        exp->type = kxAnd;
        return exp;
    }
    else
        return left;
}
Exemple #7
0
bool Tokenizer::setCurrentPos(U32 pos)
{
   mCurrPos    = pos;
   mTokenIsCurrent = false;

   return advanceToken(true);
}
Exemple #8
0
/*
 * Macro rules format:
 * "macro_rules" "!" <ident> <macro_body>
 */
static void parseMacroRules (lexerState *lexer, vString *scope, int parent_kind)
{
	advanceToken(lexer, TRUE);

	if (lexer->cur_token != '!')
		return;

	advanceToken(lexer, TRUE);

	if (lexer->cur_token != TOKEN_IDENT)
		return;

	addTag(lexer->token_str, NULL, K_MACRO, lexer->line, lexer->pos, scope, parent_kind);

	skipMacro(lexer);
}
Exemple #9
0
// operator
//      : PLUS | DASH | STAR | SLASH | ...
bool HlslGrammar::acceptOperator(TOperator& op)
{
    switch (token.tokenClass) {
    case EHTokEqual:
        op = EOpAssign;
        break;
    case EHTokPlus:
        op = EOpAdd;
        break;
    case EHTokDash:
        op = EOpSub;
        break;
    case EHTokStar:
        op = EOpMul;
        break;
    case EHTokSlash:
        op = EOpDiv;
        break;
    default:
        return false;
    }

    advanceToken();

    return true;
}
Exemple #10
0
// Accept an assignment expression, where assignment operations
// associate right-to-left.  This is, it is implicit, for example
//
//    a op (b op (c op d))
//
// assigment_expression
//      : binary_expression op binary_expression op binary_expression ...
//
bool HlslGrammar::acceptAssignmentExpression(TIntermTyped*& node)
{
    if (! acceptBinaryExpression(node, PlLogicalOr))
        return false;

    TOperator assignOp = HlslOpMap::assignment(peek());
    if (assignOp == EOpNull)
        return true;

    // ... op
    TSourceLoc loc = token.loc;
    advanceToken();

    // ... binary_expression
    // But, done by recursing this function, which automatically
    // gets the right-to-left associativity.
    TIntermTyped* rightNode = nullptr;
    if (! acceptAssignmentExpression(rightNode)) {
        expected("assignment expression");
        return false;
    }

    node = intermediate.addAssign(assignOp, node, rightNode, loc);

    if (! peekTokenClass(EHTokComma))
        return true;

    return true;
}
Exemple #11
0
// Accept a binary expression, for binary operations that
// associate left-to-right.  This is, it is implicit, for example
//
//    ((a op b) op c) op d
//
// binary_expression
//      : expression op expression op expression ...
//
// where 'expression' is the next higher level in precedence.
//
bool HlslGrammar::acceptBinaryExpression(TIntermTyped*& node, PrecedenceLevel precedenceLevel)
{
    if (precedenceLevel > PlMul)
        return acceptUnaryExpression(node);

    // assignment_expression
    if (! acceptBinaryExpression(node, (PrecedenceLevel)(precedenceLevel + 1)))
        return false;

    TOperator op = HlslOpMap::binary(peek());
    PrecedenceLevel tokenLevel = HlslOpMap::precedenceLevel(op);
    if (tokenLevel < precedenceLevel)
        return true;

    do {
        // ... op
        TSourceLoc loc = token.loc;
        advanceToken();

        // ... expression
        TIntermTyped* rightNode = nullptr;
        if (! acceptBinaryExpression(rightNode, (PrecedenceLevel)(precedenceLevel + 1))) {
            expected("expression");
            return false;
        }

        node = intermediate.addBinaryMath(op, node, rightNode, loc);

        if (! peekTokenClass(EHTokComma))
            return true;
    } while (true);
}
Exemple #12
0
// The top-level full expression recognizer.
//
// expression
//      : assignment_expression COMMA assignment_expression COMMA assignment_expression ...
//
bool HlslGrammar::acceptExpression(TIntermTyped*& node)
{
    // assignment_expression
    if (! acceptAssignmentExpression(node))
        return false;

    if (! peekTokenClass(EHTokComma))
        return true;

    do {
        // ... COMMA
        TSourceLoc loc = token.loc;
        advanceToken();

        // ... assignment_expression
        TIntermTyped* rightNode = nullptr;
        if (! acceptAssignmentExpression(rightNode)) {
            expected("assignment expression");
            return false;
        }

        node = intermediate.addComma(node, rightNode, loc);

        if (! peekTokenClass(EHTokComma))
            return true;
    } while (true);
}
Exemple #13
0
/* Type format:
 * "type" <ident>
 */
static void parseType (lexerState *lexer, vString *scope, int parent_kind)
{
	advanceToken(lexer, TRUE);
	if (lexer->cur_token != TOKEN_IDENT)
		return;

	addTag(lexer->token_str, NULL, K_TYPE, lexer->line, lexer->pos, scope, parent_kind);
}
Exemple #14
0
/* Skips type blocks of the form <T:T<T>, ...> */
static void skipTypeBlock (lexerState *lexer)
{
	if (lexer->cur_token == '<')
	{
		skipUntil(lexer, NULL, 0);
		advanceToken(lexer, TRUE);
	}
}
Exemple #15
0
/* Trait format:
 * "trait" <ident> [<type_bounds>] "{" [<body>] "}"
 */
static void parseTrait (lexerState *lexer, vString *scope, int parent_kind)
{
	int goal_tokens[] = {'{'};

	advanceToken(lexer, TRUE);
	if (lexer->cur_token != TOKEN_IDENT)
		return;

	addTag(lexer->token_str, NULL, K_TRAIT, lexer->line, lexer->pos, scope, parent_kind);
	addToScope(scope, lexer->token_str);

	advanceToken(lexer, TRUE);

	skipUntil(lexer, goal_tokens, 1);

	parseBlock(lexer, TRUE, K_TRAIT, scope);
}
Exemple #16
0
static void initLexer (lexerState *lexer)
{
	advanceNChar(lexer, 2);
	lexer->token_str = vStringNew();

	if (lexer->cur_c == '#' && lexer->next_c == '!')
		scanComments(lexer);
	advanceToken(lexer, TRUE);
}
Exemple #17
0
// Return true and advance to the next token if the current token is the
// expected (passed in) token class.
bool HlslGrammar::acceptTokenClass(EHlslTokenClass tokenClass)
{
    if (token.tokenClass == tokenClass) {
        advanceToken();
        return true;
    }

    return false;
}
Exemple #18
0
// Only process the next token if it is an identifier.
// Return true if it was an identifier.
bool HlslGrammar::acceptIdentifier(HlslToken& idToken)
{
    if (peekTokenClass(EHTokIdentifier)) {
        idToken = token;
        advanceToken();
        return true;
    }

    return false;
}
Exemple #19
0
static struct exp *parseParenthesized()
/* Parse parenthesized expressions. */
{
    struct exp *exp;
    if (token == NULL)
        return NULL;
    if (token->type == kxtOpenParen)
    {
        advanceToken();
        exp = nextExp();
        if (token->type != kxtCloseParen)
            errAbort("Unmatched parenthesis");
        advanceToken();
        return exp;
    }
    else
    {
        return parseRelation();
    }
}
Exemple #20
0
struct expression *parse()
{
    init();
    advanceToken();
    struct expression *prop = parse_prop();

    if (is_empty_expression(prop) || current_token == NULL
            || current_token->type != End) {
        return NULL;
    }
    return prop;
}
Exemple #21
0
/* Skip the body of the macro. Can't use skipUntil here as
 * the body of the macro may have arbitrary code which confuses it (e.g.
 * bitshift operators/function return arrows) */
static void skipMacro (lexerState *lexer)
{
	int level = 0;
	int plus_token = 0;
	int minus_token = 0;

	advanceToken(lexer, TRUE);
	switch (lexer->cur_token)
	{
		case '(':
			plus_token = '(';
			minus_token = ')';
			break;
		case '{':
			plus_token = '{';
			minus_token = '}';
			break;
		case '[':
			plus_token = '[';
			minus_token = ']';
			break;
		default:
			return;
	}

	while (lexer->cur_token != TOKEN_EOF)
	{
		if (lexer->cur_token == plus_token)
			level++;
		else if (lexer->cur_token == minus_token)
			level--;
		if (level == 0)
			break;
		advanceToken(lexer, TRUE);
	}
	advanceToken(lexer, TRUE);
}
Exemple #22
0
struct expression *parse_term()
{
    struct expression *term;

    if (current_token == NULL) return NULL;

    switch (current_token->type) {
    case Var:
        term = new_var_expression(current_token->u.var_id);
        advanceToken();
        return term;
    case LeftParen:
        advanceToken();
        term = parse_prop();
        if (is_empty_expression(term)) {
            return NULL;
        }
        switch (current_token->type) {
        case RightParen:
            advanceToken();
            return term;
        default:
            return NULL;
        }
    case OpNot:
        advanceToken();
        term = new_op_expression(NotExp, parse_term(), NULL);
        if (is_left_child_empty(term)) {
            destroy_expression(term);
            return NULL;
        }
        return term;
    default:
        return NULL;
    }
}
Exemple #23
0
// If token is a qualifier, return its token class and advance to the next
// qualifier.  Otherwise, return false, and don't advance.
void HlslGrammar::acceptQualifier(TQualifier& qualifier)
{
    switch (token.tokenClass) {
    case EHTokUniform:
        qualifier.storage = EvqUniform;
        break;
    case EHTokConst:
        qualifier.storage = EvqConst;
        break;
    default:
        return;
    }

    advanceToken();
}
Exemple #24
0
bool Tokenizer::findToken(U32 start, const char* pCmp)
{
   // Move to the start
   setCurrentPos(start);

   // In case the first token is what we are looking for
   if (tokenICmp(pCmp))
      return true;

   // Loop through the file and see if the token exists
   while (advanceToken(true))
   {
      if (tokenICmp(pCmp))
         return true;
   }

   return false;
}
Exemple #25
0
/* Essentially grabs the last ident before 'for', '<' and '{', which
 * tends to correspond to what we want as the impl tag entry name */
static void parseQualifiedType (lexerState *lexer, vString* name)
{
	while (lexer->cur_token != TOKEN_EOF)
	{
		if (lexer->cur_token == TOKEN_IDENT)
		{
			if (strcmp(lexer->token_str->buffer, "for") == 0)
				break;
			vStringClear(name);
			vStringCat(name, lexer->token_str);
		}
		else if (lexer->cur_token == '<' || lexer->cur_token == '{')
		{
			break;
		}
		advanceToken(lexer, TRUE);
	}
	skipTypeBlock(lexer);
}
Exemple #26
0
static struct exp *parseNot()
/* Parse not */
{
    struct exp *exp;
    struct exp *right;

    if (token == NULL)
        return NULL;
    if (token->type == kxtNot)
    {
        advanceToken();
        right = nextExp();
        AllocVar(exp);
        exp->right = right;
        exp->type = kxNot;
        return exp;
    }
    else
        return parseParenthesized();
}
Exemple #27
0
struct expression *parse_prop()
{
    struct expression *exp = parse_exp();

    if (is_empty_expression(exp) || current_token == NULL)
        return NULL;

    switch (current_token->type) {
    case OpOr:
        advanceToken();
        struct expression *prop =
            new_op_expression(OrExp, exp, parse_prop());
        if (is_right_child_empty(prop)) {
            destroy_expression(exp);
            return NULL;
        }
        return prop;
    default:
        return exp;
    }
}
Exemple #28
0
struct expression *parse_exp()
{
    struct expression *term = parse_term();
    if (is_empty_expression(term))
        return NULL;

    if (current_token == NULL) return NULL;

    switch (current_token->type) {
    case OpAnd:
        advanceToken();
        struct expression *exp =
            new_op_expression(AndExp, term, parse_exp());
        if (is_right_child_empty(exp)) {
            destroy_expression(exp);
            return NULL;
        }
        return exp;
    default:
        return term;
    }
}
Exemple #29
0
// unary_expression
//      : + unary_expression
//      | - unary_expression
//      | ! unary_expression
//      | ~ unary_expression
//      | ++ unary_expression
//      | -- unary_expression
//      | postfix_expression
//
bool HlslGrammar::acceptUnaryExpression(TIntermTyped*& node)
{
    TOperator unaryOp = HlslOpMap::preUnary(peek());
    
    // postfix_expression
    if (unaryOp == EOpNull)
        return acceptPostfixExpression(node);

    // op unary_expression
    TSourceLoc loc = token.loc;
    advanceToken();
    if (! acceptUnaryExpression(node))
        return false;

    // + is a no-op
    if (unaryOp == EOpAdd)
        return true;

    node = intermediate.addUnaryMath(unaryOp, node, loc);

    return node != nullptr;
}
Exemple #30
0
bool HlslGrammar::acceptLiteral(TIntermTyped*& node)
{
    switch (token.tokenClass) {
    case EHTokIntConstant:
        node = intermediate.addConstantUnion(token.i, token.loc, true);
        break;
    case EHTokFloatConstant:
        node = intermediate.addConstantUnion(token.d, EbtFloat, token.loc, true);
        break;
    case EHTokDoubleConstant:
        node = intermediate.addConstantUnion(token.d, EbtDouble, token.loc, true);
        break;
    case EHTokBoolConstant:
        node = intermediate.addConstantUnion(token.b, token.loc, true);
        break;

    default:
        return false;
    }

    advanceToken();

    return true;
}