Changeset 20ac1a4 in mainline for uspace/app/bithenge/script.c


Ignore:
Timestamp:
2012-07-30T02:07:10Z (12 years ago)
Author:
Sean Bartell <wingedtachikoma@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
78d3a00
Parents:
10334c2e
Message:

Bithenge: add syntactic sugar for if in struct

File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/app/bithenge/script.c

    r10334c2e r20ac1a4  
    342342
    343343static bithenge_transform_t *parse_transform(state_t *state);
     344static bithenge_transform_t *parse_struct(state_t *state);
    344345
    345346static bithenge_expression_t *parse_expression(state_t *state)
     
    490491}
    491492
    492 static bithenge_transform_t *parse_if(state_t *state)
     493static bithenge_transform_t *parse_if(state_t *state, bool in_struct)
    493494{
    494495        expect(state, TOKEN_IF);
     
    497498        expect(state, ')');
    498499        expect(state, '{');
    499         bithenge_transform_t *true_xform = parse_transform(state);
     500        bithenge_transform_t *true_xform =
     501            in_struct ? parse_struct(state) : parse_transform(state);
    500502        expect(state, '}');
    501         expect(state, TOKEN_ELSE);
    502         expect(state, '{');
    503         bithenge_transform_t *false_xform = parse_transform(state);
    504         expect(state, '}');
     503        bithenge_transform_t *false_xform = NULL;
     504        if (state->token == TOKEN_ELSE) {
     505                next_token(state);
     506                expect(state, '{');
     507                false_xform =
     508                    in_struct ? parse_struct(state) : parse_transform(state);
     509                expect(state, '}');
     510        } else {
     511                if (in_struct) {
     512                        bithenge_node_t *node;
     513                        int rc = bithenge_new_empty_internal_node(&node);
     514                        if (rc != EOK) {
     515                                error_errno(state, rc);
     516                                goto error;
     517                        }
     518                        bithenge_expression_t *expr;
     519                        rc = bithenge_const_expression(&expr, node);
     520                        if (rc != EOK) {
     521                                error_errno(state, rc);
     522                                goto error;
     523                        }
     524                        rc = bithenge_expression_transform(&false_xform, expr);
     525                        if (rc != EOK) {
     526                                error_errno(state, rc);
     527                                false_xform = NULL;
     528                                goto error;
     529                        }
     530                } else
     531                        syntax_error(state, "else expected");
     532        }
    505533        if (state->error != EOK) {
     534error:
    506535                bithenge_expression_dec_ref(expr);
    507536                bithenge_transform_dec_ref(true_xform);
     
    519548}
    520549
     550/* The TOKEN_STRUCT and '{' must already have been skipped. */
    521551static bithenge_transform_t *parse_struct(state_t *state)
    522552{
     
    525555        /* We keep an extra space for the {NULL, NULL} terminator. */
    526556        subxforms = state_malloc(state, sizeof(*subxforms));
    527         expect(state, TOKEN_STRUCT);
    528         expect(state, '{');
    529557        while (state->error == EOK && state->token != '}') {
    530                 if (state->token == '.') {
    531                         expect(state, '.');
    532                         subxforms[num].name = expect_identifier(state);
     558                if (state->token == TOKEN_IF) {
     559                        subxforms[num].transform = parse_if(state, true);
     560                        subxforms[num].name = NULL;
     561                } else {
     562                        if (state->token == '.') {
     563                                next_token(state);
     564                                subxforms[num].name = expect_identifier(state);
     565                        } else {
     566                                subxforms[num].name = NULL;
     567                        }
    533568                        expect(state, TOKEN_LEFT_ARROW);
    534                 } else {
    535                         subxforms[num].name = NULL;
    536                         expect(state, TOKEN_LEFT_ARROW);
    537                 }
    538                 subxforms[num].transform = parse_transform(state);
    539                 expect(state, ';');
     569                        subxforms[num].transform = parse_transform(state);
     570                        expect(state, ';');
     571                }
    540572                num++;
    541573                subxforms = state_realloc(state, subxforms,
    542574                    (num + 1)*sizeof(*subxforms));
    543575        }
    544         expect(state, '}');
    545576
    546577        if (state->error != EOK) {
     
    571602                return parse_invocation(state);
    572603        } else if (state->token == TOKEN_IF) {
    573                 return parse_if(state);
     604                return parse_if(state, false);
    574605        } else if (state->token == TOKEN_STRUCT) {
    575                 return parse_struct(state);
     606                next_token(state);
     607                expect(state, '{');
     608                bithenge_transform_t *xform = parse_struct(state);
     609                expect(state, '}');
     610                return xform;
    576611        } else {
    577612                syntax_error(state, "unexpected (transform expected)");
Note: See TracChangeset for help on using the changeset viewer.