From d801c296c602d04055b02b3be2f1369bfe1092b7 Mon Sep 17 00:00:00 2001 From: Michal Krol Date: Sun, 20 Dec 2009 21:11:16 +0100 Subject: glsl: Do syntax parsing inline with processing. --- src/glsl/cl/sl_cl_parse.c | 151 ++++++++++++++++++++++++++++++++++++------ src/glsl/cl/sl_cl_parse.h | 1 - src/glsl/pp/sl_pp_context.c | 3 + src/glsl/pp/sl_pp_context.h | 3 + src/glsl/pp/sl_pp_define.c | 1 + src/glsl/pp/sl_pp_error.c | 1 + src/glsl/pp/sl_pp_extension.c | 1 + src/glsl/pp/sl_pp_line.c | 1 + src/glsl/pp/sl_pp_macro.c | 1 + src/glsl/pp/sl_pp_pragma.c | 1 + src/glsl/pp/sl_pp_process.c | 116 +++++++++++++++++++++----------- src/glsl/pp/sl_pp_process.h | 3 +- src/glsl/pp/sl_pp_public.h | 4 ++ 13 files changed, 225 insertions(+), 62 deletions(-) diff --git a/src/glsl/cl/sl_cl_parse.c b/src/glsl/cl/sl_cl_parse.c index a9db65c7ad..5dddf434e1 100644 --- a/src/glsl/cl/sl_cl_parse.c +++ b/src/glsl/cl/sl_cl_parse.c @@ -321,10 +321,13 @@ struct parse_dict { struct parse_context { struct sl_pp_context *context; - const struct sl_pp_token_info *input; struct parse_dict dict; + struct sl_pp_token_info *tokens; + unsigned int tokens_read; + unsigned int tokens_cap; + unsigned char *out_buf; unsigned int out_cap; @@ -332,6 +335,7 @@ struct parse_context { unsigned int parsing_builtin; char error[256]; + int process_error; }; @@ -366,7 +370,7 @@ _update(struct parse_context *ctx, static void _error(struct parse_context *ctx, - char *msg) + const char *msg) { if (ctx->error[0] == '\0') { strcpy(ctx->error, msg); @@ -374,12 +378,96 @@ _error(struct parse_context *ctx, } +static const struct sl_pp_token_info * +_fetch_token(struct parse_context *ctx, + unsigned int pos) +{ + if (ctx->process_error) { + return NULL; + } + + while (pos >= ctx->tokens_read) { + if (ctx->tokens_read == ctx->tokens_cap) { + ctx->tokens_cap += 1024; + ctx->tokens = realloc(ctx->tokens, + ctx->tokens_cap * sizeof(struct sl_pp_token_info)); + if (!ctx->tokens) { + _error(ctx, "out of memory"); + ctx->process_error = 1; + return NULL; + } + } + if (sl_pp_process_get(ctx->context, &ctx->tokens[ctx->tokens_read])) { + _error(ctx, sl_pp_context_error_message(ctx->context)); + ctx->process_error = 1; + return NULL; + } + switch (ctx->tokens[ctx->tokens_read].token) { + case SL_PP_COMMA: + case SL_PP_SEMICOLON: + case SL_PP_LBRACE: + case SL_PP_RBRACE: + case SL_PP_LPAREN: + case SL_PP_RPAREN: + case SL_PP_LBRACKET: + case SL_PP_RBRACKET: + case SL_PP_DOT: + case SL_PP_INCREMENT: + case SL_PP_ADDASSIGN: + case SL_PP_PLUS: + case SL_PP_DECREMENT: + case SL_PP_SUBASSIGN: + case SL_PP_MINUS: + case SL_PP_BITNOT: + case SL_PP_NOTEQUAL: + case SL_PP_NOT: + case SL_PP_MULASSIGN: + case SL_PP_STAR: + case SL_PP_DIVASSIGN: + case SL_PP_SLASH: + case SL_PP_MODASSIGN: + case SL_PP_MODULO: + case SL_PP_LSHIFTASSIGN: + case SL_PP_LSHIFT: + case SL_PP_LESSEQUAL: + case SL_PP_LESS: + case SL_PP_RSHIFTASSIGN: + case SL_PP_RSHIFT: + case SL_PP_GREATEREQUAL: + case SL_PP_GREATER: + case SL_PP_EQUAL: + case SL_PP_ASSIGN: + case SL_PP_AND: + case SL_PP_BITANDASSIGN: + case SL_PP_BITAND: + case SL_PP_XOR: + case SL_PP_BITXORASSIGN: + case SL_PP_BITXOR: + case SL_PP_OR: + case SL_PP_BITORASSIGN: + case SL_PP_BITOR: + case SL_PP_QUESTION: + case SL_PP_COLON: + case SL_PP_IDENTIFIER: + case SL_PP_UINT: + case SL_PP_FLOAT: + case SL_PP_EOF: + ctx->tokens_read++; + break; + } + } + return &ctx->tokens[pos]; +} + + static int _parse_token(struct parse_context *ctx, enum sl_pp_token token, struct parse_state *ps) { - if (ctx->input[ps->in].token == token) { + const struct sl_pp_token_info *input = _fetch_token(ctx, ps->in); + + if (input && input->token == token) { ps->in++; return 0; } @@ -392,8 +480,9 @@ _parse_id(struct parse_context *ctx, int id, struct parse_state *ps) { - if (ctx->input[ps->in].token == SL_PP_IDENTIFIER && - ctx->input[ps->in].data.identifier == id) { + const struct sl_pp_token_info *input = _fetch_token(ctx, ps->in); + + if (input && input->token == SL_PP_IDENTIFIER && input->data.identifier == id) { ps->in++; return 0; } @@ -405,8 +494,10 @@ static int _parse_identifier(struct parse_context *ctx, struct parse_state *ps) { - if (ctx->input[ps->in].token == SL_PP_IDENTIFIER) { - const char *cstr = sl_pp_context_cstr(ctx->context, ctx->input[ps->in].data.identifier); + const struct sl_pp_token_info *input = _fetch_token(ctx, ps->in); + + if (input && input->token == SL_PP_IDENTIFIER) { + const char *cstr = sl_pp_context_cstr(ctx->context, input->data.identifier); do { _emit(ctx, &ps->out, *cstr); @@ -422,8 +513,10 @@ static int _parse_float(struct parse_context *ctx, struct parse_state *ps) { - if (ctx->input[ps->in].token == SL_PP_FLOAT) { - const char *cstr = sl_pp_context_cstr(ctx->context, ctx->input[ps->in].data._float); + const struct sl_pp_token_info *input = _fetch_token(ctx, ps->in); + + if (input && input->token == SL_PP_FLOAT) { + const char *cstr = sl_pp_context_cstr(ctx->context, input->data._float); _emit(ctx, &ps->out, 1); do { @@ -440,8 +533,10 @@ static int _parse_uint(struct parse_context *ctx, struct parse_state *ps) { - if (ctx->input[ps->in].token == SL_PP_UINT) { - const char *cstr = sl_pp_context_cstr(ctx->context, ctx->input[ps->in].data._uint); + const struct sl_pp_token_info *input = _fetch_token(ctx, ps->in); + + if (input && input->token == SL_PP_UINT) { + const char *cstr = sl_pp_context_cstr(ctx->context, input->data._uint); _emit(ctx, &ps->out, 1); do { @@ -614,13 +709,14 @@ _parse_type_qualifier(struct parse_context *ctx, struct parse_state *ps) { struct parse_state p = *ps; + const struct sl_pp_token_info *input = _fetch_token(ctx, p.in); unsigned int e = _emit(ctx, &p.out, 0); int id; - if (ctx->input[p.in].token != SL_PP_IDENTIFIER) { + if (!input || input->token != SL_PP_IDENTIFIER) { return -1; } - id = ctx->input[p.in].data.identifier; + id = input->data.identifier; if (id == ctx->dict._const) { _update(ctx, e, TYPE_QUALIFIER_CONST); @@ -771,6 +867,7 @@ _parse_type_specifier_nonarray(struct parse_context *ctx, { struct parse_state p = *ps; unsigned int e = _emit(ctx, &p.out, 0); + const struct sl_pp_token_info *input; int id; if (_parse_struct_specifier(ctx, &p) == 0) { @@ -779,10 +876,11 @@ _parse_type_specifier_nonarray(struct parse_context *ctx, return 0; } - if (ctx->input[p.in].token != SL_PP_IDENTIFIER) { + input = _fetch_token(ctx, p.in); + if (!input || input->token != SL_PP_IDENTIFIER) { return -1; } - id = ctx->input[p.in].data.identifier; + id = input->data.identifier; if (id == ctx->dict._void) { _update(ctx, e, TYPE_SPECIFIER_VOID); @@ -1696,13 +1794,14 @@ static int _parse_precision(struct parse_context *ctx, struct parse_state *ps) { + const struct sl_pp_token_info *input = _fetch_token(ctx, ps->in); int id; unsigned int precision; - if (ctx->input[ps->in].token != SL_PP_IDENTIFIER) { + if (!input || input->token != SL_PP_IDENTIFIER) { return -1; } - id = ctx->input[ps->in].data.identifier; + id = input->data.identifier; if (id == ctx->dict.lowp) { precision = PRECISION_LOW; @@ -1724,13 +1823,14 @@ static int _parse_prectype(struct parse_context *ctx, struct parse_state *ps) { + const struct sl_pp_token_info *input = _fetch_token(ctx, ps->in); int id; unsigned int type; - if (ctx->input[ps->in].token != SL_PP_IDENTIFIER) { + if (!input || input->token != SL_PP_IDENTIFIER) { return -1; } - id = ctx->input[ps->in].data.identifier; + id = input->data.identifier; if (id == ctx->dict._int) { type = TYPE_SPECIFIER_INT; @@ -2607,7 +2707,6 @@ _parse_translation_unit(struct parse_context *ctx, int sl_cl_compile(struct sl_pp_context *context, - const struct sl_pp_token_info *input, unsigned int shader_type, unsigned int parsing_builtin, unsigned char **output, @@ -2619,7 +2718,6 @@ sl_cl_compile(struct sl_pp_context *context, struct parse_state ps; ctx.context = context; - ctx.input = input; ADD_NAME_STR(ctx, _void, "void"); ADD_NAME_STR(ctx, _float, "float"); @@ -2699,16 +2797,27 @@ sl_cl_compile(struct sl_pp_context *context, ctx.parsing_builtin = 1; ctx.error[0] = '\0'; + ctx.process_error = 0; + + ctx.tokens_cap = 1024; + ctx.tokens_read = 0; + ctx.tokens = malloc(ctx.tokens_cap * sizeof(struct sl_pp_token_info)); + if (!ctx.tokens) { + strncpy(error, "out of memory", cberror); + return -1; + } ps.in = 0; ps.out = 0; if (_parse_translation_unit(&ctx, &ps)) { strncpy(error, ctx.error, cberror); + free(ctx.tokens); return -1; } *output = ctx.out_buf; *cboutput = ps.out; + free(ctx.tokens); return 0; } diff --git a/src/glsl/cl/sl_cl_parse.h b/src/glsl/cl/sl_cl_parse.h index 23a0d5fee0..dd5791d590 100644 --- a/src/glsl/cl/sl_cl_parse.h +++ b/src/glsl/cl/sl_cl_parse.h @@ -30,7 +30,6 @@ int sl_cl_compile(struct sl_pp_context *context, - const struct sl_pp_token_info *input, unsigned int shader_type, unsigned int parsing_builtin, unsigned char **output, diff --git a/src/glsl/pp/sl_pp_context.c b/src/glsl/pp/sl_pp_context.c index c1cef41bce..74a9bdddfd 100644 --- a/src/glsl/pp/sl_pp_context.c +++ b/src/glsl/pp/sl_pp_context.c @@ -69,6 +69,8 @@ sl_pp_context_create(const char *input, sl_pp_purify_state_init(&context->pure, input, options); + memset(&context->process_state, 0, sizeof(context->process_state)); + return context; } @@ -80,6 +82,7 @@ sl_pp_context_destroy(struct sl_pp_context *context) sl_pp_macro_free(context->macro); free(context->getc_buf); sl_pp_token_buffer_destroy(&context->tokens); + free(context->process_state.out); free(context); } } diff --git a/src/glsl/pp/sl_pp_context.h b/src/glsl/pp/sl_pp_context.h index 5e1c563048..3eada380cd 100644 --- a/src/glsl/pp/sl_pp_context.h +++ b/src/glsl/pp/sl_pp_context.h @@ -30,6 +30,7 @@ #include "sl_pp_dict.h" #include "sl_pp_macro.h" +#include "sl_pp_process.h" #include "sl_pp_purify.h" #include "sl_pp_token_util.h" @@ -84,6 +85,8 @@ struct sl_pp_context { unsigned int getc_buf_capacity; struct sl_pp_token_buffer tokens; + + struct sl_pp_process_state process_state; }; #endif /* SL_PP_CONTEXT_H */ diff --git a/src/glsl/pp/sl_pp_define.c b/src/glsl/pp/sl_pp_define.c index e004c9f95b..808a6a0d4f 100644 --- a/src/glsl/pp/sl_pp_define.c +++ b/src/glsl/pp/sl_pp_define.c @@ -27,6 +27,7 @@ #include #include +#include "sl_pp_context.h" #include "sl_pp_process.h" #include "sl_pp_public.h" diff --git a/src/glsl/pp/sl_pp_error.c b/src/glsl/pp/sl_pp_error.c index a9eeff98ba..b628e37ce8 100644 --- a/src/glsl/pp/sl_pp_error.c +++ b/src/glsl/pp/sl_pp_error.c @@ -27,6 +27,7 @@ #include #include +#include "sl_pp_context.h" #include "sl_pp_process.h" #include "sl_pp_public.h" diff --git a/src/glsl/pp/sl_pp_extension.c b/src/glsl/pp/sl_pp_extension.c index 67b24404d4..8af5731e84 100644 --- a/src/glsl/pp/sl_pp_extension.c +++ b/src/glsl/pp/sl_pp_extension.c @@ -27,6 +27,7 @@ #include #include +#include "sl_pp_context.h" #include "sl_pp_process.h" #include "sl_pp_public.h" diff --git a/src/glsl/pp/sl_pp_line.c b/src/glsl/pp/sl_pp_line.c index 87987fc2ba..6f7e9eb562 100644 --- a/src/glsl/pp/sl_pp_line.c +++ b/src/glsl/pp/sl_pp_line.c @@ -27,6 +27,7 @@ #include #include +#include "sl_pp_context.h" #include "sl_pp_public.h" #include "sl_pp_process.h" diff --git a/src/glsl/pp/sl_pp_macro.c b/src/glsl/pp/sl_pp_macro.c index c98ab6559a..9f520b8fc5 100644 --- a/src/glsl/pp/sl_pp_macro.c +++ b/src/glsl/pp/sl_pp_macro.c @@ -28,6 +28,7 @@ #include #include #include +#include "sl_pp_context.h" #include "sl_pp_public.h" #include "sl_pp_macro.h" #include "sl_pp_process.h" diff --git a/src/glsl/pp/sl_pp_pragma.c b/src/glsl/pp/sl_pp_pragma.c index 489eb17b8e..caf4c63f65 100644 --- a/src/glsl/pp/sl_pp_pragma.c +++ b/src/glsl/pp/sl_pp_pragma.c @@ -27,6 +27,7 @@ #include #include +#include "sl_pp_context.h" #include "sl_pp_process.h" diff --git a/src/glsl/pp/sl_pp_process.c b/src/glsl/pp/sl_pp_process.c index 6dcd0ab401..563ea948e7 100644 --- a/src/glsl/pp/sl_pp_process.c +++ b/src/glsl/pp/sl_pp_process.c @@ -27,6 +27,7 @@ #include #include +#include "sl_pp_context.h" #include "sl_pp_process.h" #include "sl_pp_public.h" @@ -58,34 +59,47 @@ sl_pp_process_out(struct sl_pp_process_state *state, } int -sl_pp_process(struct sl_pp_context *context, - struct sl_pp_token_info **output) +sl_pp_process_get(struct sl_pp_context *context, + struct sl_pp_token_info *output) { - struct sl_pp_process_state state; - int found_eof = 0; - - memset(&state, 0, sizeof(state)); - - if (context->line > 1) { - struct sl_pp_token_info ti; - - ti.token = SL_PP_LINE; - ti.data.line.lineno = context->line - 1; - ti.data.line.fileno = context->file; - if (sl_pp_process_out(&state, &ti)) { - strcpy(context->error_msg, "out of memory"); - return -1; - } + if (!context->process_state.out) { + if (context->line > 1) { + struct sl_pp_token_info ti; + + ti.token = SL_PP_LINE; + ti.data.line.lineno = context->line - 1; + ti.data.line.fileno = context->file; + if (sl_pp_process_out(&context->process_state, &ti)) { + strcpy(context->error_msg, "out of memory"); + return -1; + } - ti.token = SL_PP_NEWLINE; - if (sl_pp_process_out(&state, &ti)) { - strcpy(context->error_msg, "out of memory"); - return -1; + ti.token = SL_PP_NEWLINE; + if (sl_pp_process_out(&context->process_state, &ti)) { + strcpy(context->error_msg, "out of memory"); + return -1; + } } } - while (!found_eof) { + for (;;) { struct sl_pp_token_info input; + int found_eof = 0; + + if (context->process_state.out_len) { + *output = context->process_state.out[0]; + + if (context->process_state.out_len > 1) { + unsigned int i; + + for (i = 1; i < context->process_state.out_len; i++) { + context->process_state.out[i - 1] = context->process_state.out[i]; + } + } + context->process_state.out_len--; + + return 0; + } if (sl_pp_token_buffer_skip_white(&context->tokens, &input)) { return -1; @@ -101,7 +115,7 @@ sl_pp_process(struct sl_pp_context *context, int found_eol = 0; struct sl_pp_token_info endof; struct sl_pp_token_peek peek; - int result; + int result = 0; /* Directive name. */ name = input.data.identifier; @@ -166,17 +180,17 @@ sl_pp_process(struct sl_pp_context *context, sl_pp_process_error(context, peek.tokens, 0, peek.size - 1); result = -1; } else if (name == context->dict.extension) { - result = sl_pp_process_extension(context, peek.tokens, 0, peek.size - 1, &state); + result = sl_pp_process_extension(context, peek.tokens, 0, peek.size - 1, &context->process_state); } else if (name == context->dict.line) { struct sl_pp_token_buffer buffer; result = sl_pp_token_peek_to_buffer(&peek, &buffer); if (result == 0) { - result = sl_pp_process_line(context, &buffer, &state); + result = sl_pp_process_line(context, &buffer, &context->process_state); sl_pp_token_buffer_destroy(&buffer); } } else if (name == context->dict.pragma) { - result = sl_pp_process_pragma(context, peek.tokens, 0, peek.size - 1, &state); + result = sl_pp_process_pragma(context, peek.tokens, 0, peek.size - 1, &context->process_state); } else if (name == context->dict.undef) { result = sl_pp_process_undef(context, peek.tokens, 0, peek.size - 1); } else { @@ -192,7 +206,7 @@ sl_pp_process(struct sl_pp_context *context, return result; } - if (sl_pp_process_out(&state, &endof)) { + if (sl_pp_process_out(&context->process_state, &endof)) { strcpy(context->error_msg, "out of memory"); return -1; } @@ -202,7 +216,7 @@ sl_pp_process(struct sl_pp_context *context, case SL_PP_NEWLINE: /* Empty directive. */ - if (sl_pp_process_out(&state, &input)) { + if (sl_pp_process_out(&context->process_state, &input)) { strcpy(context->error_msg, "out of memory"); return -1; } @@ -211,7 +225,7 @@ sl_pp_process(struct sl_pp_context *context, case SL_PP_EOF: /* Empty directive. */ - if (sl_pp_process_out(&state, &input)) { + if (sl_pp_process_out(&context->process_state, &input)) { strcpy(context->error_msg, "out of memory"); return -1; } @@ -239,7 +253,7 @@ sl_pp_process(struct sl_pp_context *context, case SL_PP_NEWLINE: /* Preserve newline just for the sake of line numbering. */ - if (sl_pp_process_out(&state, &input)) { + if (sl_pp_process_out(&context->process_state, &input)) { strcpy(context->error_msg, "out of memory"); return -1; } @@ -248,7 +262,7 @@ sl_pp_process(struct sl_pp_context *context, break; case SL_PP_EOF: - if (sl_pp_process_out(&state, &input)) { + if (sl_pp_process_out(&context->process_state, &input)) { strcpy(context->error_msg, "out of memory"); return -1; } @@ -258,7 +272,7 @@ sl_pp_process(struct sl_pp_context *context, case SL_PP_IDENTIFIER: sl_pp_token_buffer_unget(&context->tokens, &input); - if (sl_pp_macro_expand(context, &context->tokens, NULL, &state, + if (sl_pp_macro_expand(context, &context->tokens, NULL, &context->process_state, context->if_value ? sl_pp_macro_expand_normal : sl_pp_macro_expand_mute)) { return -1; } @@ -266,7 +280,7 @@ sl_pp_process(struct sl_pp_context *context, default: if (context->if_value) { - if (sl_pp_process_out(&state, &input)) { + if (sl_pp_process_out(&context->process_state, &input)) { strcpy(context->error_msg, "out of memory"); return -1; } @@ -274,13 +288,37 @@ sl_pp_process(struct sl_pp_context *context, } } } - } - if (context->if_ptr != SL_PP_MAX_IF_NESTING) { - strcpy(context->error_msg, "expected `#endif' directive"); - return -1; + if (found_eof) { + if (context->if_ptr != SL_PP_MAX_IF_NESTING) { + strcpy(context->error_msg, "expected `#endif' directive"); + return -1; + } + } } +} - *output = state.out; - return 0; +int +sl_pp_process(struct sl_pp_context *context, + struct sl_pp_token_info **output) +{ + struct sl_pp_process_state state; + + memset(&state, 0, sizeof(state)); + for (;;) { + struct sl_pp_token_info input; + + if (sl_pp_process_get(context, &input)) { + free(state.out); + return -1; + } + if (sl_pp_process_out(&state, &input)) { + free(state.out); + return -1; + } + if (input.token == SL_PP_EOF) { + *output = state.out; + return 0; + } + } } diff --git a/src/glsl/pp/sl_pp_process.h b/src/glsl/pp/sl_pp_process.h index 31defd911a..fe6ff0d464 100644 --- a/src/glsl/pp/sl_pp_process.h +++ b/src/glsl/pp/sl_pp_process.h @@ -28,11 +28,12 @@ #ifndef SL_PP_PROCESS_H #define SL_PP_PROCESS_H -#include "sl_pp_context.h" #include "sl_pp_macro.h" #include "sl_pp_token.h" +struct sl_pp_context; + struct sl_pp_process_state { struct sl_pp_token_info *out; unsigned int out_len; diff --git a/src/glsl/pp/sl_pp_public.h b/src/glsl/pp/sl_pp_public.h index 309a70c07f..12528d6f8d 100644 --- a/src/glsl/pp/sl_pp_public.h +++ b/src/glsl/pp/sl_pp_public.h @@ -73,6 +73,10 @@ int sl_pp_version(struct sl_pp_context *context, unsigned int *version); +int +sl_pp_process_get(struct sl_pp_context *context, + struct sl_pp_token_info *output); + int sl_pp_process(struct sl_pp_context *context, struct sl_pp_token_info **output); -- cgit v1.2.3