Fork us on GitHub Follow us on Facebook Follow us on Twitter

Changeset ad5c8a48 in mainline


Ignore:
Timestamp:
2012-08-07T21:35:50Z (9 years ago)
Author:
Sean Bartell <wingedtachikoma@…>
Branches:
lfn, master
Children:
a66ea217
Parents:
c12b2ae
Message:

Bithenge: add expressions with binary operators

Location:
uspace/app/bithenge
Files:
3 edited

Legend:

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

    rc12b2ae rad5c8a48  
    9494                return rc;
    9595        }
     96
     97        /* Check types and get values. */
     98        bithenge_int_t a_int, b_int;
    9699        switch (self->op) {
     100        case BITHENGE_EXPRESSION_ADD: /* fallthrough */
     101        case BITHENGE_EXPRESSION_SUBTRACT: /* fallthrough */
     102        case BITHENGE_EXPRESSION_MULTIPLY:
     103                rc = EINVAL;
     104                if (bithenge_node_type(a) != BITHENGE_NODE_INTEGER)
     105                        goto error;
     106                if (bithenge_node_type(b) != BITHENGE_NODE_INTEGER)
     107                        goto error;
     108                a_int = bithenge_integer_node_value(a);
     109                b_int = bithenge_integer_node_value(b);
     110                break;
     111        default:
     112                break;
     113        }
     114
     115        switch (self->op) {
     116        case BITHENGE_EXPRESSION_ADD:
     117                rc = bithenge_new_integer_node(out, a_int + b_int);
     118                break;
     119        case BITHENGE_EXPRESSION_SUBTRACT:
     120                rc = bithenge_new_integer_node(out, a_int - b_int);
     121                break;
     122        case BITHENGE_EXPRESSION_MULTIPLY:
     123                rc = bithenge_new_integer_node(out, a_int * b_int);
     124                break;
    97125        case BITHENGE_EXPRESSION_EQUALS:
    98126                rc = bithenge_new_boolean_node(out, bithenge_node_equal(a, b));
    99127                break;
    100         }
     128        case BITHENGE_EXPRESSION_INVALID_BINARY_OP:
     129                assert(false);
     130                break;
     131        }
     132
     133error:
    101134        bithenge_node_dec_ref(a);
    102135        bithenge_node_dec_ref(b);
  • uspace/app/bithenge/expression.h

    rc12b2ae rad5c8a48  
    9292
    9393typedef enum {
     94        BITHENGE_EXPRESSION_INVALID_BINARY_OP,
     95        BITHENGE_EXPRESSION_ADD,
     96        BITHENGE_EXPRESSION_SUBTRACT,
     97        BITHENGE_EXPRESSION_MULTIPLY,
    9498        BITHENGE_EXPRESSION_EQUALS,
    9599} bithenge_binary_op_t;
  • uspace/app/bithenge/script.c

    rc12b2ae rad5c8a48  
    5252 * other token uses one of these values: */
    5353typedef enum {
    54         TOKEN_ERROR = -128,
     54        TOKEN_EQUALS = -128,
     55        TOKEN_ERROR,
    5556        TOKEN_EOF,
    5657        TOKEN_IDENTIFIER,
     
    261262                        state->token = TOKEN_LEFT_ARROW;
    262263                }
     264        } else if (ch == '=') {
     265                state->token = ch;
     266                state->buffer_pos++;
     267                if (state->buffer[state->buffer_pos] == '=') {
     268                        state->token = TOKEN_EQUALS;
     269                        state->buffer_pos++;
     270                }
    263271        } else {
    264272                state->token = ch;
     
    360368static bithenge_transform_t *parse_transform(state_t *state);
    361369static bithenge_transform_t *parse_struct(state_t *state);
    362 
    363 static bithenge_expression_t *parse_expression(state_t *state)
     370static bithenge_expression_t *parse_expression(state_t *state);
     371
     372
     373
     374/***************** Expressions                               *****************/
     375
     376typedef enum {
     377        PRECEDENCE_NONE,
     378        PRECEDENCE_EQUALS,
     379        PRECEDENCE_ADD,
     380        PRECEDENCE_MULTIPLY,
     381} precedence_t;
     382
     383static bithenge_binary_op_t token_as_binary_operator(token_type_t token)
     384{
     385        switch ((int)token) {
     386        case '+':
     387                return BITHENGE_EXPRESSION_ADD;
     388        case '-':
     389                return BITHENGE_EXPRESSION_SUBTRACT;
     390        case '*':
     391                return BITHENGE_EXPRESSION_MULTIPLY;
     392        case TOKEN_EQUALS:
     393                return BITHENGE_EXPRESSION_EQUALS;
     394        default:
     395                return BITHENGE_EXPRESSION_INVALID_BINARY_OP;
     396        }
     397}
     398
     399static precedence_t binary_operator_precedence(bithenge_binary_op_t op)
     400{
     401        switch (op) {
     402        case BITHENGE_EXPRESSION_ADD: /* fallthrough */
     403        case BITHENGE_EXPRESSION_SUBTRACT:
     404                return PRECEDENCE_ADD;
     405        case BITHENGE_EXPRESSION_MULTIPLY:
     406                return PRECEDENCE_MULTIPLY;
     407        case BITHENGE_EXPRESSION_EQUALS:
     408                return PRECEDENCE_EQUALS;
     409        default:
     410                assert(false);
     411                return PRECEDENCE_NONE;
     412        }
     413}
     414
     415static bithenge_expression_t *parse_term(state_t *state)
    364416{
    365417        int rc;
     
    451503
    452504                return expr;
     505        } else if (state->token == '(') {
     506                next_token(state);
     507                bithenge_expression_t *expr = parse_expression(state);
     508                expect(state, ')');
     509                return expr;
    453510        } else {
    454511                syntax_error(state, "expression expected");
     
    457514}
    458515
    459 // state->token must be TOKEN_IDENTIFIER when this is called
     516static bithenge_expression_t *parse_expression_precedence(state_t *state,
     517    precedence_t prev_precedence)
     518{
     519        bithenge_expression_t *expr = parse_term(state);
     520        while (state->error == EOK) {
     521                bithenge_binary_op_t op =
     522                    token_as_binary_operator(state->token);
     523                if (op == BITHENGE_EXPRESSION_INVALID_BINARY_OP)
     524                        break;
     525                precedence_t precedence = binary_operator_precedence(op);
     526                if (precedence <= prev_precedence)
     527                        break;
     528                next_token(state);
     529
     530                bithenge_expression_t *expr2 = parse_term(state);
     531                if (state->error != EOK) {
     532                        bithenge_expression_dec_ref(expr2);
     533                        break;
     534                }
     535                int rc = bithenge_binary_expression(&expr, op, expr, expr2);
     536                if (rc != EOK)
     537                        error_errno(state, rc);
     538        }
     539        if (state->error != EOK) {
     540                bithenge_expression_dec_ref(expr);
     541                expr = NULL;
     542        }
     543        return expr;
     544}
     545
     546static bithenge_expression_t *parse_expression(state_t *state)
     547{
     548        return parse_expression_precedence(state, PRECEDENCE_NONE);
     549}
     550
     551
     552
     553/* state->token must be TOKEN_IDENTIFIER when this is called. */
    460554static bithenge_transform_t *parse_invocation(state_t *state)
    461555{
Note: See TracChangeset for help on using the changeset viewer.