Changeset 5e718d9 in mainline for uspace/lib/bithenge/script.c


Ignore:
Timestamp:
2012-08-21T10:04:16Z (13 years ago)
Author:
Vojtech Horky <vojtechhorky@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
67edca6
Parents:
0da6c04 (diff), 6a97f2e (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
Message:

Merge with upstream (lp:~wtachi/helenos/bithenge)

File:
1 moved

Legend:

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

    r0da6c04 r5e718d9  
    3838#include <stdio.h>
    3939#include <stdlib.h>
     40#include "compound.h"
    4041#include "expression.h"
    4142#include "os.h"
     
    4546#include "tree.h"
    4647
     48/** @cond internal */
     49#define BUFFER_SIZE 4096
     50/** @endcond */
     51
    4752/** Tokens with more characters than this may be read incorrectly. */
    48 #define MAX_TOKEN_SIZE 256
    49 #define BUFFER_SIZE 4096
    50 
    51 /** Single-character symbols are represented by the character itself. Every
     53static const int MAX_TOKEN_SIZE = 256;
     54
     55/** @cond internal
     56 * Single-character symbols are represented by the character itself. Every
    5257 * other token uses one of these values: */
    5358typedef enum {
    54         TOKEN_EQUALS = -128,
    55         TOKEN_ERROR,
     59        TOKEN_ERROR = -128,
     60
     61        TOKEN_AND,
     62        TOKEN_CONCAT,
     63        TOKEN_EQUALS,
    5664        TOKEN_EOF,
     65        TOKEN_GREATER_THAN_OR_EQUAL,
    5766        TOKEN_IDENTIFIER,
    5867        TOKEN_INTEGER,
     68        TOKEN_INTEGER_DIVIDE,
    5969        TOKEN_LEFT_ARROW,
     70        TOKEN_LESS_THAN_OR_EQUAL,
     71        TOKEN_NOT_EQUAL,
     72        TOKEN_OR,
    6073
    6174        /* Keywords */
     
    6578        TOKEN_IF,
    6679        TOKEN_IN,
     80        TOKEN_PARTIAL,
    6781        TOKEN_REPEAT,
    6882        TOKEN_STRUCT,
     
    7286        TOKEN_WHILE,
    7387} token_type_t;
     88/** @endcond */
    7489
    7590/** Singly-linked list of named transforms. */
     
    232247                        state->token = TOKEN_IN;
    233248                        free(value);
     249                } else if (!str_cmp(value, "partial")) {
     250                        state->token = TOKEN_PARTIAL;
     251                        free(value);
    234252                } else if (!str_cmp(value, "repeat")) {
    235253                        state->token = TOKEN_REPEAT;
     
    267285                        state->buffer_pos++;
    268286                        state->token = TOKEN_LEFT_ARROW;
     287                } else if (state->buffer[state->buffer_pos] == '=') {
     288                        state->buffer_pos++;
     289                        state->token = TOKEN_LESS_THAN_OR_EQUAL;
     290                }
     291        } else if (ch == '>') {
     292                state->token = ch;
     293                state->buffer_pos++;
     294                if (state->buffer[state->buffer_pos] == '=') {
     295                        state->buffer_pos++;
     296                        state->token = TOKEN_GREATER_THAN_OR_EQUAL;
    269297                }
    270298        } else if (ch == '=') {
     
    275303                        state->buffer_pos++;
    276304                }
     305        } else if (ch == '/') {
     306                state->token = ch;
     307                state->buffer_pos++;
     308                if (state->buffer[state->buffer_pos] == '/') {
     309                        state->token = TOKEN_INTEGER_DIVIDE;
     310                        state->buffer_pos++;
     311                }
     312        } else if (ch == '!') {
     313                state->token = ch;
     314                state->buffer_pos++;
     315                if (state->buffer[state->buffer_pos] == '=') {
     316                        state->token = TOKEN_NOT_EQUAL;
     317                        state->buffer_pos++;
     318                }
     319        } else if (ch == '&') {
     320                state->token = ch;
     321                state->buffer_pos++;
     322                if (state->buffer[state->buffer_pos] == '&') {
     323                        state->token = TOKEN_AND;
     324                        state->buffer_pos++;
     325                }
     326        } else if (ch == '|') {
     327                state->token = ch;
     328                state->buffer_pos++;
     329                if (state->buffer[state->buffer_pos] == '|') {
     330                        state->token = TOKEN_OR;
     331                        state->buffer_pos++;
     332                }
     333        } else if (ch == '+') {
     334                state->token = ch;
     335                state->buffer_pos++;
     336                if (state->buffer[state->buffer_pos] == '+') {
     337                        state->token = TOKEN_CONCAT;
     338                        state->buffer_pos++;
     339                }
    277340        } else {
    278341                state->token = ch;
     
    380443/***************** Expressions                               *****************/
    381444
     445/** @cond internal */
    382446typedef enum {
    383447        PRECEDENCE_NONE,
     448        PRECEDENCE_AND,
    384449        PRECEDENCE_EQUALS,
     450        PRECEDENCE_COMPARE,
    385451        PRECEDENCE_ADD,
    386452        PRECEDENCE_MULTIPLY,
    387453} precedence_t;
     454/** @endcond */
    388455
    389456static bithenge_binary_op_t token_as_binary_operator(token_type_t token)
     
    396463        case '*':
    397464                return BITHENGE_EXPRESSION_MULTIPLY;
     465        case TOKEN_INTEGER_DIVIDE:
     466                return BITHENGE_EXPRESSION_INTEGER_DIVIDE;
     467        case '%':
     468                return BITHENGE_EXPRESSION_MODULO;
     469        case '<':
     470                return BITHENGE_EXPRESSION_LESS_THAN;
     471        case TOKEN_LESS_THAN_OR_EQUAL:
     472                return BITHENGE_EXPRESSION_LESS_THAN_OR_EQUAL;
     473        case '>':
     474                return BITHENGE_EXPRESSION_GREATER_THAN;
     475        case TOKEN_GREATER_THAN_OR_EQUAL:
     476                return BITHENGE_EXPRESSION_GREATER_THAN_OR_EQUAL;
    398477        case TOKEN_EQUALS:
    399478                return BITHENGE_EXPRESSION_EQUALS;
     479        case TOKEN_NOT_EQUAL:
     480                return BITHENGE_EXPRESSION_NOT_EQUALS;
     481        case TOKEN_AND:
     482                return BITHENGE_EXPRESSION_AND;
     483        case TOKEN_OR:
     484                return BITHENGE_EXPRESSION_OR;
     485        case TOKEN_CONCAT:
     486                return BITHENGE_EXPRESSION_CONCAT;
    400487        default:
    401488                return BITHENGE_EXPRESSION_INVALID_BINARY_OP;
     
    407494        switch (op) {
    408495        case BITHENGE_EXPRESSION_ADD: /* fallthrough */
    409         case BITHENGE_EXPRESSION_SUBTRACT:
     496        case BITHENGE_EXPRESSION_SUBTRACT: /* fallthrough */
     497        case BITHENGE_EXPRESSION_CONCAT:
    410498                return PRECEDENCE_ADD;
    411         case BITHENGE_EXPRESSION_MULTIPLY:
     499        case BITHENGE_EXPRESSION_MULTIPLY: /* fallthrough */
     500        case BITHENGE_EXPRESSION_INTEGER_DIVIDE: /* fallthrough */
     501        case BITHENGE_EXPRESSION_MODULO:
    412502                return PRECEDENCE_MULTIPLY;
    413         case BITHENGE_EXPRESSION_EQUALS:
     503        case BITHENGE_EXPRESSION_LESS_THAN: /* fallthrough */
     504        case BITHENGE_EXPRESSION_LESS_THAN_OR_EQUAL: /* fallthrough */
     505        case BITHENGE_EXPRESSION_GREATER_THAN: /* fallthrough */
     506        case BITHENGE_EXPRESSION_GREATER_THAN_OR_EQUAL:
     507                return PRECEDENCE_COMPARE;
     508        case BITHENGE_EXPRESSION_EQUALS: /* fallthrough */
     509        case BITHENGE_EXPRESSION_NOT_EQUALS:
    414510                return PRECEDENCE_EQUALS;
     511        case BITHENGE_EXPRESSION_AND: /* fallthrough */
     512        case BITHENGE_EXPRESSION_OR:
     513                return PRECEDENCE_AND;
    415514        default:
    416515                assert(false);
     
    480579                }
    481580
     581                next_token(state);
     582
    482583                bithenge_expression_t *expr;
    483584                rc = bithenge_param_expression(&expr, i);
     
    486587                        return NULL;
    487588                }
    488 
    489                 next_token(state);
    490 
    491589                return expr;
    492590        } else if (state->token == '.') {
     
    530628}
    531629
     630static bithenge_expression_t *parse_postfix_expression(state_t *state)
     631{
     632        int rc;
     633        bithenge_expression_t *expr = parse_term(state);
     634        while (state->error == EOK) {
     635                if (state->token == '.') {
     636                        next_token(state);
     637
     638                        const char *id = expect_identifier(state);
     639
     640                        if (state->error != EOK) {
     641                                free((char *)id);
     642                                bithenge_expression_dec_ref(expr);
     643                                return NULL;
     644                        }
     645
     646                        bithenge_node_t *key = NULL;
     647                        rc = bithenge_new_string_node(&key, id, true);
     648                        if (rc != EOK) {
     649                                error_errno(state, rc);
     650                                bithenge_expression_dec_ref(expr);
     651                                return NULL;
     652                        }
     653
     654                        bithenge_expression_t *key_expr;
     655                        rc = bithenge_const_expression(&key_expr, key);
     656                        if (rc != EOK) {
     657                                error_errno(state, rc);
     658                                bithenge_expression_dec_ref(expr);
     659                                return NULL;
     660                        }
     661
     662                        rc = bithenge_binary_expression(&expr,
     663                            BITHENGE_EXPRESSION_MEMBER, expr, key_expr);
     664                        if (rc != EOK) {
     665                                error_errno(state, rc);
     666                                return NULL;
     667                        }
     668                } else if (state->token == '[') {
     669                        next_token(state);
     670                        bithenge_expression_t *start = parse_expression(state);
     671                        bool absolute_limit = false;
     672                        if (state->token == ',' || state->token == ':') {
     673                                absolute_limit = state->token == ':';
     674                                next_token(state);
     675                                bithenge_expression_t *limit = NULL;
     676                                if (!(state->token == ']' && absolute_limit))
     677                                        limit = parse_expression(state);
     678                                expect(state, ']');
     679
     680                                if (state->error != EOK) {
     681                                        bithenge_expression_dec_ref(expr);
     682                                        bithenge_expression_dec_ref(start);
     683                                        bithenge_expression_dec_ref(limit);
     684                                        return NULL;
     685                                }
     686                                rc = bithenge_subblob_expression(&expr, expr, start,
     687                                    limit, absolute_limit);
     688                                if (rc != EOK) {
     689                                        error_errno(state, rc);
     690                                        return NULL;
     691                                }
     692                        } else if (state->token == ']') {
     693                                next_token(state);
     694
     695                                if (state->error != EOK) {
     696                                        bithenge_expression_dec_ref(expr);
     697                                        bithenge_expression_dec_ref(start);
     698                                        return NULL;
     699                                }
     700                                rc = bithenge_binary_expression(&expr,
     701                                    BITHENGE_EXPRESSION_MEMBER, expr, start);
     702                                if (rc != EOK) {
     703                                        error_errno(state, rc);
     704                                        return NULL;
     705                                }
     706                        } else {
     707                                syntax_error(state, "expected ',', ':', or ']'");
     708                                bithenge_expression_dec_ref(expr);
     709                                bithenge_expression_dec_ref(start);
     710                                return NULL;
     711                        }
     712                } else {
     713                        break;
     714                }
     715        }
     716        return expr;
     717}
     718
    532719static bithenge_expression_t *parse_expression_precedence(state_t *state,
    533720    precedence_t prev_precedence)
    534721{
    535         bithenge_expression_t *expr = parse_term(state);
     722        bithenge_expression_t *expr = parse_postfix_expression(state);
    536723        while (state->error == EOK) {
    537724                bithenge_binary_op_t op =
     
    544731                next_token(state);
    545732
    546                 bithenge_expression_t *expr2 = parse_term(state);
     733                bithenge_expression_t *expr2 =
     734                    parse_expression_precedence(state, precedence);
    547735                if (state->error != EOK) {
    548736                        bithenge_expression_dec_ref(expr2);
     
    550738                }
    551739                int rc = bithenge_binary_expression(&expr, op, expr, expr2);
    552                 if (rc != EOK)
    553                         error_errno(state, rc);
     740                if (rc != EOK) {
     741                        expr = NULL;
     742                        error_errno(state, rc);
     743                }
    554744        }
    555745        if (state->error != EOK) {
     
    759949                int rc = bithenge_if_transform(&switch_xform, exprs[num],
    760950                    xforms[num], switch_xform);
    761                 if (rc != EOK)
    762                         error_errno(state, rc);
     951                if (rc != EOK) {
     952                        switch_xform = NULL;
     953                        error_errno(state, rc);
     954                }
    763955        }
    764956
     
    8271019        }
    8281020        return do_while_xform;
     1021}
     1022
     1023static bithenge_transform_t *parse_partial(state_t *state)
     1024{
     1025        expect(state, TOKEN_PARTIAL);
     1026        bithenge_transform_t *offset_xform = NULL;
     1027        if (state->token == '(') {
     1028                next_token(state);
     1029                bithenge_expression_t *offset = parse_expression(state);
     1030                expect(state, ')');
     1031
     1032                bithenge_expression_t *in_expr;
     1033                int rc = bithenge_in_node_expression(&in_expr);
     1034                if (rc != EOK)
     1035                        error_errno(state, rc);
     1036                if (state->error != EOK) {
     1037                        bithenge_expression_dec_ref(offset);
     1038                        return NULL;
     1039                }
     1040
     1041                rc = bithenge_subblob_expression(&offset, in_expr, offset,
     1042                    NULL, true);
     1043                if (rc != EOK) {
     1044                        error_errno(state, rc);
     1045                        return NULL;
     1046                }
     1047
     1048                rc = bithenge_expression_transform(&offset_xform, offset);
     1049                if (rc != EOK) {
     1050                        error_errno(state, rc);
     1051                        return NULL;
     1052                }
     1053        }
     1054        expect(state, '{');
     1055        bithenge_transform_t *xform = parse_transform(state);
     1056        expect(state, '}');
     1057        if (state->error != EOK) {
     1058                bithenge_transform_dec_ref(offset_xform);
     1059                bithenge_transform_dec_ref(xform);
     1060                return NULL;
     1061        }
     1062
     1063        int rc = bithenge_partial_transform(&xform, xform);
     1064        if (rc != EOK) {
     1065                error_errno(state, rc);
     1066                bithenge_transform_dec_ref(offset_xform);
     1067                return NULL;
     1068        }
     1069
     1070        if (offset_xform) {
     1071                bithenge_transform_t **xforms = malloc(2 * sizeof(*xforms));
     1072                if (!xforms) {
     1073                        error_errno(state, ENOMEM);
     1074                        bithenge_transform_dec_ref(xform);
     1075                        bithenge_transform_dec_ref(offset_xform);
     1076                        return NULL;
     1077                }
     1078                xforms[0] = xform;
     1079                xforms[1] = offset_xform;
     1080                rc = bithenge_new_composed_transform(&xform, xforms, 2);
     1081                if (rc != EOK) {
     1082                        error_errno(state, rc);
     1083                        return NULL;
     1084                }
     1085        }
     1086
     1087        return xform;
    8291088}
    8301089
     
    9101169        } else if (state->token == TOKEN_IF) {
    9111170                return parse_if(state, false);
     1171        } else if (state->token == TOKEN_PARTIAL) {
     1172                return parse_partial(state);
    9121173        } else if (state->token == TOKEN_REPEAT) {
    9131174                return parse_repeat(state);
     
    9391200                if (state->error != EOK)
    9401201                        break;
    941                 xforms[num] = parse_transform_no_compose(state);
    942                 num++;
     1202                xforms[num++] = parse_transform_no_compose(state);
    9431203        }
    9441204        if (state->error != EOK) {
    945                 while (xforms && num--)
    946                         bithenge_transform_dec_ref(xforms[num]);
     1205                while (xforms && num > 1)
     1206                        bithenge_transform_dec_ref(xforms[--num]);
    9471207                free(xforms);
    9481208                bithenge_transform_dec_ref(result);
     
    9821242        }
    9831243
     1244        bithenge_transform_t *barrier = NULL;
     1245        if (state->error == EOK) {
     1246                int rc = bithenge_new_barrier_transform(&barrier,
     1247                    state->num_params);
     1248                if (rc != EOK) {
     1249                        barrier = NULL;
     1250                        error_errno(state, rc);
     1251                }
     1252        }
     1253
     1254        add_named_transform(state, barrier, name);
     1255
    9841256        expect(state, '=');
    9851257        bithenge_transform_t *xform = parse_transform(state);
     
    9871259
    9881260        if (state->error == EOK) {
    989                 int rc = bithenge_new_barrier_transform(&xform, xform,
    990                     state->num_params);
    991                 if (rc != EOK) {
    992                         xform = NULL;
    993                         error_errno(state, rc);
    994                 }
    995         }
    996 
    997         add_named_transform(state, xform, name);
     1261                int rc = bithenge_barrier_transform_set_subtransform(barrier,
     1262                    xform);
     1263                xform = NULL;
     1264                if (rc != EOK)
     1265                        error_errno(state, rc);
     1266        }
     1267
     1268        if (state->error != EOK)
     1269                bithenge_transform_dec_ref(xform);
    9981270
    9991271        for (int i = 0; i < state->num_params; i++)
Note: See TracChangeset for help on using the changeset viewer.