Exemple #1
0
static int parse_numeric_literal(parser_ctx_t *ctx, literal_t **literal)
{
    LONG l, d;

    l = *ctx->ptr++ - '0';
    if(!l) {
        if(*ctx->ptr == 'x' || *ctx->ptr == 'X') {
            if(++ctx->ptr == ctx->end) {
                ERR("unexpected end of file\n");
                return 0;
            }

            while(ctx->ptr < ctx->end && (d = hex_to_int(*ctx->ptr)) != -1) {
                l = l*16 + d;
                ctx->ptr++;
            }

            if(ctx->ptr < ctx->end && is_identifier_char(*ctx->ptr)) {
                WARN("unexpected identifier char\n");
                return lex_error(ctx, JS_E_MISSING_SEMICOLON);
            }

            *literal = new_double_literal(ctx, l);
            return tNumericLiteral;
        }

        if(isdigitW(*ctx->ptr)) {
            unsigned base = 8;
            const WCHAR *ptr;
            double val = 0;

            for(ptr = ctx->ptr; ptr < ctx->end && isdigitW(*ptr); ptr++) {
                if(*ptr > '7') {
                    base = 10;
                    break;
                }
            }

            do {
                val = val*base + *ctx->ptr-'0';
            }while(++ctx->ptr < ctx->end && isdigitW(*ctx->ptr));

            /* FIXME: Do we need it here? */
            if(ctx->ptr < ctx->end && (is_identifier_char(*ctx->ptr) || *ctx->ptr == '.')) {
                WARN("wrong char after octal literal: '%c'\n", *ctx->ptr);
                return lex_error(ctx, JS_E_MISSING_SEMICOLON);
            }

            *literal = new_double_literal(ctx, val);
            return tNumericLiteral;
        }

        if(is_identifier_char(*ctx->ptr)) {
            WARN("wrong char after zero\n");
            return lex_error(ctx, JS_E_MISSING_SEMICOLON);
        }
    }

    return parse_double_literal(ctx, l, literal);
}
Exemple #2
0
static int cc_token(parser_ctx_t *ctx, void *lval)
{
    unsigned id_len = 0;
    cc_var_t *var;

    static const WCHAR cc_onW[] = {'c','c','_','o','n',0};
    static const WCHAR setW[] = {'s','e','t',0};
    static const WCHAR elifW[] = {'e','l','i','f',0};
    static const WCHAR endW[] = {'e','n','d',0};

    ctx->ptr++;

    if(!check_keyword(ctx, cc_onW, NULL))
        return init_cc(ctx);

    if(!check_keyword(ctx, setW, NULL)) {
        FIXME("@set not implemented\n");
        return lex_error(ctx, E_NOTIMPL);
    }

    if(!check_keyword(ctx, ifW, NULL)) {
        FIXME("@if not implemented\n");
        return lex_error(ctx, E_NOTIMPL);
    }

    if(!check_keyword(ctx, elifW, NULL)) {
        FIXME("@elif not implemented\n");
        return lex_error(ctx, E_NOTIMPL);
    }

    if(!check_keyword(ctx, elseW, NULL)) {
        FIXME("@else not implemented\n");
        return lex_error(ctx, E_NOTIMPL);
    }

    if(!check_keyword(ctx, endW, NULL)) {
        FIXME("@end not implemented\n");
        return lex_error(ctx, E_NOTIMPL);
    }

    if(!ctx->script->cc)
        return lex_error(ctx, JS_E_DISABLED_CC);

    while(ctx->ptr+id_len < ctx->end && is_identifier_char(ctx->ptr[id_len]))
        id_len++;
    if(!id_len)
        return '@';

    TRACE("var %s\n", debugstr_wn(ctx->ptr, id_len));

    var = find_cc_var(ctx->script->cc, ctx->ptr, id_len);
    ctx->ptr += id_len;
    if(!var || var->is_num) {
        *(literal_t**)lval = new_double_literal(ctx, var ? var->u.n : ret_nan());
        return tNumericLiteral;
    }

    *(literal_t**)lval = new_boolean_literal(ctx, var->u.b);
    return tBooleanLiteral;
}
Exemple #3
0
struct ast* default_value_for(enum datatype type){
	switch(type){
		case INT: return new_int_literal(0);
		case DOUBLE: return new_double_literal(0);
		case NONE: return NULL;
		case INVALID_DATATYPE: return NULL;
	}
}
Exemple #4
0
static int parse_double_literal(parser_ctx_t *ctx, LONG int_part, literal_t **literal)
{
    LONGLONG d, hlp;
    int exp = 0;

    if(ctx->ptr == ctx->end || (!isdigitW(*ctx->ptr) &&
        *ctx->ptr!='.' && *ctx->ptr!='e' && *ctx->ptr!='E')) {
        ERR("Illegal character\n");
        return 0;
    }

    d = int_part;
    while(ctx->ptr < ctx->end && isdigitW(*ctx->ptr)) {
        hlp = d*10 + *(ctx->ptr++) - '0';
        if(d>LONGLONG_MAX/10 || hlp<0) {
            exp++;
            break;
        }
        else
            d = hlp;
    }
    while(ctx->ptr < ctx->end && isdigitW(*ctx->ptr)) {
        exp++;
        ctx->ptr++;
    }

    if(*ctx->ptr == '.') ctx->ptr++;

    while(ctx->ptr < ctx->end && isdigitW(*ctx->ptr)) {
        hlp = d*10 + *(ctx->ptr++) - '0';
        if(d>LONGLONG_MAX/10 || hlp<0)
            break;

        d = hlp;
        exp--;
    }
    while(ctx->ptr < ctx->end && isdigitW(*ctx->ptr))
        ctx->ptr++;

    if(ctx->ptr < ctx->end && (*ctx->ptr == 'e' || *ctx->ptr == 'E')) {
        int sign = 1, e = 0;

        ctx->ptr++;
        if(ctx->ptr < ctx->end) {
            if(*ctx->ptr == '+') {
                ctx->ptr++;
            }else if(*ctx->ptr == '-') {
                sign = -1;
                ctx->ptr++;
            }else if(!isdigitW(*ctx->ptr)) {
                WARN("Expected exponent part\n");
                return lex_error(ctx, E_FAIL);
            }
        }

        if(ctx->ptr == ctx->end) {
            WARN("unexpected end of file\n");
            return lex_error(ctx, E_FAIL);
        }

        while(ctx->ptr < ctx->end && isdigitW(*ctx->ptr)) {
            if(e > INT_MAX/10 || (e = e*10 + *ctx->ptr++ - '0')<0)
                e = INT_MAX;
        }
        e *= sign;

        if(exp<0 && e<0 && e+exp>0) exp = INT_MIN;
        else if(exp>0 && e>0 && e+exp<0) exp = INT_MAX;
        else exp += e;
    }

    *literal = new_double_literal(ctx, (DOUBLE)d*pow(10, exp));
    return tNumericLiteral;
}
Exemple #5
0
static int cc_token(parser_ctx_t *ctx, void *lval)
{
    unsigned id_len = 0;
    cc_var_t *var;

    static const WCHAR cc_onW[] = {'c','c','_','o','n',0};
    static const WCHAR setW[] = {'s','e','t',0};

    ctx->ptr++;

    if(!check_keyword(ctx, cc_onW, NULL))
        return init_cc(ctx) ? 0 : -1;

    if(!check_keyword(ctx, setW, NULL)) {
        const WCHAR *ident;
        unsigned ident_len;
        cc_var_t *var;

        if(!init_cc(ctx))
            return -1;

        if(!skip_spaces(ctx))
            return lex_error(ctx, JS_E_EXPECTED_AT);

        if(!parse_cc_identifier(ctx, &ident, &ident_len))
            return -1;

        if(!skip_spaces(ctx) || *ctx->ptr != '=')
            return lex_error(ctx, JS_E_EXPECTED_ASSIGN);
        ctx->ptr++;

        if(!parse_cc_expr(ctx)) {
            WARN("parsing CC expression failed\n");
            return -1;
        }

        var = find_cc_var(ctx->script->cc, ident, ident_len);
        if(var) {
            var->val = ctx->ccval;
        }else {
            if(!new_cc_var(ctx->script->cc, ident, ident_len, ctx->ccval))
                return lex_error(ctx, E_OUTOFMEMORY);
        }

        return 0;
    }

    if(!check_keyword(ctx, ifW, NULL)) {
        if(!init_cc(ctx))
            return -1;

        if(!skip_spaces(ctx) || *ctx->ptr != '(')
            return lex_error(ctx, JS_E_MISSING_LBRACKET);

        if(!parse_cc_expr(ctx))
            return -1;

        if(get_ccbool(ctx->ccval)) {
            /* continue parsing block inside if */
            ctx->cc_if_depth++;
            return 0;
        }

        return skip_code(ctx, TRUE);
    }

    if(!check_keyword(ctx, elifW, NULL) || !check_keyword(ctx, elseW, NULL)) {
        if(!ctx->cc_if_depth)
            return lex_error(ctx, JS_E_SYNTAX);

        return skip_code(ctx, FALSE);
    }

    if(!check_keyword(ctx, endW, NULL)) {
        if(!ctx->cc_if_depth)
            return lex_error(ctx, JS_E_SYNTAX);

        ctx->cc_if_depth--;
        return 0;
    }

    if(!ctx->script->cc)
        return lex_error(ctx, JS_E_DISABLED_CC);

    while(ctx->ptr+id_len < ctx->end && is_identifier_char(ctx->ptr[id_len]))
        id_len++;
    if(!id_len)
        return '@';

    TRACE("var %s\n", debugstr_wn(ctx->ptr, id_len));

    var = find_cc_var(ctx->script->cc, ctx->ptr, id_len);
    ctx->ptr += id_len;
    if(!var || var->val.is_num) {
        *(literal_t**)lval = new_double_literal(ctx, var ? var->val.u.n : NAN);
        return tNumericLiteral;
    }

    *(literal_t**)lval = new_boolean_literal(ctx, var->val.u.b);
    return tBooleanLiteral;
}
Exemple #6
0
static int next_token(parser_ctx_t *ctx, void *lval)
{
    do {
        if(!skip_spaces(ctx))
            return tEOF;
    }while(skip_comment(ctx) || skip_html_comment(ctx));

    if(ctx->implicit_nl_semicolon) {
        if(ctx->nl)
            return ';';
        ctx->implicit_nl_semicolon = FALSE;
    }

    if(isalphaW(*ctx->ptr)) {
        int ret = check_keywords(ctx, lval);
        if(ret)
            return ret;

        return parse_identifier(ctx, lval);
    }

    if(isdigitW(*ctx->ptr)) {
        double n;

        if(!parse_numeric_literal(ctx, &n))
            return -1;

        *(literal_t**)lval = new_double_literal(ctx, n);
        return tNumericLiteral;
    }

    switch(*ctx->ptr) {
    case '{':
    case '(':
    case ')':
    case '[':
    case ']':
    case ';':
    case ',':
    case '~':
    case '?':
    case ':':
        return *ctx->ptr++;

    case '}':
        *(const WCHAR**)lval = ctx->ptr++;
        return '}';

    case '.':
        if(++ctx->ptr < ctx->end && isdigitW(*ctx->ptr)) {
            double n;
            if(!parse_double_literal(ctx, 0, &n))
                return -1;
            *(literal_t**)lval = new_double_literal(ctx, n);
            return tNumericLiteral;
        }
        return '.';

    case '<':
        if(++ctx->ptr == ctx->end) {
            *(int*)lval = EXPR_LESS;
            return tRelOper;
        }

        switch(*ctx->ptr) {
        case '=':  /* <= */
            ctx->ptr++;
            *(int*)lval = EXPR_LESSEQ;
            return tRelOper;
        case '<':  /* << */
            if(++ctx->ptr < ctx->end && *ctx->ptr == '=') { /* <<= */
                ctx->ptr++;
                *(int*)lval = EXPR_ASSIGNLSHIFT;
                return tAssignOper;
            }
            *(int*)lval = EXPR_LSHIFT;
            return tShiftOper;
        default: /* < */
            *(int*)lval = EXPR_LESS;
            return tRelOper;
        }

    case '>':
        if(++ctx->ptr == ctx->end) { /* > */
            *(int*)lval = EXPR_GREATER;
            return tRelOper;
        }

        switch(*ctx->ptr) {
        case '=':  /* >= */
            ctx->ptr++;
            *(int*)lval = EXPR_GREATEREQ;
            return tRelOper;
        case '>':  /* >> */
            if(++ctx->ptr < ctx->end) {
                if(*ctx->ptr == '=') {  /* >>= */
                    ctx->ptr++;
                    *(int*)lval = EXPR_ASSIGNRSHIFT;
                    return tAssignOper;
                }
                if(*ctx->ptr == '>') {  /* >>> */
                    if(++ctx->ptr < ctx->end && *ctx->ptr == '=') {  /* >>>= */
                        ctx->ptr++;
                        *(int*)lval = EXPR_ASSIGNRRSHIFT;
                        return tAssignOper;
                    }
                    *(int*)lval = EXPR_RRSHIFT;
                    return tRelOper;
                }
            }
            *(int*)lval = EXPR_RSHIFT;
            return tShiftOper;
        default:
            *(int*)lval = EXPR_GREATER;
            return tRelOper;
        }

    case '+':
        ctx->ptr++;
        if(ctx->ptr < ctx->end) {
            switch(*ctx->ptr) {
            case '+':  /* ++ */
                ctx->ptr++;
                return tINC;
            case '=':  /* += */
                ctx->ptr++;
                *(int*)lval = EXPR_ASSIGNADD;
                return tAssignOper;
            }
        }
        return '+';

    case '-':
        ctx->ptr++;
        if(ctx->ptr < ctx->end) {
            switch(*ctx->ptr) {
            case '-':  /* -- or --> */
                ctx->ptr++;
                if(ctx->is_html && ctx->nl && ctx->ptr < ctx->end && *ctx->ptr == '>') {
                    ctx->ptr++;
                    return tHTMLCOMMENT;
                }
                return tDEC;
            case '=':  /* -= */
                ctx->ptr++;
                *(int*)lval = EXPR_ASSIGNSUB;
                return tAssignOper;
            }
        }
        return '-';

    case '*':
        if(++ctx->ptr < ctx->end && *ctx->ptr == '=') { /* *= */
            ctx->ptr++;
            *(int*)lval = EXPR_ASSIGNMUL;
            return tAssignOper;
        }
        return '*';

    case '%':
        if(++ctx->ptr < ctx->end && *ctx->ptr == '=') { /* %= */
            ctx->ptr++;
            *(int*)lval = EXPR_ASSIGNMOD;
            return tAssignOper;
        }
        return '%';

    case '&':
        if(++ctx->ptr < ctx->end) {
            switch(*ctx->ptr) {
            case '=':  /* &= */
                ctx->ptr++;
                *(int*)lval = EXPR_ASSIGNAND;
                return tAssignOper;
            case '&':  /* && */
                ctx->ptr++;
                return tANDAND;
            }
        }
        return '&';

    case '|':
        if(++ctx->ptr < ctx->end) {
            switch(*ctx->ptr) {
            case '=':  /* |= */
                ctx->ptr++;
                *(int*)lval = EXPR_ASSIGNOR;
                return tAssignOper;
            case '|':  /* || */
                ctx->ptr++;
                return tOROR;
            }
        }
        return '|';

    case '^':
        if(++ctx->ptr < ctx->end && *ctx->ptr == '=') {  /* ^= */
            ctx->ptr++;
            *(int*)lval = EXPR_ASSIGNXOR;
            return tAssignOper;
        }
        return '^';

    case '!':
        if(++ctx->ptr < ctx->end && *ctx->ptr == '=') {  /* != */
            if(++ctx->ptr < ctx->end && *ctx->ptr == '=') {  /* !== */
                ctx->ptr++;
                *(int*)lval = EXPR_NOTEQEQ;
                return tEqOper;
            }
            *(int*)lval = EXPR_NOTEQ;
            return tEqOper;
        }
        return '!';

    case '=':
        if(++ctx->ptr < ctx->end && *ctx->ptr == '=') {  /* == */
            if(++ctx->ptr < ctx->end && *ctx->ptr == '=') {  /* === */
                ctx->ptr++;
                *(int*)lval = EXPR_EQEQ;
                return tEqOper;
            }
            *(int*)lval = EXPR_EQ;
            return tEqOper;
        }
        return '=';

    case '/':
        if(++ctx->ptr < ctx->end) {
            if(*ctx->ptr == '=') {  /* /= */
                ctx->ptr++;
                *(int*)lval = EXPR_ASSIGNDIV;
                return kDIVEQ;
            }
        }
        return '/';

    case '\"':
    case '\'':
        return parse_string_literal(ctx, lval, *ctx->ptr);

    case '_':
    case '$':
        return parse_identifier(ctx, lval);

    case '@':
        return '@';
    }

    WARN("unexpected char '%c' %d\n", *ctx->ptr, *ctx->ptr);
    return 0;
}
Exemple #7
0
static int parse_double_literal(parser_ctx_t *ctx, LONG int_part, literal_t **literal)
{
    LONGLONG d, hlp;
    int exp = 0;

    d = int_part;
    while(ctx->ptr < ctx->end && isdigitW(*ctx->ptr)) {
        hlp = d*10 + *(ctx->ptr++) - '0';
        if(d>MAXLONGLONG/10 || hlp<0) {
            exp++;
            break;
        }
        else
            d = hlp;
    }
    while(ctx->ptr < ctx->end && isdigitW(*ctx->ptr)) {
        exp++;
        ctx->ptr++;
    }

    if(*ctx->ptr == '.') {
        ctx->ptr++;

        while(ctx->ptr < ctx->end && isdigitW(*ctx->ptr)) {
            hlp = d*10 + *(ctx->ptr++) - '0';
            if(d>MAXLONGLONG/10 || hlp<0)
                break;

            d = hlp;
            exp--;
        }
        while(ctx->ptr < ctx->end && isdigitW(*ctx->ptr))
            ctx->ptr++;
    }

    if(ctx->ptr < ctx->end && (*ctx->ptr == 'e' || *ctx->ptr == 'E')) {
        int sign = 1, e = 0;

        ctx->ptr++;
        if(ctx->ptr < ctx->end) {
            if(*ctx->ptr == '+') {
                ctx->ptr++;
            }else if(*ctx->ptr == '-') {
                sign = -1;
                ctx->ptr++;
            }else if(!isdigitW(*ctx->ptr)) {
                WARN("Expected exponent part\n");
                return lex_error(ctx, E_FAIL);
            }
        }

        if(ctx->ptr == ctx->end) {
            WARN("unexpected end of file\n");
            return lex_error(ctx, E_FAIL);
        }

        while(ctx->ptr < ctx->end && isdigitW(*ctx->ptr)) {
            if(e > INT_MAX/10 || (e = e*10 + *ctx->ptr++ - '0')<0)
                e = INT_MAX;
        }
        e *= sign;

        if(exp<0 && e<0 && e+exp>0) exp = INT_MIN;
        else if(exp>0 && e>0 && e+exp<0) exp = INT_MAX;
        else exp += e;
    }

    if(is_identifier_char(*ctx->ptr)) {
        WARN("wrong char after zero\n");
        return lex_error(ctx, JS_E_MISSING_SEMICOLON);
    }

    *literal = new_double_literal(ctx, exp>=0 ? d*pow(10, exp) : d/pow(10, -exp));
    return tNumericLiteral;
}