/* processes texture.Sample(sampler, texcoord) */ static bool gl_write_texture_code(struct gl_shader_parser *glsp, struct cf_token **p_token, struct shader_var *var) { struct cf_parser *cfp = &glsp->parser.cfp; bool written = false; cfp->cur_token = *p_token; if (!next_token(cfp)) return false; if (!token_is(cfp, ".")) return false; if (!next_token(cfp)) return false; if (token_is(cfp, "Sample")) written = gl_write_texture_call(glsp, var, "texture"); else if (token_is(cfp, "SampleBias")) written = gl_write_texture_call(glsp, var, "texture"); else if (token_is(cfp, "SampleGrad")) written = gl_write_texture_call(glsp, var, "textureGrad"); else if (token_is(cfp, "SampleLevel")) written = gl_write_texture_call(glsp, var, "textureLod"); if (!written) return false; if (!next_token(cfp)) return false; gl_write_function_contents(glsp, &cfp->cur_token, ")"); dstr_cat(&glsp->gl_string, ")"); *p_token = cfp->cur_token; return true; }
/* For example skips commas between function arguments */ void skip_token(int token_type) { token = get_token(); if ((token_type != TOKEN_RROUND_BRACKET) && token_is(token, TOKEN_RROUND_BRACKET)) { my_exit_error(E_SEMANTIC_TYPES, 20); } if (token_is(token, TOKEN_COMMA) && (token_type != TOKEN_COMMA)) { my_exit_error(E_SEMANTIC_TYPES, 19); } if ((token_type == TOKEN_RROUND_BRACKET) && token_is_operand(token)) { my_exit_error(E_SYNTAX, 6); } if (token->type != token_type) { my_exit_error(E_SYNTAX, 7); } }
void check_expr_integrity(const TToken *tok, int *last_type) { switch (*last_type) { case TOKEN_EOF: if (!token_is_operand(tok) && !token_is(tok, TOKEN_LROUND_BRACKET)) { my_exit_error(E_SYNTAX, 14); } break; case TOKEN_INT_VALUE: case TOKEN_DOUBLE_VALUE: case TOKEN_STRING_VALUE: case TOKEN_IDENTIFIER: if (!token_is_operator(tok) && !token_is(tok, TOKEN_RROUND_BRACKET)) { my_exit_error(E_SYNTAX, 15); } break; case TOKEN_LROUND_BRACKET: if (!token_is_operand(tok) && !token_is(tok, TOKEN_LROUND_BRACKET)) { my_exit_error(E_SYNTAX, 16); } break; case TOKEN_RROUND_BRACKET: if (!token_is_operator(tok) && !token_is(tok, TOKEN_RROUND_BRACKET)) { my_exit_error(E_SYNTAX, 17); } break; case TOKEN_MUL: case TOKEN_DIV: case TOKEN_ADD: case TOKEN_SUB: case TOKEN_EQUAL: case TOKEN_NOT_EQUAL: case TOKEN_GREATER: case TOKEN_GREATER_EQUAL: case TOKEN_LESS: case TOKEN_LESS_EQUAL: if (!(token_is_operand(tok)) && !token_is(tok, TOKEN_LROUND_BRACKET)) { my_exit_error(E_SYNTAX, 18); } } *last_type = tok->type; }
static inline bool gl_write_texture_call(struct gl_shader_parser *glsp, struct shader_var *var, const char *call) { struct cf_parser *cfp = &glsp->parser.cfp; size_t sampler_id = (size_t)-1; if (!next_token(cfp)) return false; if (!token_is(cfp, "(")) return false; if (!next_token(cfp)) return false; sampler_id = sp_getsampler(glsp, cfp->cur_token); if (sampler_id == (size_t)-1) return false; if (!next_token(cfp)) return false; if (!token_is(cfp, ",")) return false; var->gl_sampler_id = sampler_id; dstr_cat(&glsp->gl_string, call); dstr_cat(&glsp->gl_string, "("); dstr_cat(&glsp->gl_string, var->name); dstr_cat(&glsp->gl_string, ", "); return true; }
static bool gl_write_saturate(struct gl_shader_parser *glsp, struct cf_token **p_token) { struct cf_parser *cfp = &glsp->parser.cfp; cfp->cur_token = *p_token; if (!next_token(cfp)) return false; if (!token_is(cfp, "(")) return false; dstr_cat(&glsp->gl_string, "clamp"); gl_write_function_contents(glsp, &cfp->cur_token, ")"); dstr_cat(&glsp->gl_string, ", 0.0, 1.0)"); *p_token = cfp->cur_token; return true; }
/* Returns next function arguments */ TVariable *get_next_para(const int operand_type) { TVariable *new_var; token = get_token(); if (!token_is_operand(token)) { if (token_is(token, TOKEN_RROUND_BRACKET)) { my_exit_error(E_SEMANTIC_TYPES, 12); } else { my_exit_error(E_SYNTAX, 8); } } new_var = find_var(token, 1); if (operation_table[operand_type][new_var->var_type] == ER) { my_exit_error(E_SEMANTIC_TYPES, 5); } return new_var; }
void infix_2_postfix() { TToken *token_stack; int bracket_counter; int last_token_type = TOKEN_EOF; bracket_counter = 1; token = get_token(); while ((token->type != TOKEN_SEMICOLON) && (bracket_counter)) { check_expr_integrity(token, &last_token_type); switch (token->type) { case TOKEN_INT_VALUE: case TOKEN_DOUBLE_VALUE: case TOKEN_STRING_VALUE: case TOKEN_IDENTIFIER: stack_push(postfix_output_stack, save_tok()); break; case TOKEN_LROUND_BRACKET: bracket_counter++; stack_push(in_out_stack, save_tok()); break; case TOKEN_RROUND_BRACKET: bracket_counter--; if (!bracket_counter) { unget_token(token); break; } token_stack = stack_top(in_out_stack); stack_pop(in_out_stack); while (!token_is(token_stack, TOKEN_LROUND_BRACKET)) { stack_push(postfix_output_stack, token_stack); token_stack = stack_top(in_out_stack); stack_pop(in_out_stack); } break; case TOKEN_MUL: case TOKEN_DIV: case TOKEN_ADD: case TOKEN_SUB: case TOKEN_EQUAL: case TOKEN_NOT_EQUAL: case TOKEN_GREATER: case TOKEN_GREATER_EQUAL: case TOKEN_LESS: case TOKEN_LESS_EQUAL: token_stack = stack_top(in_out_stack); if (stack_empty(in_out_stack) || stack_lower_prio(token_stack)) { stack_push(in_out_stack, save_tok()); } else { while (!stack_empty(in_out_stack) && !stack_lower_prio(token_stack)) { stack_push(postfix_output_stack, token_stack); stack_pop(in_out_stack); token_stack = stack_top(in_out_stack); } stack_push(in_out_stack, save_tok()); } break; } token = get_token(); } transfer_rest_of_in_out_stack(); #ifdef DEBUG_MODE after_infix(); #endif unget_token(token); }