Changeset 4056ad0 in mainline for uspace/app/bithenge/script.c


Ignore:
Timestamp:
2012-07-28T01:57:31Z (12 years ago)
Author:
Sean Bartell <wingedtachikoma@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
32eb01b
Parents:
03cad47
Message:

Bithenge: basic parameter passing (integer literals only)

File:
1 edited

Legend:

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

    r03cad47 r4056ad0  
    3838#include <stdio.h>
    3939#include <stdlib.h>
     40#include "expression.h"
    4041#include "os.h"
    4142#include "script.h"
     
    5354        TOKEN_EOF,
    5455        TOKEN_IDENTIFIER,
     56        TOKEN_INTEGER,
    5557        TOKEN_LEFT_ARROW,
    5658
     
    9597                 * NULL, it will be freed when the next token is read. */
    9698                char *token_string;
     99                /** The value of a TOKEN_INTEGER token. */
     100                bithenge_int_t token_int;
    97101        };
    98102} state_t;
     
    202206                        state->token_string = value;
    203207                }
     208        } else if (isdigit(ch)) {
     209                while (isdigit(state->buffer[state->buffer_pos]))
     210                        state->buffer_pos++;
     211                state->token = TOKEN_INTEGER;
     212                int rc = bithenge_parse_int(state->buffer +
     213                    state->old_buffer_pos, &state->token_int);
     214                if (rc != EOK)
     215                        error_errno(state, rc);
    204216        } else if (ch == '<') {
    205217                state->token = ch;
     
    307319
    308320static bithenge_transform_t *parse_transform(state_t *state);
     321
     322static bithenge_expression_t *parse_expression(state_t *state)
     323{
     324        if (state->token == TOKEN_INTEGER) {
     325                bithenge_int_t val = state->token_int;
     326                next_token(state);
     327                bithenge_node_t *node;
     328                int rc = bithenge_new_integer_node(&node, val);
     329                if (rc != EOK) {
     330                        error_errno(state, rc);
     331                        return NULL;
     332                }
     333
     334                bithenge_expression_t *expr;
     335                rc = bithenge_const_expression(&expr, node);
     336                if (rc != EOK) {
     337                        error_errno(state, rc);
     338                        return NULL;
     339                }
     340
     341                return expr;
     342        } else {
     343                syntax_error(state, "expression expected");
     344                return NULL;
     345        }
     346}
     347
     348// state->token must be TOKEN_IDENTIFIER when this is called
     349static bithenge_transform_t *parse_invocation(state_t *state)
     350{
     351        bithenge_transform_t *result = get_named_transform(state,
     352            state->token_string);
     353        if (!result)
     354                syntax_error(state, "transform not found");
     355        next_token(state);
     356
     357        bithenge_expression_t **params = NULL;
     358        int num_params = 0;
     359        if (state->token == '(') {
     360                next_token(state);
     361                while (state->error == EOK && state->token != ')') {
     362                        if (num_params)
     363                                expect(state, ',');
     364                        params = state_realloc(state, params,
     365                            (num_params + 1)*sizeof(*params));
     366                        if (state->error != EOK)
     367                                break;
     368                        params[num_params] = parse_expression(state);
     369                        num_params++;
     370                }
     371                expect(state, ')');
     372        }
     373
     374        /* TODO: show correct error position */
     375        if (state->error == EOK
     376            && bithenge_transform_num_params(result) != num_params)
     377                syntax_error(state, "incorrect number of parameters before");
     378
     379        if (state->error != EOK) {
     380                while (num_params--)
     381                        bithenge_expression_dec_ref(params[num_params]);
     382                free(params);
     383                bithenge_transform_dec_ref(result);
     384                return NULL;
     385        }
     386
     387        if (num_params) {
     388                int rc = bithenge_param_wrapper(&result, result, params);
     389                if (rc != EOK) {
     390                        error_errno(state, rc);
     391                        result = NULL;
     392                }
     393        }
     394
     395        return result;
     396}
    309397
    310398static bithenge_transform_t *parse_struct(state_t *state)
     
    358446{
    359447        if (state->token == TOKEN_IDENTIFIER) {
    360                 bithenge_transform_t *result = get_named_transform(state,
    361                     state->token_string);
    362                 if (!result)
    363                         syntax_error(state, "transform not found");
    364                 next_token(state);
    365                 return result;
     448                return parse_invocation(state);
    366449        } else if (state->token == TOKEN_STRUCT) {
    367450                return parse_struct(state);
Note: See TracChangeset for help on using the changeset viewer.