Remove remnants of the old glsl compiler.
This commit is contained in:
parent
a4b10a5614
commit
284ce20901
12
Makefile
12
Makefile
|
@ -230,7 +230,10 @@ MAIN_FILES = \
|
|||
$(DIRECTORY)/src/glsl/Makefile.template \
|
||||
$(DIRECTORY)/src/glsl/SConscript \
|
||||
$(DIRECTORY)/src/glsl/*/Makefile \
|
||||
$(DIRECTORY)/src/glsl/*/*.[ch] \
|
||||
$(DIRECTORY)/src/glsl/*.[ch] \
|
||||
$(DIRECTORY)/src/glsl/*.[cly]pp \
|
||||
$(DIRECTORY)/src/glsl/README \
|
||||
$(DIRECTORY)/src/glsl/glcpp/README \
|
||||
$(DIRECTORY)/src/Makefile \
|
||||
$(DIRECTORY)/src/mesa/Makefile* \
|
||||
$(DIRECTORY)/src/mesa/sources.mak \
|
||||
|
@ -240,16 +243,13 @@ MAIN_FILES = \
|
|||
$(DIRECTORY)/src/mesa/depend \
|
||||
$(MAIN_ES_FILES) \
|
||||
$(DIRECTORY)/src/mesa/main/*.[chS] \
|
||||
$(DIRECTORY)/src/mesa/main/*.cpp \
|
||||
$(DIRECTORY)/src/mesa/main/descrip.mms \
|
||||
$(DIRECTORY)/src/mesa/math/*.[ch] \
|
||||
$(DIRECTORY)/src/mesa/math/descrip.mms \
|
||||
$(DIRECTORY)/src/mesa/program/*.[chly] \
|
||||
$(DIRECTORY)/src/mesa/program/Makefile \
|
||||
$(DIRECTORY)/src/mesa/program/descrip.mms \
|
||||
$(DIRECTORY)/src/mesa/slang/*.[ch] \
|
||||
$(DIRECTORY)/src/mesa/slang/descrip.mms \
|
||||
$(DIRECTORY)/src/mesa/slang/library/*.gc \
|
||||
$(DIRECTORY)/src/mesa/slang/library/Makefile \
|
||||
$(DIRECTORY)/src/mesa/swrast/*.[ch] \
|
||||
$(DIRECTORY)/src/mesa/swrast/descrip.mms \
|
||||
$(DIRECTORY)/src/mesa/swrast_setup/*.[ch] \
|
||||
|
@ -278,8 +278,6 @@ MAIN_FILES = \
|
|||
$(DIRECTORY)/src/mesa/drivers/x11/Makefile \
|
||||
$(DIRECTORY)/src/mesa/drivers/x11/descrip.mms \
|
||||
$(DIRECTORY)/src/mesa/drivers/x11/*.[ch] \
|
||||
$(DIRECTORY)/src/mesa/drivers/glslcompiler/Makefile \
|
||||
$(DIRECTORY)/src/mesa/drivers/glslcompiler/glslcompiler.c \
|
||||
$(DIRECTORY)/src/mesa/ppc/*.[ch] \
|
||||
$(DIRECTORY)/src/mesa/sparc/*.[chS] \
|
||||
$(DIRECTORY)/src/mesa/x86/Makefile \
|
||||
|
|
|
@ -1,13 +0,0 @@
|
|||
#src/glsl/cl/Makefile
|
||||
|
||||
TOP = ../../..
|
||||
|
||||
include $(TOP)/configs/current
|
||||
|
||||
LIBNAME = glslcl
|
||||
|
||||
C_SOURCES = \
|
||||
sl_cl_parse.c
|
||||
|
||||
include ../Makefile.template
|
||||
|
File diff suppressed because it is too large
Load Diff
|
@ -1,42 +0,0 @@
|
|||
/**************************************************************************
|
||||
*
|
||||
* Copyright 2009 VMware, Inc.
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sub license, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the
|
||||
* next paragraph) shall be included in all copies or substantial portions
|
||||
* of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
|
||||
* IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
|
||||
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
**************************************************************************/
|
||||
|
||||
#ifndef SL_CL_PARSE_H
|
||||
#define SL_CL_PARSE_H
|
||||
|
||||
struct sl_pp_context;
|
||||
|
||||
int
|
||||
sl_cl_compile(struct sl_pp_context *context,
|
||||
unsigned int shader_type,
|
||||
unsigned int parsing_builtin,
|
||||
unsigned char **output,
|
||||
unsigned int *cboutput,
|
||||
char *error,
|
||||
unsigned int cberror);
|
||||
|
||||
#endif /* SL_CL_PARSE_H */
|
|
@ -1,27 +0,0 @@
|
|||
#src/glsl/pp/Makefile
|
||||
|
||||
TOP = ../../..
|
||||
|
||||
include $(TOP)/configs/current
|
||||
|
||||
LIBNAME = glslpp
|
||||
|
||||
C_SOURCES = \
|
||||
sl_pp_context.c \
|
||||
sl_pp_define.c \
|
||||
sl_pp_dict.c \
|
||||
sl_pp_error.c \
|
||||
sl_pp_expression.c \
|
||||
sl_pp_extension.c \
|
||||
sl_pp_if.c \
|
||||
sl_pp_line.c \
|
||||
sl_pp_macro.c \
|
||||
sl_pp_pragma.c \
|
||||
sl_pp_process.c \
|
||||
sl_pp_purify.c \
|
||||
sl_pp_token.c \
|
||||
sl_pp_token_util.c \
|
||||
sl_pp_version.c
|
||||
|
||||
include ../Makefile.template
|
||||
|
|
@ -1,183 +0,0 @@
|
|||
/**************************************************************************
|
||||
*
|
||||
* Copyright 2009 VMware, Inc.
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sub license, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the
|
||||
* next paragraph) shall be included in all copies or substantial portions
|
||||
* of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
|
||||
* IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
|
||||
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
**************************************************************************/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "sl_pp_macro.h"
|
||||
#include "sl_pp_public.h"
|
||||
#include "sl_pp_context.h"
|
||||
|
||||
|
||||
struct sl_pp_context *
|
||||
sl_pp_context_create(const char *input,
|
||||
const struct sl_pp_purify_options *options)
|
||||
{
|
||||
struct sl_pp_context *context;
|
||||
|
||||
context = calloc(1, sizeof(struct sl_pp_context));
|
||||
if (!context) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (sl_pp_dict_init(context)) {
|
||||
sl_pp_context_destroy(context);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
context->getc_buf_capacity = 64;
|
||||
context->getc_buf = malloc(context->getc_buf_capacity * sizeof(char));
|
||||
if (!context->getc_buf) {
|
||||
sl_pp_context_destroy(context);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (sl_pp_token_buffer_init(&context->tokens, context)) {
|
||||
sl_pp_context_destroy(context);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
context->macro_tail = &context->macro;
|
||||
context->if_ptr = SL_PP_MAX_IF_NESTING;
|
||||
context->if_value = 1;
|
||||
memset(context->error_msg, 0, sizeof(context->error_msg));
|
||||
context->error_line = 1;
|
||||
context->line = 1;
|
||||
context->file = 0;
|
||||
|
||||
sl_pp_purify_state_init(&context->pure, input, options);
|
||||
|
||||
memset(&context->process_state, 0, sizeof(context->process_state));
|
||||
|
||||
return context;
|
||||
}
|
||||
|
||||
void
|
||||
sl_pp_context_destroy(struct sl_pp_context *context)
|
||||
{
|
||||
if (context) {
|
||||
free(context->cstr_pool);
|
||||
sl_pp_macro_free(context->macro);
|
||||
free(context->getc_buf);
|
||||
sl_pp_token_buffer_destroy(&context->tokens);
|
||||
free(context->process_state.out);
|
||||
free(context);
|
||||
}
|
||||
}
|
||||
|
||||
const char *
|
||||
sl_pp_context_error_message(const struct sl_pp_context *context)
|
||||
{
|
||||
return context->error_msg;
|
||||
}
|
||||
|
||||
void
|
||||
sl_pp_context_error_position(const struct sl_pp_context *context,
|
||||
unsigned int *file,
|
||||
unsigned int *line)
|
||||
{
|
||||
if (file) {
|
||||
*file = 0;
|
||||
}
|
||||
if (line) {
|
||||
*line = context->error_line;
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
sl_pp_context_add_predefined(struct sl_pp_context *context,
|
||||
const char *name,
|
||||
const char *value)
|
||||
{
|
||||
struct sl_pp_predefined pre;
|
||||
|
||||
if (context->num_predefined == SL_PP_MAX_PREDEFINED) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
pre.name = sl_pp_context_add_unique_str(context, name);
|
||||
if (pre.name == -1) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
pre.value = sl_pp_context_add_unique_str(context, value);
|
||||
if (pre.value == -1) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
context->predefined[context->num_predefined++] = pre;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
sl_pp_context_add_unique_str(struct sl_pp_context *context,
|
||||
const char *str)
|
||||
{
|
||||
unsigned int size;
|
||||
unsigned int offset = 0;
|
||||
|
||||
size = strlen(str) + 1;
|
||||
|
||||
/* Find out if this is a unique string. */
|
||||
while (offset < context->cstr_pool_len) {
|
||||
const char *str2;
|
||||
unsigned int size2;
|
||||
|
||||
str2 = &context->cstr_pool[offset];
|
||||
size2 = strlen(str2) + 1;
|
||||
if (size == size2 && !memcmp(str, str2, size - 1)) {
|
||||
return offset;
|
||||
}
|
||||
|
||||
offset += size2;
|
||||
}
|
||||
|
||||
if (context->cstr_pool_len + size > context->cstr_pool_max) {
|
||||
context->cstr_pool_max = (context->cstr_pool_len + size + 0xffff) & ~0xffff;
|
||||
context->cstr_pool = realloc(context->cstr_pool, context->cstr_pool_max);
|
||||
}
|
||||
|
||||
if (!context->cstr_pool) {
|
||||
strcpy(context->error_msg, "out of memory");
|
||||
return -1;
|
||||
}
|
||||
|
||||
offset = context->cstr_pool_len;
|
||||
memcpy(&context->cstr_pool[offset], str, size);
|
||||
context->cstr_pool_len += size;
|
||||
|
||||
return offset;
|
||||
}
|
||||
|
||||
const char *
|
||||
sl_pp_context_cstr(const struct sl_pp_context *context,
|
||||
int offset)
|
||||
{
|
||||
if (offset == -1) {
|
||||
return NULL;
|
||||
}
|
||||
return &context->cstr_pool[offset];
|
||||
}
|
|
@ -1,99 +0,0 @@
|
|||
/**************************************************************************
|
||||
*
|
||||
* Copyright 2009 VMware, Inc.
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sub license, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the
|
||||
* next paragraph) shall be included in all copies or substantial portions
|
||||
* of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
|
||||
* IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
|
||||
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
**************************************************************************/
|
||||
|
||||
#ifndef SL_PP_CONTEXT_H
|
||||
#define SL_PP_CONTEXT_H
|
||||
|
||||
#include "sl_pp_dict.h"
|
||||
#include "sl_pp_process.h"
|
||||
#include "sl_pp_purify.h"
|
||||
#include "sl_pp_token_util.h"
|
||||
|
||||
|
||||
#define SL_PP_MAX_IF_NESTING 64
|
||||
|
||||
#define SL_PP_MAX_ERROR_MSG 1024
|
||||
|
||||
#define SL_PP_MAX_EXTENSIONS 16
|
||||
|
||||
#define SL_PP_MAX_PREDEFINED 16
|
||||
|
||||
struct sl_pp_extension {
|
||||
int name; /*< GL_VENDOR_extension_name */
|
||||
};
|
||||
|
||||
struct sl_pp_predefined {
|
||||
int name;
|
||||
int value;
|
||||
};
|
||||
|
||||
union sl_pp_if_state {
|
||||
struct {
|
||||
unsigned int condition:1;
|
||||
unsigned int went_thru_else:1;
|
||||
unsigned int had_true_cond:1;
|
||||
} u;
|
||||
unsigned int value;
|
||||
};
|
||||
|
||||
struct sl_pp_context {
|
||||
char *cstr_pool;
|
||||
unsigned int cstr_pool_max;
|
||||
unsigned int cstr_pool_len;
|
||||
struct sl_pp_dict dict;
|
||||
|
||||
struct sl_pp_macro *macro;
|
||||
struct sl_pp_macro **macro_tail;
|
||||
|
||||
struct sl_pp_extension extensions[SL_PP_MAX_EXTENSIONS];
|
||||
unsigned int num_extensions;
|
||||
|
||||
struct sl_pp_predefined predefined[SL_PP_MAX_PREDEFINED];
|
||||
unsigned int num_predefined;
|
||||
|
||||
union sl_pp_if_state if_stack[SL_PP_MAX_IF_NESTING];
|
||||
unsigned int if_ptr;
|
||||
unsigned int if_value;
|
||||
|
||||
char error_msg[SL_PP_MAX_ERROR_MSG];
|
||||
unsigned int error_line;
|
||||
|
||||
unsigned int line;
|
||||
unsigned int file;
|
||||
|
||||
struct sl_pp_purify_state pure;
|
||||
|
||||
char *getc_buf;
|
||||
unsigned int getc_buf_size;
|
||||
unsigned int getc_buf_capacity;
|
||||
|
||||
struct sl_pp_token_buffer tokens;
|
||||
|
||||
struct sl_pp_process_state process_state;
|
||||
};
|
||||
|
||||
#endif /* SL_PP_CONTEXT_H */
|
|
@ -1,240 +0,0 @@
|
|||
/**************************************************************************
|
||||
*
|
||||
* Copyright 2009 VMware, Inc.
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sub license, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the
|
||||
* next paragraph) shall be included in all copies or substantial portions
|
||||
* of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
|
||||
* IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
|
||||
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
**************************************************************************/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "sl_pp_context.h"
|
||||
#include "sl_pp_macro.h"
|
||||
#include "sl_pp_process.h"
|
||||
#include "sl_pp_public.h"
|
||||
#include "sl_pp_token.h"
|
||||
|
||||
|
||||
static void
|
||||
skip_whitespace(const struct sl_pp_token_info *input,
|
||||
unsigned int *first,
|
||||
unsigned int last)
|
||||
{
|
||||
while (*first < last && input[*first].token == SL_PP_WHITESPACE) {
|
||||
(*first)++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
_parse_formal_args(struct sl_pp_context *context,
|
||||
const struct sl_pp_token_info *input,
|
||||
unsigned int *first,
|
||||
unsigned int last,
|
||||
struct sl_pp_macro *macro)
|
||||
{
|
||||
struct sl_pp_macro_formal_arg **arg;
|
||||
|
||||
macro->num_args = 0;
|
||||
|
||||
skip_whitespace(input, first, last);
|
||||
if (*first < last) {
|
||||
if (input[*first].token == SL_PP_RPAREN) {
|
||||
(*first)++;
|
||||
return 0;
|
||||
}
|
||||
} else {
|
||||
strcpy(context->error_msg, "expected either macro formal argument or `)'");
|
||||
return -1;
|
||||
}
|
||||
|
||||
arg = ¯o->arg;
|
||||
|
||||
for (;;) {
|
||||
if (*first < last && input[*first].token != SL_PP_IDENTIFIER) {
|
||||
strcpy(context->error_msg, "expected macro formal argument");
|
||||
return -1;
|
||||
}
|
||||
|
||||
*arg = malloc(sizeof(struct sl_pp_macro_formal_arg));
|
||||
if (!*arg) {
|
||||
strcpy(context->error_msg, "out of memory");
|
||||
return -1;
|
||||
}
|
||||
|
||||
(**arg).name = input[*first].data.identifier;
|
||||
(*first)++;
|
||||
|
||||
(**arg).next = NULL;
|
||||
arg = &(**arg).next;
|
||||
|
||||
macro->num_args++;
|
||||
|
||||
skip_whitespace(input, first, last);
|
||||
if (*first < last) {
|
||||
if (input[*first].token == SL_PP_COMMA) {
|
||||
(*first)++;
|
||||
skip_whitespace(input, first, last);
|
||||
} else if (input[*first].token == SL_PP_RPAREN) {
|
||||
(*first)++;
|
||||
return 0;
|
||||
} else {
|
||||
strcpy(context->error_msg, "expected either `,' or `)'");
|
||||
return -1;
|
||||
}
|
||||
} else {
|
||||
strcpy(context->error_msg, "expected either `,' or `)'");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
/* Should not gete here. */
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
sl_pp_process_define(struct sl_pp_context *context,
|
||||
const struct sl_pp_token_info *input,
|
||||
unsigned int first,
|
||||
unsigned int last)
|
||||
{
|
||||
int macro_name = -1;
|
||||
struct sl_pp_macro *macro;
|
||||
unsigned int i;
|
||||
unsigned int body_len;
|
||||
unsigned int j;
|
||||
|
||||
if (first < last && input[first].token == SL_PP_IDENTIFIER) {
|
||||
macro_name = input[first].data.identifier;
|
||||
first++;
|
||||
}
|
||||
if (macro_name == -1) {
|
||||
strcpy(context->error_msg, "expected macro name");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Check for reserved macro names */
|
||||
{
|
||||
const char *name = sl_pp_context_cstr(context, macro_name);
|
||||
|
||||
if (strstr(name, "__")) {
|
||||
strcpy(context->error_msg, "macro names containing `__' are reserved");
|
||||
return 1;
|
||||
}
|
||||
if (name[0] == 'G' && name[1] == 'L' && name[2] == '_') {
|
||||
strcpy(context->error_msg, "macro names prefixed with `GL_' are reserved");
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
for (macro = context->macro; macro; macro = macro->next) {
|
||||
if (macro->name == macro_name) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!macro) {
|
||||
macro = sl_pp_macro_new();
|
||||
if (!macro) {
|
||||
strcpy(context->error_msg, "out of memory");
|
||||
return -1;
|
||||
}
|
||||
|
||||
*context->macro_tail = macro;
|
||||
context->macro_tail = ¯o->next;
|
||||
} else {
|
||||
sl_pp_macro_reset(macro);
|
||||
}
|
||||
|
||||
macro->name = macro_name;
|
||||
|
||||
/*
|
||||
* If there is no whitespace between macro name and left paren, a macro
|
||||
* formal argument list follows. This is the only place where the presence
|
||||
* of a whitespace matters and it's the only reason why we are dealing
|
||||
* with whitespace at this level.
|
||||
*/
|
||||
if (first < last && input[first].token == SL_PP_LPAREN) {
|
||||
first++;
|
||||
if (_parse_formal_args(context, input, &first, last, macro)) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
/* Calculate body size, trim out whitespace, make room for EOF. */
|
||||
body_len = 1;
|
||||
for (i = first; i < last; i++) {
|
||||
if (input[i].token != SL_PP_WHITESPACE) {
|
||||
body_len++;
|
||||
}
|
||||
}
|
||||
|
||||
macro->body = malloc(sizeof(struct sl_pp_token_info) * body_len);
|
||||
if (!macro->body) {
|
||||
strcpy(context->error_msg, "out of memory");
|
||||
return -1;
|
||||
}
|
||||
|
||||
for (j = 0, i = first; i < last; i++) {
|
||||
if (input[i].token != SL_PP_WHITESPACE) {
|
||||
macro->body[j++] = input[i];
|
||||
}
|
||||
}
|
||||
macro->body[j++].token = SL_PP_EOF;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
sl_pp_process_undef(struct sl_pp_context *context,
|
||||
const struct sl_pp_token_info *input,
|
||||
unsigned int first,
|
||||
unsigned int last)
|
||||
{
|
||||
int macro_name = -1;
|
||||
struct sl_pp_macro **pmacro;
|
||||
struct sl_pp_macro *macro;
|
||||
|
||||
if (first < last && input[first].token == SL_PP_IDENTIFIER) {
|
||||
macro_name = input[first].data.identifier;
|
||||
}
|
||||
if (macro_name == -1) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
for (pmacro = &context->macro; *pmacro; pmacro = &(**pmacro).next) {
|
||||
if ((**pmacro).name == macro_name) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!*pmacro) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
macro = *pmacro;
|
||||
*pmacro = macro->next;
|
||||
macro->next = NULL;
|
||||
sl_pp_macro_free(macro);
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -1,85 +0,0 @@
|
|||
/**************************************************************************
|
||||
*
|
||||
* Copyright 2009 VMware, Inc.
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sub license, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the
|
||||
* next paragraph) shall be included in all copies or substantial portions
|
||||
* of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
|
||||
* IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
|
||||
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
**************************************************************************/
|
||||
|
||||
#include "sl_pp_public.h"
|
||||
#include "sl_pp_context.h"
|
||||
#include "sl_pp_dict.h"
|
||||
|
||||
|
||||
#define ADD_NAME_STR(CTX, NAME, STR)\
|
||||
do {\
|
||||
(CTX)->dict.NAME = sl_pp_context_add_unique_str((CTX), (STR));\
|
||||
if ((CTX)->dict.NAME == -1) {\
|
||||
return -1;\
|
||||
}\
|
||||
} while (0)
|
||||
|
||||
#define ADD_NAME(CTX, NAME) ADD_NAME_STR(CTX, NAME, #NAME)
|
||||
|
||||
|
||||
int
|
||||
sl_pp_dict_init(struct sl_pp_context *context)
|
||||
{
|
||||
ADD_NAME(context, all);
|
||||
|
||||
ADD_NAME(context, require);
|
||||
ADD_NAME(context, enable);
|
||||
ADD_NAME(context, warn);
|
||||
ADD_NAME(context, disable);
|
||||
|
||||
ADD_NAME(context, defined);
|
||||
|
||||
ADD_NAME_STR(context, ___LINE__, "__LINE__");
|
||||
ADD_NAME_STR(context, ___FILE__, "__FILE__");
|
||||
ADD_NAME_STR(context, ___VERSION__, "__VERSION__");
|
||||
|
||||
ADD_NAME(context, optimize);
|
||||
ADD_NAME(context, debug);
|
||||
|
||||
ADD_NAME(context, off);
|
||||
ADD_NAME(context, on);
|
||||
|
||||
ADD_NAME(context, define);
|
||||
ADD_NAME(context, elif);
|
||||
ADD_NAME_STR(context, _else, "else");
|
||||
ADD_NAME(context, endif);
|
||||
ADD_NAME(context, error);
|
||||
ADD_NAME(context, extension);
|
||||
ADD_NAME_STR(context, _if, "if");
|
||||
ADD_NAME(context, ifdef);
|
||||
ADD_NAME(context, ifndef);
|
||||
ADD_NAME(context, line);
|
||||
ADD_NAME(context, pragma);
|
||||
ADD_NAME(context, undef);
|
||||
|
||||
ADD_NAME(context, version);
|
||||
|
||||
ADD_NAME_STR(context, _0, "0");
|
||||
ADD_NAME_STR(context, _1, "1");
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -1,77 +0,0 @@
|
|||
/**************************************************************************
|
||||
*
|
||||
* Copyright 2009 VMware, Inc.
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sub license, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the
|
||||
* next paragraph) shall be included in all copies or substantial portions
|
||||
* of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
|
||||
* IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
|
||||
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
**************************************************************************/
|
||||
|
||||
#ifndef SL_PP_DICT_H
|
||||
#define SL_PP_DICT_H
|
||||
|
||||
|
||||
struct sl_pp_context;
|
||||
|
||||
struct sl_pp_dict {
|
||||
int all;
|
||||
|
||||
int require;
|
||||
int enable;
|
||||
int warn;
|
||||
int disable;
|
||||
|
||||
int defined;
|
||||
|
||||
int ___LINE__;
|
||||
int ___FILE__;
|
||||
int ___VERSION__;
|
||||
|
||||
int optimize;
|
||||
int debug;
|
||||
|
||||
int off;
|
||||
int on;
|
||||
|
||||
int define;
|
||||
int elif;
|
||||
int _else;
|
||||
int endif;
|
||||
int error;
|
||||
int extension;
|
||||
int _if;
|
||||
int ifdef;
|
||||
int ifndef;
|
||||
int line;
|
||||
int pragma;
|
||||
int undef;
|
||||
|
||||
int version;
|
||||
|
||||
int _0;
|
||||
int _1;
|
||||
};
|
||||
|
||||
|
||||
int
|
||||
sl_pp_dict_init(struct sl_pp_context *context);
|
||||
|
||||
#endif /* SL_PP_DICT_H */
|
|
@ -1,271 +0,0 @@
|
|||
/**************************************************************************
|
||||
*
|
||||
* Copyright 2009 VMware, Inc.
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sub license, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the
|
||||
* next paragraph) shall be included in all copies or substantial portions
|
||||
* of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
|
||||
* IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
|
||||
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
**************************************************************************/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "sl_pp_context.h"
|
||||
#include "sl_pp_process.h"
|
||||
#include "sl_pp_public.h"
|
||||
#include "sl_pp_token.h"
|
||||
|
||||
|
||||
void
|
||||
sl_pp_process_error(struct sl_pp_context *context,
|
||||
const struct sl_pp_token_info *input,
|
||||
unsigned int first,
|
||||
unsigned int last)
|
||||
{
|
||||
unsigned int out_len = 0;
|
||||
unsigned int i;
|
||||
|
||||
for (i = first; i < last; i++) {
|
||||
const char *s = NULL;
|
||||
char buf[2];
|
||||
|
||||
switch (input[i].token) {
|
||||
case SL_PP_WHITESPACE:
|
||||
s = " ";
|
||||
break;
|
||||
|
||||
case SL_PP_NEWLINE:
|
||||
s = "\n";
|
||||
break;
|
||||
|
||||
case SL_PP_HASH:
|
||||
s = "#";
|
||||
break;
|
||||
|
||||
case SL_PP_COMMA:
|
||||
s = ",";
|
||||
break;
|
||||
|
||||
case SL_PP_SEMICOLON:
|
||||
s = ";";
|
||||
break;
|
||||
|
||||
case SL_PP_LBRACE:
|
||||
s = "{";
|
||||
break;
|
||||
|
||||
case SL_PP_RBRACE:
|
||||
s = "}";
|
||||
break;
|
||||
|
||||
case SL_PP_LPAREN:
|
||||
s = "(";
|
||||
break;
|
||||
|
||||
case SL_PP_RPAREN:
|
||||
s = ")";
|
||||
break;
|
||||
|
||||
case SL_PP_LBRACKET:
|
||||
s = "[";
|
||||
break;
|
||||
|
||||
case SL_PP_RBRACKET:
|
||||
s = "]";
|
||||
break;
|
||||
|
||||
case SL_PP_DOT:
|
||||
s = ".";
|
||||
break;
|
||||
|
||||
case SL_PP_INCREMENT:
|
||||
s = "++";
|
||||
break;
|
||||
|
||||
case SL_PP_ADDASSIGN:
|
||||
s = "+=";
|
||||
break;
|
||||
|
||||
case SL_PP_PLUS:
|
||||
s = "+";
|
||||
break;
|
||||
|
||||
case SL_PP_DECREMENT:
|
||||
s = "--";
|
||||
break;
|
||||
|
||||
case SL_PP_SUBASSIGN:
|
||||
s = "-=";
|
||||
break;
|
||||
|
||||
case SL_PP_MINUS:
|
||||
s = "-";
|
||||
break;
|
||||
|
||||
case SL_PP_BITNOT:
|
||||
s = "~";
|
||||
break;
|
||||
|
||||
case SL_PP_NOTEQUAL:
|
||||
s = "!=";
|
||||
break;
|
||||
|
||||
case SL_PP_NOT:
|
||||
s = "!";
|
||||
break;
|
||||
|
||||
case SL_PP_MULASSIGN:
|
||||
s = "*=";
|
||||
break;
|
||||
|
||||
case SL_PP_STAR:
|
||||
s = "*";
|
||||
break;
|
||||
|
||||
case SL_PP_DIVASSIGN:
|
||||
s = "/=";
|
||||
break;
|
||||
|
||||
case SL_PP_SLASH:
|
||||
s = "/";
|
||||
break;
|
||||
|
||||
case SL_PP_MODASSIGN:
|
||||
s = "%=";
|
||||
break;
|
||||
|
||||
case SL_PP_MODULO:
|
||||
s = "%";
|
||||
break;
|
||||
|
||||
case SL_PP_LSHIFTASSIGN:
|
||||
s = "<<=";
|
||||
break;
|
||||
|
||||
case SL_PP_LSHIFT:
|
||||
s = "<<";
|
||||
break;
|
||||
|
||||
case SL_PP_LESSEQUAL:
|
||||
s = "<=";
|
||||
break;
|
||||
|
||||
case SL_PP_LESS:
|
||||
s = "<";
|
||||
break;
|
||||
|
||||
case SL_PP_RSHIFTASSIGN:
|
||||
s = ">>=";
|
||||
break;
|
||||
|
||||
case SL_PP_RSHIFT:
|
||||
s = ">>";
|
||||
break;
|
||||
|
||||
case SL_PP_GREATEREQUAL:
|
||||
s = ">=";
|
||||
break;
|
||||
|
||||
case SL_PP_GREATER:
|
||||
s = ">";
|
||||
break;
|
||||
|
||||
case SL_PP_EQUAL:
|
||||
s = "==";
|
||||
break;
|
||||
|
||||
case SL_PP_ASSIGN:
|
||||
s = "=";
|
||||
break;
|
||||
|
||||
case SL_PP_AND:
|
||||
s = "&&";
|
||||
break;
|
||||
|
||||
case SL_PP_BITANDASSIGN:
|
||||
s = "&=";
|
||||
break;
|
||||
|
||||
case SL_PP_BITAND:
|
||||
s = "&";
|
||||
break;
|
||||
|
||||
case SL_PP_XOR:
|
||||
s = "^^";
|
||||
break;
|
||||
|
||||
case SL_PP_BITXORASSIGN:
|
||||
s = "^=";
|
||||
break;
|
||||
|
||||
case SL_PP_BITXOR:
|
||||
s = "^";
|
||||
break;
|
||||
|
||||
case SL_PP_OR:
|
||||
s = "||";
|
||||
break;
|
||||
|
||||
case SL_PP_BITORASSIGN:
|
||||
s = "|=";
|
||||
break;
|
||||
|
||||
case SL_PP_BITOR:
|
||||
s = "|";
|
||||
break;
|
||||
|
||||
case SL_PP_QUESTION:
|
||||
s = "?";
|
||||
break;
|
||||
|
||||
case SL_PP_COLON:
|
||||
s = ":";
|
||||
break;
|
||||
|
||||
case SL_PP_IDENTIFIER:
|
||||
s = sl_pp_context_cstr(context, input[i].data.identifier);
|
||||
break;
|
||||
|
||||
case SL_PP_UINT:
|
||||
s = sl_pp_context_cstr(context, input[i].data._uint);
|
||||
break;
|
||||
|
||||
case SL_PP_FLOAT:
|
||||
s = sl_pp_context_cstr(context, input[i].data._float);
|
||||
break;
|
||||
|
||||
case SL_PP_OTHER:
|
||||
buf[0] = input[i].data.other;
|
||||
buf[1] = '\0';
|
||||
s = buf;
|
||||
break;
|
||||
|
||||
default:
|
||||
strcpy(context->error_msg, "internal error");
|
||||
return;
|
||||
}
|
||||
|
||||
while (*s != '\0' && out_len < sizeof(context->error_msg) - 1) {
|
||||
context->error_msg[out_len++] = *s++;
|
||||
}
|
||||
}
|
||||
|
||||
context->error_msg[out_len] = '\0';
|
||||
}
|
|
@ -1,413 +0,0 @@
|
|||
/**************************************************************************
|
||||
*
|
||||
* Copyright 2009 VMware, Inc.
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sub license, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the
|
||||
* next paragraph) shall be included in all copies or substantial portions
|
||||
* of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
|
||||
* IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
|
||||
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
**************************************************************************/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "sl_pp_context.h"
|
||||
#include "sl_pp_expression.h"
|
||||
#include "sl_pp_public.h"
|
||||
#include "sl_pp_token.h"
|
||||
|
||||
|
||||
struct parse_context {
|
||||
struct sl_pp_context *context;
|
||||
const struct sl_pp_token_info *input;
|
||||
};
|
||||
|
||||
static int
|
||||
_parse_or(struct parse_context *ctx,
|
||||
int *result);
|
||||
|
||||
static int
|
||||
_parse_primary(struct parse_context *ctx,
|
||||
int *result)
|
||||
{
|
||||
if (ctx->input->token == SL_PP_UINT) {
|
||||
*result = atoi(sl_pp_context_cstr(ctx->context, ctx->input->data._uint));
|
||||
ctx->input++;
|
||||
} else {
|
||||
if (ctx->input->token != SL_PP_LPAREN) {
|
||||
strcpy(ctx->context->error_msg, "expected `('");
|
||||
return -1;
|
||||
}
|
||||
ctx->input++;
|
||||
if (_parse_or(ctx, result)) {
|
||||
return -1;
|
||||
}
|
||||
if (ctx->input->token != SL_PP_RPAREN) {
|
||||
strcpy(ctx->context->error_msg, "expected `)'");
|
||||
return -1;
|
||||
}
|
||||
ctx->input++;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
_parse_unary(struct parse_context *ctx,
|
||||
int *result)
|
||||
{
|
||||
if (!_parse_primary(ctx, result)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
switch (ctx->input->token) {
|
||||
case SL_PP_PLUS:
|
||||
ctx->input++;
|
||||
if (_parse_unary(ctx, result)) {
|
||||
return -1;
|
||||
}
|
||||
*result = +*result;
|
||||
break;
|
||||
|
||||
case SL_PP_MINUS:
|
||||
ctx->input++;
|
||||
if (_parse_unary(ctx, result)) {
|
||||
return -1;
|
||||
}
|
||||
*result = -*result;
|
||||
break;
|
||||
|
||||
case SL_PP_NOT:
|
||||
ctx->input++;
|
||||
if (_parse_unary(ctx, result)) {
|
||||
return -1;
|
||||
}
|
||||
*result = !*result;
|
||||
break;
|
||||
|
||||
case SL_PP_BITNOT:
|
||||
ctx->input++;
|
||||
if (_parse_unary(ctx, result)) {
|
||||
return -1;
|
||||
}
|
||||
*result = ~*result;
|
||||
break;
|
||||
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
_parse_multiplicative(struct parse_context *ctx,
|
||||
int *result)
|
||||
{
|
||||
if (_parse_unary(ctx, result)) {
|
||||
return -1;
|
||||
}
|
||||
for (;;) {
|
||||
int right;
|
||||
|
||||
switch (ctx->input->token) {
|
||||
case SL_PP_STAR:
|
||||
ctx->input++;
|
||||
if (_parse_unary(ctx, &right)) {
|
||||
return -1;
|
||||
}
|
||||
*result = *result * right;
|
||||
break;
|
||||
|
||||
case SL_PP_SLASH:
|
||||
ctx->input++;
|
||||
if (_parse_unary(ctx, &right)) {
|
||||
return -1;
|
||||
}
|
||||
*result = *result / right;
|
||||
break;
|
||||
|
||||
case SL_PP_MODULO:
|
||||
ctx->input++;
|
||||
if (_parse_unary(ctx, &right)) {
|
||||
return -1;
|
||||
}
|
||||
*result = *result % right;
|
||||
break;
|
||||
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
_parse_additive(struct parse_context *ctx,
|
||||
int *result)
|
||||
{
|
||||
if (_parse_multiplicative(ctx, result)) {
|
||||
return -1;
|
||||
}
|
||||
for (;;) {
|
||||
int right;
|
||||
|
||||
switch (ctx->input->token) {
|
||||
case SL_PP_PLUS:
|
||||
ctx->input++;
|
||||
if (_parse_multiplicative(ctx, &right)) {
|
||||
return -1;
|
||||
}
|
||||
*result = *result + right;
|
||||
break;
|
||||
|
||||
case SL_PP_MINUS:
|
||||
ctx->input++;
|
||||
if (_parse_multiplicative(ctx, &right)) {
|
||||
return -1;
|
||||
}
|
||||
*result = *result - right;
|
||||
break;
|
||||
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
_parse_shift(struct parse_context *ctx,
|
||||
int *result)
|
||||
{
|
||||
if (_parse_additive(ctx, result)) {
|
||||
return -1;
|
||||
}
|
||||
for (;;) {
|
||||
int right;
|
||||
|
||||
switch (ctx->input->token) {
|
||||
case SL_PP_LSHIFT:
|
||||
ctx->input++;
|
||||
if (_parse_additive(ctx, &right)) {
|
||||
return -1;
|
||||
}
|
||||
*result = *result << right;
|
||||
break;
|
||||
|
||||
case SL_PP_RSHIFT:
|
||||
ctx->input++;
|
||||
if (_parse_additive(ctx, &right)) {
|
||||
return -1;
|
||||
}
|
||||
*result = *result >> right;
|
||||
break;
|
||||
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
_parse_relational(struct parse_context *ctx,
|
||||
int *result)
|
||||
{
|
||||
if (_parse_shift(ctx, result)) {
|
||||
return -1;
|
||||
}
|
||||
for (;;) {
|
||||
int right;
|
||||
|
||||
switch (ctx->input->token) {
|
||||
case SL_PP_LESSEQUAL:
|
||||
ctx->input++;
|
||||
if (_parse_shift(ctx, &right)) {
|
||||
return -1;
|
||||
}
|
||||
*result = *result <= right;
|
||||
break;
|
||||
|
||||
case SL_PP_GREATEREQUAL:
|
||||
ctx->input++;
|
||||
if (_parse_shift(ctx, &right)) {
|
||||
return -1;
|
||||
}
|
||||
*result = *result >= right;
|
||||
break;
|
||||
|
||||
case SL_PP_LESS:
|
||||
ctx->input++;
|
||||
if (_parse_shift(ctx, &right)) {
|
||||
return -1;
|
||||
}
|
||||
*result = *result < right;
|
||||
break;
|
||||
|
||||
case SL_PP_GREATER:
|
||||
ctx->input++;
|
||||
if (_parse_shift(ctx, &right)) {
|
||||
return -1;
|
||||
}
|
||||
*result = *result > right;
|
||||
break;
|
||||
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
_parse_equality(struct parse_context *ctx,
|
||||
int *result)
|
||||
{
|
||||
if (_parse_relational(ctx, result)) {
|
||||
return -1;
|
||||
}
|
||||
for (;;) {
|
||||
int right;
|
||||
|
||||
switch (ctx->input->token) {
|
||||
case SL_PP_EQUAL:
|
||||
ctx->input++;
|
||||
if (_parse_relational(ctx, &right)) {
|
||||
return -1;
|
||||
}
|
||||
*result = *result == right;
|
||||
break;
|
||||
|
||||
case SL_PP_NOTEQUAL:
|
||||
ctx->input++;
|
||||
if (_parse_relational(ctx, &right)) {
|
||||
return -1;
|
||||
}
|
||||
*result = *result != right;
|
||||
break;
|
||||
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
_parse_bitand(struct parse_context *ctx,
|
||||
int *result)
|
||||
{
|
||||
if (_parse_equality(ctx, result)) {
|
||||
return -1;
|
||||
}
|
||||
while (ctx->input->token == SL_PP_BITAND) {
|
||||
int right;
|
||||
|
||||
ctx->input++;
|
||||
if (_parse_equality(ctx, &right)) {
|
||||
return -1;
|
||||
}
|
||||
*result = *result & right;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
_parse_xor(struct parse_context *ctx,
|
||||
int *result)
|
||||
{
|
||||
if (_parse_bitand(ctx, result)) {
|
||||
return -1;
|
||||
}
|
||||
while (ctx->input->token == SL_PP_XOR) {
|
||||
int right;
|
||||
|
||||
ctx->input++;
|
||||
if (_parse_bitand(ctx, &right)) {
|
||||
return -1;
|
||||
}
|
||||
*result = *result ^ right;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
_parse_bitor(struct parse_context *ctx,
|
||||
int *result)
|
||||
{
|
||||
if (_parse_xor(ctx, result)) {
|
||||
return -1;
|
||||
}
|
||||
while (ctx->input->token == SL_PP_BITOR) {
|
||||
int right;
|
||||
|
||||
ctx->input++;
|
||||
if (_parse_xor(ctx, &right)) {
|
||||
return -1;
|
||||
}
|
||||
*result = *result | right;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
_parse_and(struct parse_context *ctx,
|
||||
int *result)
|
||||
{
|
||||
if (_parse_bitor(ctx, result)) {
|
||||
return -1;
|
||||
}
|
||||
while (ctx->input->token == SL_PP_AND) {
|
||||
int right;
|
||||
|
||||
ctx->input++;
|
||||
if (_parse_bitor(ctx, &right)) {
|
||||
return -1;
|
||||
}
|
||||
*result = *result && right;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
_parse_or(struct parse_context *ctx,
|
||||
int *result)
|
||||
{
|
||||
if (_parse_and(ctx, result)) {
|
||||
return -1;
|
||||
}
|
||||
while (ctx->input->token == SL_PP_OR) {
|
||||
int right;
|
||||
|
||||
ctx->input++;
|
||||
if (_parse_and(ctx, &right)) {
|
||||
return -1;
|
||||
}
|
||||
*result = *result || right;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
sl_pp_execute_expression(struct sl_pp_context *context,
|
||||
const struct sl_pp_token_info *input,
|
||||
int *result)
|
||||
{
|
||||
struct parse_context ctx;
|
||||
|
||||
ctx.context = context;
|
||||
ctx.input = input;
|
||||
|
||||
return _parse_or(&ctx, result);
|
||||
}
|
|
@ -1,40 +0,0 @@
|
|||
/**************************************************************************
|
||||
*
|
||||
* Copyright 2009 VMware, Inc.
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sub license, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the
|
||||
* next paragraph) shall be included in all copies or substantial portions
|
||||
* of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
|
||||
* IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
|
||||
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
**************************************************************************/
|
||||
|
||||
#ifndef SL_PP_EXPRESSION_H
|
||||
#define SL_PP_EXPRESSION_H
|
||||
|
||||
struct sl_pp_context;
|
||||
struct sl_pp_token_info;
|
||||
|
||||
|
||||
int
|
||||
sl_pp_execute_expression(struct sl_pp_context *context,
|
||||
const struct sl_pp_token_info *input,
|
||||
int *result);
|
||||
|
||||
#endif /* SL_PP_EXPRESSION_H */
|
|
@ -1,180 +0,0 @@
|
|||
/**************************************************************************
|
||||
*
|
||||
* Copyright 2009 VMware, Inc.
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sub license, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the
|
||||
* next paragraph) shall be included in all copies or substantial portions
|
||||
* of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
|
||||
* IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
|
||||
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
**************************************************************************/
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "sl_pp_context.h"
|
||||
#include "sl_pp_process.h"
|
||||
#include "sl_pp_public.h"
|
||||
#include "sl_pp_token.h"
|
||||
|
||||
|
||||
/**
|
||||
* Declare an extension to the preprocessor. This tells the preprocessor
|
||||
* which extensions are supported by Mesa.
|
||||
* The shader still needs to have a "#extension name: behavior" line to enable
|
||||
* the extension.
|
||||
*/
|
||||
int
|
||||
sl_pp_context_add_extension(struct sl_pp_context *context,
|
||||
const char *name)
|
||||
{
|
||||
struct sl_pp_extension ext;
|
||||
|
||||
if (context->num_extensions == SL_PP_MAX_EXTENSIONS) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
ext.name = sl_pp_context_add_unique_str(context, name);
|
||||
if (ext.name == -1) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
context->extensions[context->num_extensions++] = ext;
|
||||
|
||||
assert(context->num_extensions <= sizeof(context->extensions));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Process a "#extension name: behavior" directive.
|
||||
*/
|
||||
int
|
||||
sl_pp_process_extension(struct sl_pp_context *context,
|
||||
const struct sl_pp_token_info *input,
|
||||
unsigned int first,
|
||||
unsigned int last,
|
||||
struct sl_pp_process_state *state)
|
||||
{
|
||||
int extension_name = -1;
|
||||
int behavior = -1;
|
||||
struct sl_pp_token_info out;
|
||||
|
||||
/* Grab the extension name. */
|
||||
if (first < last && input[first].token == SL_PP_IDENTIFIER) {
|
||||
extension_name = input[first].data.identifier;
|
||||
first++;
|
||||
}
|
||||
if (extension_name == -1) {
|
||||
strcpy(context->error_msg, "expected identifier after `#extension'");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Make sure the extension is supported. */
|
||||
if (extension_name == context->dict.all) {
|
||||
out.data.extension = extension_name;
|
||||
} else {
|
||||
unsigned int i;
|
||||
|
||||
out.data.extension = -1;
|
||||
for (i = 0; i < context->num_extensions; i++) {
|
||||
if (extension_name == context->extensions[i].name) {
|
||||
out.data.extension = extension_name;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Grab the colon separating the extension name and behavior. */
|
||||
while (first < last && input[first].token == SL_PP_WHITESPACE) {
|
||||
first++;
|
||||
}
|
||||
if (first < last && input[first].token == SL_PP_COLON) {
|
||||
first++;
|
||||
} else {
|
||||
strcpy(context->error_msg, "expected `:' after extension name");
|
||||
return -1;
|
||||
}
|
||||
while (first < last && input[first].token == SL_PP_WHITESPACE) {
|
||||
first++;
|
||||
}
|
||||
|
||||
/* Grab the behavior name. */
|
||||
if (first < last && input[first].token == SL_PP_IDENTIFIER) {
|
||||
behavior = input[first].data.identifier;
|
||||
first++;
|
||||
}
|
||||
if (behavior == -1) {
|
||||
strcpy(context->error_msg, "expected identifier after `:'");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (behavior == context->dict.require) {
|
||||
if (out.data.extension == -1) {
|
||||
strcpy(context->error_msg, "the required extension is not supported");
|
||||
return -1;
|
||||
}
|
||||
if (out.data.extension == context->dict.all) {
|
||||
strcpy(context->error_msg, "invalid behavior for `all' extension: `require'");
|
||||
return -1;
|
||||
}
|
||||
out.token = SL_PP_EXTENSION_REQUIRE;
|
||||
} else if (behavior == context->dict.enable) {
|
||||
if (out.data.extension == -1) {
|
||||
/* Warning: the extension cannot be enabled. */
|
||||
return 0;
|
||||
}
|
||||
if (out.data.extension == context->dict.all) {
|
||||
strcpy(context->error_msg, "invalid behavior for `all' extension: `enable'");
|
||||
return -1;
|
||||
}
|
||||
out.token = SL_PP_EXTENSION_ENABLE;
|
||||
} else if (behavior == context->dict.warn) {
|
||||
if (out.data.extension == -1) {
|
||||
/* Warning: the extension is not supported. */
|
||||
return 0;
|
||||
}
|
||||
out.token = SL_PP_EXTENSION_WARN;
|
||||
} else if (behavior == context->dict.disable) {
|
||||
if (out.data.extension == -1) {
|
||||
/* Warning: the extension is not supported. */
|
||||
return 0;
|
||||
}
|
||||
out.token = SL_PP_EXTENSION_DISABLE;
|
||||
} else {
|
||||
strcpy(context->error_msg, "unrecognised behavior name");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Grab the end of line. */
|
||||
while (first < last && input[first].token == SL_PP_WHITESPACE) {
|
||||
first++;
|
||||
}
|
||||
if (first < last) {
|
||||
strcpy(context->error_msg, "expected end of line after behavior name");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (sl_pp_process_out(state, &out)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -1,343 +0,0 @@
|
|||
/**************************************************************************
|
||||
*
|
||||
* Copyright 2009 VMware, Inc.
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sub license, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the
|
||||
* next paragraph) shall be included in all copies or substantial portions
|
||||
* of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
|
||||
* IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
|
||||
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
**************************************************************************/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "sl_pp_context.h"
|
||||
#include "sl_pp_expression.h"
|
||||
#include "sl_pp_macro.h"
|
||||
#include "sl_pp_process.h"
|
||||
#include "sl_pp_token.h"
|
||||
|
||||
|
||||
static int
|
||||
_macro_is_defined(struct sl_pp_context *context,
|
||||
int macro_name)
|
||||
{
|
||||
unsigned int i;
|
||||
struct sl_pp_macro *macro;
|
||||
|
||||
for (i = 0; i < context->num_extensions; i++) {
|
||||
if (macro_name == context->extensions[i].name) {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
for (macro = context->macro; macro; macro = macro->next) {
|
||||
if (macro_name == macro->name) {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
_parse_defined(struct sl_pp_context *context,
|
||||
struct sl_pp_token_buffer *buffer,
|
||||
struct sl_pp_process_state *state)
|
||||
{
|
||||
struct sl_pp_token_info input;
|
||||
int parens = 0;
|
||||
int defined;
|
||||
struct sl_pp_token_info result;
|
||||
|
||||
if (sl_pp_token_buffer_skip_white(buffer, &input)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (input.token == SL_PP_LPAREN) {
|
||||
if (sl_pp_token_buffer_skip_white(buffer, &input)) {
|
||||
return -1;
|
||||
}
|
||||
parens = 1;
|
||||
}
|
||||
|
||||
if (input.token != SL_PP_IDENTIFIER) {
|
||||
strcpy(context->error_msg, "expected an identifier");
|
||||
return -1;
|
||||
}
|
||||
|
||||
defined = _macro_is_defined(context, input.data.identifier);
|
||||
|
||||
if (parens) {
|
||||
if (sl_pp_token_buffer_skip_white(buffer, &input)) {
|
||||
return -1;
|
||||
}
|
||||
if (input.token != SL_PP_RPAREN) {
|
||||
strcpy(context->error_msg, "expected `)'");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
result.token = SL_PP_UINT;
|
||||
result.data._uint = (defined ? context->dict._1 : context->dict._0);
|
||||
|
||||
if (sl_pp_process_out(state, &result)) {
|
||||
strcpy(context->error_msg, "out of memory");
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static unsigned int
|
||||
_evaluate_if_stack(struct sl_pp_context *context)
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
for (i = context->if_ptr; i < SL_PP_MAX_IF_NESTING; i++) {
|
||||
if (!context->if_stack[i].u.condition) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int
|
||||
_parse_if(struct sl_pp_context *context,
|
||||
struct sl_pp_token_buffer *buffer)
|
||||
{
|
||||
struct sl_pp_process_state state;
|
||||
int found_end = 0;
|
||||
struct sl_pp_token_info eof;
|
||||
int result;
|
||||
|
||||
if (!context->if_ptr) {
|
||||
strcpy(context->error_msg, "`#if' nesting too deep");
|
||||
return -1;
|
||||
}
|
||||
|
||||
memset(&state, 0, sizeof(state));
|
||||
while (!found_end) {
|
||||
struct sl_pp_token_info input;
|
||||
|
||||
sl_pp_token_buffer_get(buffer, &input);
|
||||
switch (input.token) {
|
||||
case SL_PP_WHITESPACE:
|
||||
break;
|
||||
|
||||
case SL_PP_IDENTIFIER:
|
||||
if (input.data.identifier == context->dict.defined) {
|
||||
if (_parse_defined(context, buffer, &state)) {
|
||||
free(state.out);
|
||||
return -1;
|
||||
}
|
||||
} else {
|
||||
sl_pp_token_buffer_unget(buffer, &input);
|
||||
if (sl_pp_macro_expand(context, buffer, NULL, &state, sl_pp_macro_expand_unknown_to_0)) {
|
||||
free(state.out);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case SL_PP_NEWLINE:
|
||||
case SL_PP_EOF:
|
||||
found_end = 1;
|
||||
break;
|
||||
|
||||
default:
|
||||
if (sl_pp_process_out(&state, &input)) {
|
||||
strcpy(context->error_msg, "out of memory");
|
||||
free(state.out);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
eof.token = SL_PP_EOF;
|
||||
if (sl_pp_process_out(&state, &eof)) {
|
||||
strcpy(context->error_msg, "out of memory");
|
||||
free(state.out);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (sl_pp_execute_expression(context, state.out, &result)) {
|
||||
free(state.out);
|
||||
return -1;
|
||||
}
|
||||
|
||||
free(state.out);
|
||||
|
||||
context->if_ptr--;
|
||||
context->if_stack[context->if_ptr].value = 0;
|
||||
context->if_stack[context->if_ptr].u.condition = result ? 1 : 0;
|
||||
context->if_value = _evaluate_if_stack(context);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
_parse_else(struct sl_pp_context *context)
|
||||
{
|
||||
union sl_pp_if_state *state = &context->if_stack[context->if_ptr];
|
||||
|
||||
if (context->if_ptr == SL_PP_MAX_IF_NESTING) {
|
||||
strcpy(context->error_msg, "no matching `#if'");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (state->u.went_thru_else) {
|
||||
strcpy(context->error_msg, "no matching `#if'");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Once we had a true condition, the subsequent #elifs should always be false. */
|
||||
state->u.had_true_cond |= state->u.condition;
|
||||
|
||||
/* Update current condition value and mark that we are in the #else block. */
|
||||
state->u.condition = !(state->u.had_true_cond | state->u.condition);
|
||||
state->u.went_thru_else = 1;
|
||||
context->if_value = _evaluate_if_stack(context);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
sl_pp_process_if(struct sl_pp_context *context,
|
||||
struct sl_pp_token_buffer *buffer)
|
||||
{
|
||||
return _parse_if(context, buffer);
|
||||
}
|
||||
|
||||
int
|
||||
sl_pp_process_ifdef(struct sl_pp_context *context,
|
||||
const struct sl_pp_token_info *input,
|
||||
unsigned int first,
|
||||
unsigned int last)
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
if (!context->if_ptr) {
|
||||
strcpy(context->error_msg, "`#if' nesting too deep");
|
||||
return -1;
|
||||
}
|
||||
|
||||
for (i = first; i < last; i++) {
|
||||
switch (input[i].token) {
|
||||
case SL_PP_IDENTIFIER:
|
||||
context->if_ptr--;
|
||||
context->if_stack[context->if_ptr].value = 0;
|
||||
context->if_stack[context->if_ptr].u.condition = _macro_is_defined(context, input[i].data.identifier);
|
||||
context->if_value = _evaluate_if_stack(context);
|
||||
return 0;
|
||||
|
||||
case SL_PP_WHITESPACE:
|
||||
break;
|
||||
|
||||
default:
|
||||
strcpy(context->error_msg, "expected an identifier");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
strcpy(context->error_msg, "expected an identifier");
|
||||
return -1;
|
||||
}
|
||||
|
||||
int
|
||||
sl_pp_process_ifndef(struct sl_pp_context *context,
|
||||
const struct sl_pp_token_info *input,
|
||||
unsigned int first,
|
||||
unsigned int last)
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
if (!context->if_ptr) {
|
||||
strcpy(context->error_msg, "`#if' nesting too deep");
|
||||
return -1;
|
||||
}
|
||||
|
||||
for (i = first; i < last; i++) {
|
||||
switch (input[i].token) {
|
||||
case SL_PP_IDENTIFIER:
|
||||
context->if_ptr--;
|
||||
context->if_stack[context->if_ptr].value = 0;
|
||||
context->if_stack[context->if_ptr].u.condition = !_macro_is_defined(context, input[i].data.identifier);
|
||||
context->if_value = _evaluate_if_stack(context);
|
||||
return 0;
|
||||
|
||||
case SL_PP_WHITESPACE:
|
||||
break;
|
||||
|
||||
default:
|
||||
strcpy(context->error_msg, "expected an identifier");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
strcpy(context->error_msg, "expected an identifier");
|
||||
return -1;
|
||||
}
|
||||
|
||||
int
|
||||
sl_pp_process_elif(struct sl_pp_context *context,
|
||||
struct sl_pp_token_buffer *buffer)
|
||||
{
|
||||
if (_parse_else(context)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (context->if_stack[context->if_ptr].u.condition) {
|
||||
context->if_ptr++;
|
||||
if (_parse_if(context, buffer)) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
/* We are still in the #if block. */
|
||||
context->if_stack[context->if_ptr].u.went_thru_else = 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
sl_pp_process_else(struct sl_pp_context *context,
|
||||
const struct sl_pp_token_info *input,
|
||||
unsigned int first,
|
||||
unsigned int last)
|
||||
{
|
||||
return _parse_else(context);
|
||||
}
|
||||
|
||||
int
|
||||
sl_pp_process_endif(struct sl_pp_context *context,
|
||||
const struct sl_pp_token_info *input,
|
||||
unsigned int first,
|
||||
unsigned int last)
|
||||
{
|
||||
if (context->if_ptr == SL_PP_MAX_IF_NESTING) {
|
||||
strcpy(context->error_msg, "no matching `#if'");
|
||||
return -1;
|
||||
}
|
||||
|
||||
context->if_ptr++;
|
||||
context->if_value = _evaluate_if_stack(context);
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -1,129 +0,0 @@
|
|||
/**************************************************************************
|
||||
*
|
||||
* Copyright 2009 VMware, Inc.
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sub license, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the
|
||||
* next paragraph) shall be included in all copies or substantial portions
|
||||
* of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
|
||||
* IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
|
||||
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
**************************************************************************/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "sl_pp_context.h"
|
||||
#include "sl_pp_macro.h"
|
||||
#include "sl_pp_public.h"
|
||||
#include "sl_pp_process.h"
|
||||
#include "sl_pp_token.h"
|
||||
|
||||
|
||||
int
|
||||
sl_pp_process_line(struct sl_pp_context *context,
|
||||
struct sl_pp_token_buffer *buffer,
|
||||
struct sl_pp_process_state *pstate)
|
||||
{
|
||||
struct sl_pp_process_state state;
|
||||
int found_end = 0;
|
||||
int line_number = -1;
|
||||
int file_number = -1;
|
||||
unsigned int line;
|
||||
unsigned int file;
|
||||
|
||||
memset(&state, 0, sizeof(state));
|
||||
while (!found_end) {
|
||||
struct sl_pp_token_info input;
|
||||
|
||||
sl_pp_token_buffer_get(buffer, &input);
|
||||
switch (input.token) {
|
||||
case SL_PP_WHITESPACE:
|
||||
break;
|
||||
|
||||
case SL_PP_IDENTIFIER:
|
||||
sl_pp_token_buffer_unget(buffer, &input);
|
||||
if (sl_pp_macro_expand(context, buffer, NULL, &state, sl_pp_macro_expand_normal)) {
|
||||
free(state.out);
|
||||
return -1;
|
||||
}
|
||||
break;
|
||||
|
||||
case SL_PP_NEWLINE:
|
||||
case SL_PP_EOF:
|
||||
found_end = 1;
|
||||
break;
|
||||
|
||||
default:
|
||||
if (sl_pp_process_out(&state, &input)) {
|
||||
strcpy(context->error_msg, "out of memory");
|
||||
free(state.out);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (state.out_len > 0 && state.out[0].token == SL_PP_UINT) {
|
||||
line_number = state.out[0].data._uint;
|
||||
} else {
|
||||
strcpy(context->error_msg, "expected a number after `#line'");
|
||||
free(state.out);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (state.out_len > 1) {
|
||||
if (state.out[1].token == SL_PP_UINT) {
|
||||
file_number = state.out[1].data._uint;
|
||||
} else {
|
||||
strcpy(context->error_msg, "expected a number after line number");
|
||||
free(state.out);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (state.out_len > 2) {
|
||||
strcpy(context->error_msg, "expected an end of line after file number");
|
||||
free(state.out);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
free(state.out);
|
||||
|
||||
line = atoi(sl_pp_context_cstr(context, line_number));
|
||||
if (file_number != -1) {
|
||||
file = atoi(sl_pp_context_cstr(context, file_number));
|
||||
} else {
|
||||
file = context->file;
|
||||
}
|
||||
|
||||
if (context->line != line || context->file != file) {
|
||||
struct sl_pp_token_info ti;
|
||||
|
||||
ti.token = SL_PP_LINE;
|
||||
ti.data.line.lineno = line;
|
||||
ti.data.line.fileno = file;
|
||||
if (sl_pp_process_out(pstate, &ti)) {
|
||||
strcpy(context->error_msg, "out of memory");
|
||||
return -1;
|
||||
}
|
||||
|
||||
context->line = line;
|
||||
context->file = file;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -1,415 +0,0 @@
|
|||
/**************************************************************************
|
||||
*
|
||||
* Copyright 2009 VMware, Inc.
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sub license, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the
|
||||
* next paragraph) shall be included in all copies or substantial portions
|
||||
* of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
|
||||
* IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
|
||||
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
**************************************************************************/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include "sl_pp_context.h"
|
||||
#include "sl_pp_public.h"
|
||||
#include "sl_pp_macro.h"
|
||||
#include "sl_pp_process.h"
|
||||
#include "sl_pp_token.h"
|
||||
|
||||
|
||||
static void
|
||||
_macro_init(struct sl_pp_macro *macro)
|
||||
{
|
||||
macro->name = -1;
|
||||
macro->num_args = -1;
|
||||
macro->arg = NULL;
|
||||
macro->body = NULL;
|
||||
}
|
||||
|
||||
struct sl_pp_macro *
|
||||
sl_pp_macro_new(void)
|
||||
{
|
||||
struct sl_pp_macro *macro;
|
||||
|
||||
macro = calloc(1, sizeof(struct sl_pp_macro));
|
||||
if (macro) {
|
||||
_macro_init(macro);
|
||||
}
|
||||
return macro;
|
||||
}
|
||||
|
||||
static void
|
||||
_macro_destroy(struct sl_pp_macro *macro)
|
||||
{
|
||||
struct sl_pp_macro_formal_arg *arg = macro->arg;
|
||||
|
||||
while (arg) {
|
||||
struct sl_pp_macro_formal_arg *next_arg = arg->next;
|
||||
|
||||
free(arg);
|
||||
arg = next_arg;
|
||||
}
|
||||
|
||||
free(macro->body);
|
||||
}
|
||||
|
||||
void
|
||||
sl_pp_macro_free(struct sl_pp_macro *macro)
|
||||
{
|
||||
while (macro) {
|
||||
struct sl_pp_macro *next_macro = macro->next;
|
||||
|
||||
_macro_destroy(macro);
|
||||
free(macro);
|
||||
macro = next_macro;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
sl_pp_macro_reset(struct sl_pp_macro *macro)
|
||||
{
|
||||
_macro_destroy(macro);
|
||||
_macro_init(macro);
|
||||
}
|
||||
|
||||
static int
|
||||
_out_number(struct sl_pp_context *context,
|
||||
struct sl_pp_process_state *state,
|
||||
unsigned int number)
|
||||
{
|
||||
char buf[32];
|
||||
struct sl_pp_token_info ti;
|
||||
|
||||
sprintf(buf, "%u", number);
|
||||
|
||||
ti.token = SL_PP_UINT;
|
||||
ti.data._uint = sl_pp_context_add_unique_str(context, buf);
|
||||
if (sl_pp_process_out(state, &ti)) {
|
||||
strcpy(context->error_msg, "out of memory");
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
sl_pp_macro_expand(struct sl_pp_context *context,
|
||||
struct sl_pp_token_buffer *tokens,
|
||||
struct sl_pp_macro *local,
|
||||
struct sl_pp_process_state *state,
|
||||
enum sl_pp_macro_expand_behaviour behaviour)
|
||||
{
|
||||
int mute = (behaviour == sl_pp_macro_expand_mute);
|
||||
struct sl_pp_token_info input;
|
||||
int macro_name;
|
||||
struct sl_pp_macro *macro = NULL;
|
||||
struct sl_pp_macro *actual_arg = NULL;
|
||||
unsigned int j;
|
||||
|
||||
if (sl_pp_token_buffer_get(tokens, &input)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (input.token != SL_PP_IDENTIFIER) {
|
||||
strcpy(context->error_msg, "expected an identifier");
|
||||
return -1;
|
||||
}
|
||||
|
||||
macro_name = input.data.identifier;
|
||||
|
||||
/* First look for predefined macros.
|
||||
*/
|
||||
|
||||
if (macro_name == context->dict.___LINE__) {
|
||||
if (!mute && _out_number(context, state, context->line)) {
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
if (macro_name == context->dict.___FILE__) {
|
||||
if (!mute && _out_number(context, state, context->file)) {
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
if (macro_name == context->dict.___VERSION__) {
|
||||
if (!mute && _out_number(context, state, 110)) {
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
for (j = 0; j < context->num_predefined; j++) {
|
||||
if (macro_name == context->predefined[j].name) {
|
||||
if (!mute) {
|
||||
struct sl_pp_token_info ti;
|
||||
|
||||
ti.token = SL_PP_UINT;
|
||||
ti.data._uint = context->predefined[j].value;
|
||||
if (sl_pp_process_out(state, &ti)) {
|
||||
strcpy(context->error_msg, "out of memory");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* Replace extension names with 1.
|
||||
*/
|
||||
for (j = 0; j < context->num_extensions; j++) {
|
||||
if (macro_name == context->extensions[j].name) {
|
||||
if (!mute && _out_number(context, state, 1)) {
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (local) {
|
||||
for (macro = local; macro; macro = macro->next) {
|
||||
if (macro->name == macro_name) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!macro) {
|
||||
for (macro = context->macro; macro; macro = macro->next) {
|
||||
if (macro->name == macro_name) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!macro) {
|
||||
if (behaviour == sl_pp_macro_expand_unknown_to_0) {
|
||||
if (_out_number(context, state, 0)) {
|
||||
strcpy(context->error_msg, "out of memory");
|
||||
return -1;
|
||||
}
|
||||
} else if (!mute) {
|
||||
if (sl_pp_process_out(state, &input)) {
|
||||
strcpy(context->error_msg, "out of memory");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (macro->num_args >= 0) {
|
||||
if (sl_pp_token_buffer_skip_white(tokens, &input)) {
|
||||
return -1;
|
||||
}
|
||||
if (input.token != SL_PP_LPAREN) {
|
||||
strcpy(context->error_msg, "expected `('");
|
||||
return -1;
|
||||
}
|
||||
if (sl_pp_token_buffer_skip_white(tokens, &input)) {
|
||||
return -1;
|
||||
}
|
||||
sl_pp_token_buffer_unget(tokens, &input);
|
||||
}
|
||||
|
||||
if (macro->num_args > 0) {
|
||||
struct sl_pp_macro_formal_arg *formal_arg = macro->arg;
|
||||
struct sl_pp_macro **pmacro = &actual_arg;
|
||||
|
||||
for (j = 0; j < (unsigned int)macro->num_args; j++) {
|
||||
struct sl_pp_process_state arg_state;
|
||||
int done = 0;
|
||||
unsigned int paren_nesting = 0;
|
||||
struct sl_pp_token_info eof;
|
||||
|
||||
memset(&arg_state, 0, sizeof(arg_state));
|
||||
|
||||
while (!done) {
|
||||
if (sl_pp_token_buffer_get(tokens, &input)) {
|
||||
goto fail_arg;
|
||||
}
|
||||
switch (input.token) {
|
||||
case SL_PP_WHITESPACE:
|
||||
break;
|
||||
|
||||
case SL_PP_COMMA:
|
||||
if (!paren_nesting) {
|
||||
if (j < (unsigned int)macro->num_args - 1) {
|
||||
done = 1;
|
||||
} else {
|
||||
strcpy(context->error_msg, "too many actual macro arguments");
|
||||
goto fail_arg;
|
||||
}
|
||||
} else {
|
||||
if (sl_pp_process_out(&arg_state, &input)) {
|
||||
strcpy(context->error_msg, "out of memory");
|
||||
goto fail_arg;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case SL_PP_LPAREN:
|
||||
paren_nesting++;
|
||||
if (sl_pp_process_out(&arg_state, &input)) {
|
||||
goto oom_arg;
|
||||
}
|
||||
break;
|
||||
|
||||
case SL_PP_RPAREN:
|
||||
if (!paren_nesting) {
|
||||
if (j == (unsigned int)macro->num_args - 1) {
|
||||
done = 1;
|
||||
} else {
|
||||
strcpy(context->error_msg, "too few actual macro arguments");
|
||||
goto fail_arg;
|
||||
}
|
||||
} else {
|
||||
paren_nesting--;
|
||||
if (sl_pp_process_out(&arg_state, &input)) {
|
||||
goto oom_arg;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case SL_PP_IDENTIFIER:
|
||||
sl_pp_token_buffer_unget(tokens, &input);
|
||||
if (sl_pp_macro_expand(context, tokens, local, &arg_state, sl_pp_macro_expand_normal)) {
|
||||
goto fail_arg;
|
||||
}
|
||||
break;
|
||||
|
||||
case SL_PP_EOF:
|
||||
strcpy(context->error_msg, "too few actual macro arguments");
|
||||
goto fail_arg;
|
||||
|
||||
default:
|
||||
if (sl_pp_process_out(&arg_state, &input)) {
|
||||
goto oom_arg;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
eof.token = SL_PP_EOF;
|
||||
if (sl_pp_process_out(&arg_state, &eof)) {
|
||||
goto oom_arg;
|
||||
}
|
||||
|
||||
*pmacro = sl_pp_macro_new();
|
||||
if (!*pmacro) {
|
||||
goto oom_arg;
|
||||
}
|
||||
|
||||
(**pmacro).name = formal_arg->name;
|
||||
(**pmacro).body = arg_state.out;
|
||||
|
||||
formal_arg = formal_arg->next;
|
||||
pmacro = &(**pmacro).next;
|
||||
|
||||
continue;
|
||||
|
||||
oom_arg:
|
||||
strcpy(context->error_msg, "out of memory");
|
||||
fail_arg:
|
||||
free(arg_state.out);
|
||||
goto fail;
|
||||
}
|
||||
}
|
||||
|
||||
/* Right paren for non-empty argument list has already been eaten. */
|
||||
if (macro->num_args == 0) {
|
||||
if (sl_pp_token_buffer_skip_white(tokens, &input)) {
|
||||
goto fail;
|
||||
}
|
||||
if (input.token != SL_PP_RPAREN) {
|
||||
strcpy(context->error_msg, "expected `)'");
|
||||
goto fail;
|
||||
}
|
||||
}
|
||||
|
||||
/* XXX: This is all wrong, we should be ungetting all tokens
|
||||
* back to the main token buffer.
|
||||
*/
|
||||
{
|
||||
struct sl_pp_token_buffer buffer;
|
||||
|
||||
/* Seek to the end.
|
||||
*/
|
||||
for (j = 0; macro->body[j].token != SL_PP_EOF; j++) {
|
||||
}
|
||||
j++;
|
||||
|
||||
/* Create a context-less token buffer since we are not going to underrun
|
||||
* its internal buffer.
|
||||
*/
|
||||
if (sl_pp_token_buffer_init(&buffer, NULL)) {
|
||||
strcpy(context->error_msg, "out of memory");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
/* Unget the tokens in reverse order so later they will be fetched correctly.
|
||||
*/
|
||||
for (; j > 0; j--) {
|
||||
sl_pp_token_buffer_unget(&buffer, ¯o->body[j - 1]);
|
||||
}
|
||||
|
||||
/* Expand.
|
||||
*/
|
||||
for (;;) {
|
||||
struct sl_pp_token_info input;
|
||||
|
||||
sl_pp_token_buffer_get(&buffer, &input);
|
||||
switch (input.token) {
|
||||
case SL_PP_NEWLINE:
|
||||
if (sl_pp_process_out(state, &input)) {
|
||||
strcpy(context->error_msg, "out of memory");
|
||||
sl_pp_token_buffer_destroy(&buffer);
|
||||
goto fail;
|
||||
}
|
||||
break;
|
||||
|
||||
case SL_PP_IDENTIFIER:
|
||||
sl_pp_token_buffer_unget(&buffer, &input);
|
||||
if (sl_pp_macro_expand(context, &buffer, actual_arg, state, behaviour)) {
|
||||
sl_pp_token_buffer_destroy(&buffer);
|
||||
goto fail;
|
||||
}
|
||||
break;
|
||||
|
||||
case SL_PP_EOF:
|
||||
sl_pp_token_buffer_destroy(&buffer);
|
||||
sl_pp_macro_free(actual_arg);
|
||||
return 0;
|
||||
|
||||
default:
|
||||
if (!mute) {
|
||||
if (sl_pp_process_out(state, &input)) {
|
||||
strcpy(context->error_msg, "out of memory");
|
||||
sl_pp_token_buffer_destroy(&buffer);
|
||||
goto fail;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fail:
|
||||
sl_pp_macro_free(actual_arg);
|
||||
return -1;
|
||||
}
|
|
@ -1,70 +0,0 @@
|
|||
/**************************************************************************
|
||||
*
|
||||
* Copyright 2009 VMware, Inc.
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sub license, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the
|
||||
* next paragraph) shall be included in all copies or substantial portions
|
||||
* of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
|
||||
* IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
|
||||
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
**************************************************************************/
|
||||
|
||||
#ifndef SL_PP_MACRO_H
|
||||
#define SL_PP_MACRO_H
|
||||
|
||||
struct sl_pp_context;
|
||||
struct sl_pp_process_state;
|
||||
struct sl_pp_token_buffer;
|
||||
|
||||
struct sl_pp_macro_formal_arg {
|
||||
int name;
|
||||
struct sl_pp_macro_formal_arg *next;
|
||||
};
|
||||
|
||||
struct sl_pp_macro {
|
||||
int name;
|
||||
int num_args; /* -1 means no args, 0 means `()' */
|
||||
struct sl_pp_macro_formal_arg *arg;
|
||||
struct sl_pp_token_info *body;
|
||||
struct sl_pp_macro *next;
|
||||
};
|
||||
|
||||
struct sl_pp_macro *
|
||||
sl_pp_macro_new(void);
|
||||
|
||||
void
|
||||
sl_pp_macro_free(struct sl_pp_macro *macro);
|
||||
|
||||
void
|
||||
sl_pp_macro_reset(struct sl_pp_macro *macro);
|
||||
|
||||
enum sl_pp_macro_expand_behaviour {
|
||||
sl_pp_macro_expand_normal,
|
||||
sl_pp_macro_expand_mute,
|
||||
sl_pp_macro_expand_unknown_to_0
|
||||
};
|
||||
|
||||
int
|
||||
sl_pp_macro_expand(struct sl_pp_context *context,
|
||||
struct sl_pp_token_buffer *tokens,
|
||||
struct sl_pp_macro *local,
|
||||
struct sl_pp_process_state *state,
|
||||
enum sl_pp_macro_expand_behaviour behaviour);
|
||||
|
||||
#endif /* SL_PP_MACRO_H */
|
|
@ -1,110 +0,0 @@
|
|||
/**************************************************************************
|
||||
*
|
||||
* Copyright 2009 VMware, Inc.
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sub license, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the
|
||||
* next paragraph) shall be included in all copies or substantial portions
|
||||
* of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
|
||||
* IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
|
||||
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
**************************************************************************/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "sl_pp_context.h"
|
||||
#include "sl_pp_process.h"
|
||||
#include "sl_pp_token.h"
|
||||
|
||||
|
||||
int
|
||||
sl_pp_process_pragma(struct sl_pp_context *context,
|
||||
const struct sl_pp_token_info *input,
|
||||
unsigned int first,
|
||||
unsigned int last,
|
||||
struct sl_pp_process_state *state)
|
||||
{
|
||||
int pragma_name = -1;
|
||||
struct sl_pp_token_info out;
|
||||
int arg_name = -1;
|
||||
|
||||
if (first < last && input[first].token == SL_PP_IDENTIFIER) {
|
||||
pragma_name = input[first].data.identifier;
|
||||
first++;
|
||||
}
|
||||
if (pragma_name == -1) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (pragma_name == context->dict.optimize) {
|
||||
out.token = SL_PP_PRAGMA_OPTIMIZE;
|
||||
} else if (pragma_name == context->dict.debug) {
|
||||
out.token = SL_PP_PRAGMA_DEBUG;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
|
||||
while (first < last && input[first].token == SL_PP_WHITESPACE) {
|
||||
first++;
|
||||
}
|
||||
|
||||
if (first < last && input[first].token == SL_PP_LPAREN) {
|
||||
first++;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
|
||||
while (first < last && input[first].token == SL_PP_WHITESPACE) {
|
||||
first++;
|
||||
}
|
||||
|
||||
if (first < last && input[first].token == SL_PP_IDENTIFIER) {
|
||||
arg_name = input[first].data.identifier;
|
||||
first++;
|
||||
}
|
||||
if (arg_name == -1) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (arg_name == context->dict.off) {
|
||||
out.data.pragma = 0;
|
||||
} else if (arg_name == context->dict.on) {
|
||||
out.data.pragma = 1;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
|
||||
while (first < last && input[first].token == SL_PP_WHITESPACE) {
|
||||
first++;
|
||||
}
|
||||
|
||||
if (first < last && input[first].token == SL_PP_RPAREN) {
|
||||
first++;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Ignore the tokens that follow. */
|
||||
|
||||
if (sl_pp_process_out(state, &out)) {
|
||||
strcpy(context->error_msg, "out of memory");
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -1,331 +0,0 @@
|
|||
/**************************************************************************
|
||||
*
|
||||
* Copyright 2009 VMware, Inc.
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sub license, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the
|
||||
* next paragraph) shall be included in all copies or substantial portions
|
||||
* of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
|
||||
* IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
|
||||
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
**************************************************************************/
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "sl_pp_context.h"
|
||||
#include "sl_pp_macro.h"
|
||||
#include "sl_pp_process.h"
|
||||
#include "sl_pp_public.h"
|
||||
#include "sl_pp_token.h"
|
||||
|
||||
|
||||
int
|
||||
sl_pp_process_out(struct sl_pp_process_state *state,
|
||||
const struct sl_pp_token_info *token)
|
||||
{
|
||||
if (state->out_len >= state->out_max) {
|
||||
unsigned int new_max = state->out_max;
|
||||
|
||||
if (new_max < 0x100) {
|
||||
new_max = 0x100;
|
||||
} else if (new_max < 0x10000) {
|
||||
new_max *= 2;
|
||||
} else {
|
||||
new_max += 0x10000;
|
||||
}
|
||||
|
||||
state->out = realloc(state->out, new_max * sizeof(struct sl_pp_token_info));
|
||||
if (!state->out) {
|
||||
return -1;
|
||||
}
|
||||
state->out_max = new_max;
|
||||
}
|
||||
|
||||
state->out[state->out_len++] = *token;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
sl_pp_process_get(struct sl_pp_context *context,
|
||||
struct sl_pp_token_info *output)
|
||||
{
|
||||
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(&context->process_state, &ti)) {
|
||||
strcpy(context->error_msg, "out of memory");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (;;) {
|
||||
struct sl_pp_token_info input;
|
||||
int found_eof = 0;
|
||||
|
||||
if (context->process_state.out_len) {
|
||||
assert(context->process_state.out);
|
||||
*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;
|
||||
}
|
||||
if (input.token == SL_PP_HASH) {
|
||||
if (sl_pp_token_buffer_skip_white(&context->tokens, &input)) {
|
||||
return -1;
|
||||
}
|
||||
switch (input.token) {
|
||||
case SL_PP_IDENTIFIER:
|
||||
{
|
||||
int name;
|
||||
int found_eol = 0;
|
||||
struct sl_pp_token_info endof;
|
||||
struct sl_pp_token_peek peek;
|
||||
int result = 0;
|
||||
|
||||
/* Directive name. */
|
||||
name = input.data.identifier;
|
||||
|
||||
if (sl_pp_token_buffer_skip_white(&context->tokens, &input)) {
|
||||
return -1;
|
||||
}
|
||||
sl_pp_token_buffer_unget(&context->tokens, &input);
|
||||
|
||||
if (sl_pp_token_peek_init(&peek, &context->tokens)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
while (!found_eol) {
|
||||
if (sl_pp_token_peek_get(&peek, &input)) {
|
||||
sl_pp_token_peek_destroy(&peek);
|
||||
return -1;
|
||||
}
|
||||
switch (input.token) {
|
||||
case SL_PP_NEWLINE:
|
||||
/* Preserve newline just for the sake of line numbering. */
|
||||
endof = input;
|
||||
found_eol = 1;
|
||||
break;
|
||||
|
||||
case SL_PP_EOF:
|
||||
endof = input;
|
||||
found_eof = 1;
|
||||
found_eol = 1;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (name == context->dict._if) {
|
||||
struct sl_pp_token_buffer buffer;
|
||||
|
||||
result = sl_pp_token_peek_to_buffer(&peek, &buffer);
|
||||
if (result == 0) {
|
||||
result = sl_pp_process_if(context, &buffer);
|
||||
sl_pp_token_buffer_destroy(&buffer);
|
||||
}
|
||||
} else if (name == context->dict.ifdef) {
|
||||
result = sl_pp_process_ifdef(context, peek.tokens, 0, peek.size - 1);
|
||||
} else if (name == context->dict.ifndef) {
|
||||
result = sl_pp_process_ifndef(context, peek.tokens, 0, peek.size - 1);
|
||||
} else if (name == context->dict.elif) {
|
||||
struct sl_pp_token_buffer buffer;
|
||||
|
||||
result = sl_pp_token_peek_to_buffer(&peek, &buffer);
|
||||
if (result == 0) {
|
||||
result = sl_pp_process_elif(context, &buffer);
|
||||
sl_pp_token_buffer_destroy(&buffer);
|
||||
}
|
||||
} else if (name == context->dict._else) {
|
||||
result = sl_pp_process_else(context, peek.tokens, 0, peek.size - 1);
|
||||
} else if (name == context->dict.endif) {
|
||||
result = sl_pp_process_endif(context, peek.tokens, 0, peek.size - 1);
|
||||
} else if (context->if_value) {
|
||||
if (name == context->dict.define) {
|
||||
result = sl_pp_process_define(context, peek.tokens, 0, peek.size - 1);
|
||||
} else if (name == context->dict.error) {
|
||||
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, &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, &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, &context->process_state);
|
||||
} else if (name == context->dict.undef) {
|
||||
result = sl_pp_process_undef(context, peek.tokens, 0, peek.size - 1);
|
||||
} else {
|
||||
strcpy(context->error_msg, "unrecognised directive name");
|
||||
result = -1;
|
||||
}
|
||||
}
|
||||
|
||||
sl_pp_token_peek_commit(&peek);
|
||||
sl_pp_token_peek_destroy(&peek);
|
||||
|
||||
if (result) {
|
||||
return result;
|
||||
}
|
||||
|
||||
if (sl_pp_process_out(&context->process_state, &endof)) {
|
||||
strcpy(context->error_msg, "out of memory");
|
||||
return -1;
|
||||
}
|
||||
context->line++;
|
||||
}
|
||||
break;
|
||||
|
||||
case SL_PP_NEWLINE:
|
||||
/* Empty directive. */
|
||||
if (sl_pp_process_out(&context->process_state, &input)) {
|
||||
strcpy(context->error_msg, "out of memory");
|
||||
return -1;
|
||||
}
|
||||
context->line++;
|
||||
break;
|
||||
|
||||
case SL_PP_EOF:
|
||||
/* Empty directive. */
|
||||
if (sl_pp_process_out(&context->process_state, &input)) {
|
||||
strcpy(context->error_msg, "out of memory");
|
||||
return -1;
|
||||
}
|
||||
found_eof = 1;
|
||||
break;
|
||||
|
||||
default:
|
||||
strcpy(context->error_msg, "expected a directive name");
|
||||
return -1;
|
||||
}
|
||||
} else {
|
||||
int found_eol = 0;
|
||||
|
||||
sl_pp_token_buffer_unget(&context->tokens, &input);
|
||||
|
||||
while (!found_eol) {
|
||||
if (sl_pp_token_buffer_get(&context->tokens, &input)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
switch (input.token) {
|
||||
case SL_PP_WHITESPACE:
|
||||
/* Drop whitespace all together at this point. */
|
||||
break;
|
||||
|
||||
case SL_PP_NEWLINE:
|
||||
/* Preserve newline just for the sake of line numbering. */
|
||||
if (sl_pp_process_out(&context->process_state, &input)) {
|
||||
strcpy(context->error_msg, "out of memory");
|
||||
return -1;
|
||||
}
|
||||
context->line++;
|
||||
found_eol = 1;
|
||||
break;
|
||||
|
||||
case SL_PP_EOF:
|
||||
if (sl_pp_process_out(&context->process_state, &input)) {
|
||||
strcpy(context->error_msg, "out of memory");
|
||||
return -1;
|
||||
}
|
||||
found_eof = 1;
|
||||
found_eol = 1;
|
||||
break;
|
||||
|
||||
case SL_PP_IDENTIFIER:
|
||||
sl_pp_token_buffer_unget(&context->tokens, &input);
|
||||
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;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
if (context->if_value) {
|
||||
if (sl_pp_process_out(&context->process_state, &input)) {
|
||||
strcpy(context->error_msg, "out of memory");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (found_eof) {
|
||||
if (context->if_ptr != SL_PP_MAX_IF_NESTING) {
|
||||
strcpy(context->error_msg, "expected `#endif' directive");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,113 +0,0 @@
|
|||
/**************************************************************************
|
||||
*
|
||||
* Copyright 2009 VMware, Inc.
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sub license, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the
|
||||
* next paragraph) shall be included in all copies or substantial portions
|
||||
* of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
|
||||
* IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
|
||||
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
**************************************************************************/
|
||||
|
||||
#ifndef SL_PP_PROCESS_H
|
||||
#define SL_PP_PROCESS_H
|
||||
|
||||
struct sl_pp_context;
|
||||
struct sl_pp_token_buffer;
|
||||
|
||||
struct sl_pp_process_state {
|
||||
struct sl_pp_token_info *out;
|
||||
unsigned int out_len;
|
||||
unsigned int out_max;
|
||||
};
|
||||
|
||||
int
|
||||
sl_pp_process_define(struct sl_pp_context *context,
|
||||
const struct sl_pp_token_info *input,
|
||||
unsigned int first,
|
||||
unsigned int last);
|
||||
|
||||
int
|
||||
sl_pp_process_undef(struct sl_pp_context *context,
|
||||
const struct sl_pp_token_info *input,
|
||||
unsigned int first,
|
||||
unsigned int last);
|
||||
|
||||
int
|
||||
sl_pp_process_if(struct sl_pp_context *context,
|
||||
struct sl_pp_token_buffer *input);
|
||||
|
||||
int
|
||||
sl_pp_process_ifdef(struct sl_pp_context *context,
|
||||
const struct sl_pp_token_info *input,
|
||||
unsigned int first,
|
||||
unsigned int last);
|
||||
|
||||
int
|
||||
sl_pp_process_ifndef(struct sl_pp_context *context,
|
||||
const struct sl_pp_token_info *input,
|
||||
unsigned int first,
|
||||
unsigned int last);
|
||||
|
||||
int
|
||||
sl_pp_process_elif(struct sl_pp_context *context,
|
||||
struct sl_pp_token_buffer *buffer);
|
||||
|
||||
int
|
||||
sl_pp_process_else(struct sl_pp_context *context,
|
||||
const struct sl_pp_token_info *input,
|
||||
unsigned int first,
|
||||
unsigned int last);
|
||||
|
||||
int
|
||||
sl_pp_process_endif(struct sl_pp_context *context,
|
||||
const struct sl_pp_token_info *input,
|
||||
unsigned int first,
|
||||
unsigned int last);
|
||||
|
||||
void
|
||||
sl_pp_process_error(struct sl_pp_context *context,
|
||||
const struct sl_pp_token_info *input,
|
||||
unsigned int first,
|
||||
unsigned int last);
|
||||
|
||||
int
|
||||
sl_pp_process_pragma(struct sl_pp_context *context,
|
||||
const struct sl_pp_token_info *input,
|
||||
unsigned int first,
|
||||
unsigned int last,
|
||||
struct sl_pp_process_state *state);
|
||||
|
||||
int
|
||||
sl_pp_process_extension(struct sl_pp_context *context,
|
||||
const struct sl_pp_token_info *input,
|
||||
unsigned int first,
|
||||
unsigned int last,
|
||||
struct sl_pp_process_state *state);
|
||||
|
||||
int
|
||||
sl_pp_process_line(struct sl_pp_context *context,
|
||||
struct sl_pp_token_buffer *buffer,
|
||||
struct sl_pp_process_state *state);
|
||||
|
||||
int
|
||||
sl_pp_process_out(struct sl_pp_process_state *state,
|
||||
const struct sl_pp_token_info *token);
|
||||
|
||||
#endif /* SL_PP_PROCESS_H */
|
|
@ -1,79 +0,0 @@
|
|||
/**************************************************************************
|
||||
*
|
||||
* Copyright 2009 VMware, Inc.
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sub license, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the
|
||||
* next paragraph) shall be included in all copies or substantial portions
|
||||
* of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
|
||||
* IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
|
||||
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
**************************************************************************/
|
||||
|
||||
#ifndef SL_PP_PUBLIC_H
|
||||
#define SL_PP_PUBLIC_H
|
||||
|
||||
struct sl_pp_context;
|
||||
struct sl_pp_purify_options;
|
||||
struct sl_pp_token_info;
|
||||
|
||||
struct sl_pp_context *
|
||||
sl_pp_context_create(const char *input,
|
||||
const struct sl_pp_purify_options *options);
|
||||
|
||||
void
|
||||
sl_pp_context_destroy(struct sl_pp_context *context);
|
||||
|
||||
const char *
|
||||
sl_pp_context_error_message(const struct sl_pp_context *context);
|
||||
|
||||
void
|
||||
sl_pp_context_error_position(const struct sl_pp_context *context,
|
||||
unsigned int *file,
|
||||
unsigned int *line);
|
||||
|
||||
int
|
||||
sl_pp_context_add_extension(struct sl_pp_context *context,
|
||||
const char *name);
|
||||
|
||||
int
|
||||
sl_pp_context_add_predefined(struct sl_pp_context *context,
|
||||
const char *name,
|
||||
const char *value);
|
||||
|
||||
int
|
||||
sl_pp_context_add_unique_str(struct sl_pp_context *context,
|
||||
const char *str);
|
||||
|
||||
const char *
|
||||
sl_pp_context_cstr(const struct sl_pp_context *context,
|
||||
int offset);
|
||||
|
||||
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);
|
||||
|
||||
#endif /* SL_PP_PUBLIC_H */
|
|
@ -1,302 +0,0 @@
|
|||
/**************************************************************************
|
||||
*
|
||||
* Copyright 2009 VMware, Inc.
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sub license, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the
|
||||
* next paragraph) shall be included in all copies or substantial portions
|
||||
* of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
|
||||
* IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
|
||||
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
**************************************************************************/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include "sl_pp_purify.h"
|
||||
|
||||
|
||||
/*
|
||||
* Preprocessor purifier performs the following tasks.
|
||||
* - Convert all variants of newlines into a Unix newline.
|
||||
* - Merge continued lines into a single long line.
|
||||
* - Remove line comments and replace block comments with whitespace.
|
||||
*/
|
||||
|
||||
|
||||
static unsigned int
|
||||
_purify_newline(const char *input,
|
||||
char *out,
|
||||
unsigned int *current_line)
|
||||
{
|
||||
if (input[0] == '\n') {
|
||||
*out = '\n';
|
||||
(*current_line)++;
|
||||
if (input[1] == '\r') {
|
||||
/*
|
||||
* The GLSL spec is not explicit about whether this
|
||||
* combination is a valid newline or not.
|
||||
* Let's assume it is acceptable.
|
||||
*/
|
||||
return 2;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
if (input[0] == '\r') {
|
||||
*out = '\n';
|
||||
(*current_line)++;
|
||||
if (input[1] == '\n') {
|
||||
return 2;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
*out = input[0];
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
static unsigned int
|
||||
_purify_backslash(const char *input,
|
||||
char *out,
|
||||
unsigned int *current_line)
|
||||
{
|
||||
unsigned int eaten = 0;
|
||||
|
||||
for (;;) {
|
||||
if (input[0] == '\\') {
|
||||
char next;
|
||||
unsigned int next_eaten;
|
||||
unsigned int next_line = *current_line;
|
||||
|
||||
eaten++;
|
||||
input++;
|
||||
|
||||
next_eaten = _purify_newline(input, &next, &next_line);
|
||||
if (next == '\n') {
|
||||
/*
|
||||
* If this is really a line continuation sequence, eat
|
||||
* it and do not exit the loop.
|
||||
*/
|
||||
eaten += next_eaten;
|
||||
input += next_eaten;
|
||||
*current_line = next_line;
|
||||
} else {
|
||||
/*
|
||||
* It is an error to put anything between a backslash
|
||||
* and a newline and still expect it to behave like a line
|
||||
* continuation sequence.
|
||||
* Even if it is an innocent whitespace.
|
||||
*/
|
||||
*out = '\\';
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
eaten += _purify_newline(input, out, current_line);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return eaten;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
_report_error(char *buf,
|
||||
unsigned int cbbuf,
|
||||
const char *msg,
|
||||
...)
|
||||
{
|
||||
va_list args;
|
||||
|
||||
va_start(args, msg);
|
||||
vsnprintf(buf, cbbuf, msg, args);
|
||||
va_end(args);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
sl_pp_purify_state_init(struct sl_pp_purify_state *state,
|
||||
const char *input,
|
||||
const struct sl_pp_purify_options *options)
|
||||
{
|
||||
state->options = *options;
|
||||
state->input = input;
|
||||
state->current_line = 1;
|
||||
state->inside_c_comment = 0;
|
||||
}
|
||||
|
||||
|
||||
static unsigned int
|
||||
_purify_comment(struct sl_pp_purify_state *state,
|
||||
char *output,
|
||||
unsigned int *current_line,
|
||||
char *errormsg,
|
||||
unsigned int cberrormsg)
|
||||
{
|
||||
for (;;) {
|
||||
unsigned int eaten;
|
||||
char next;
|
||||
|
||||
eaten = _purify_backslash(state->input, &next, current_line);
|
||||
state->input += eaten;
|
||||
while (next == '*') {
|
||||
eaten = _purify_backslash(state->input, &next, current_line);
|
||||
state->input += eaten;
|
||||
if (next == '/') {
|
||||
*output = ' ';
|
||||
state->inside_c_comment = 0;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
if (next == '\n') {
|
||||
*output = '\n';
|
||||
state->inside_c_comment = 1;
|
||||
return 1;
|
||||
}
|
||||
if (next == '\0') {
|
||||
_report_error(errormsg, cberrormsg, "expected `*/' but end of translation unit found");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
unsigned int
|
||||
sl_pp_purify_getc(struct sl_pp_purify_state *state,
|
||||
char *output,
|
||||
unsigned int *current_line,
|
||||
char *errormsg,
|
||||
unsigned int cberrormsg)
|
||||
{
|
||||
unsigned int eaten;
|
||||
|
||||
if (state->inside_c_comment) {
|
||||
return _purify_comment(state, output, current_line, errormsg, cberrormsg);
|
||||
}
|
||||
|
||||
eaten = _purify_backslash(state->input, output, current_line);
|
||||
state->input += eaten;
|
||||
if (*output == '/') {
|
||||
char next;
|
||||
unsigned int next_line = *current_line;
|
||||
|
||||
eaten = _purify_backslash(state->input, &next, &next_line);
|
||||
if (next == '/') {
|
||||
state->input += eaten;
|
||||
*current_line = next_line;
|
||||
|
||||
/* Replace a line comment with either a newline or nil. */
|
||||
for (;;) {
|
||||
eaten = _purify_backslash(state->input, &next, current_line);
|
||||
state->input += eaten;
|
||||
if (next == '\n' || next == '\0') {
|
||||
*output = next;
|
||||
return eaten;
|
||||
}
|
||||
}
|
||||
} else if (next == '*') {
|
||||
state->input += eaten;
|
||||
*current_line = next_line;
|
||||
|
||||
return _purify_comment(state, output, current_line, errormsg, cberrormsg);
|
||||
}
|
||||
}
|
||||
return eaten;
|
||||
}
|
||||
|
||||
|
||||
struct out_buf {
|
||||
char *out;
|
||||
unsigned int len;
|
||||
unsigned int capacity;
|
||||
unsigned int current_line;
|
||||
char *errormsg;
|
||||
unsigned int cberrormsg;
|
||||
};
|
||||
|
||||
|
||||
static int
|
||||
_out_buf_putc(struct out_buf *obuf,
|
||||
char c)
|
||||
{
|
||||
if (obuf->len >= obuf->capacity) {
|
||||
unsigned int new_max = obuf->capacity;
|
||||
|
||||
if (new_max < 0x100) {
|
||||
new_max = 0x100;
|
||||
} else if (new_max < 0x10000) {
|
||||
new_max *= 2;
|
||||
} else {
|
||||
new_max += 0x10000;
|
||||
}
|
||||
|
||||
obuf->out = realloc(obuf->out, new_max);
|
||||
if (!obuf->out) {
|
||||
_report_error(obuf->errormsg, obuf->cberrormsg, "out of memory");
|
||||
return -1;
|
||||
}
|
||||
obuf->capacity = new_max;
|
||||
}
|
||||
|
||||
obuf->out[obuf->len++] = c;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
sl_pp_purify(const char *input,
|
||||
const struct sl_pp_purify_options *options,
|
||||
char **output,
|
||||
char *errormsg,
|
||||
unsigned int cberrormsg,
|
||||
unsigned int *errorline)
|
||||
{
|
||||
struct out_buf obuf;
|
||||
struct sl_pp_purify_state state;
|
||||
|
||||
obuf.out = NULL;
|
||||
obuf.len = 0;
|
||||
obuf.capacity = 0;
|
||||
obuf.current_line = 1;
|
||||
obuf.errormsg = errormsg;
|
||||
obuf.cberrormsg = cberrormsg;
|
||||
|
||||
sl_pp_purify_state_init(&state, input, options);
|
||||
|
||||
for (;;) {
|
||||
unsigned int eaten;
|
||||
char c;
|
||||
|
||||
eaten = sl_pp_purify_getc(&state, &c, &obuf.current_line, errormsg, cberrormsg);
|
||||
if (!eaten) {
|
||||
*errorline = obuf.current_line;
|
||||
return -1;
|
||||
}
|
||||
if (_out_buf_putc(&obuf, c)) {
|
||||
*errorline = obuf.current_line;
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (c == '\0') {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
*output = obuf.out;
|
||||
return 0;
|
||||
}
|
|
@ -1,63 +0,0 @@
|
|||
/**************************************************************************
|
||||
*
|
||||
* Copyright 2009 VMware, Inc.
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sub license, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the
|
||||
* next paragraph) shall be included in all copies or substantial portions
|
||||
* of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
|
||||
* IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
|
||||
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
**************************************************************************/
|
||||
|
||||
#ifndef SL_PP_PURIFY_H
|
||||
#define SL_PP_PURIFY_H
|
||||
|
||||
struct sl_pp_purify_options {
|
||||
unsigned int preserve_columns:1;
|
||||
unsigned int tab_width:4;
|
||||
};
|
||||
|
||||
int
|
||||
sl_pp_purify(const char *input,
|
||||
const struct sl_pp_purify_options *options,
|
||||
char **output,
|
||||
char *errormsg,
|
||||
unsigned int cberrormsg,
|
||||
unsigned int *errorline);
|
||||
|
||||
struct sl_pp_purify_state {
|
||||
struct sl_pp_purify_options options;
|
||||
const char *input;
|
||||
unsigned int current_line;
|
||||
unsigned int inside_c_comment:1;
|
||||
};
|
||||
|
||||
void
|
||||
sl_pp_purify_state_init(struct sl_pp_purify_state *state,
|
||||
const char *input,
|
||||
const struct sl_pp_purify_options *options);
|
||||
|
||||
unsigned int
|
||||
sl_pp_purify_getc(struct sl_pp_purify_state *state,
|
||||
char *output,
|
||||
unsigned int *current_line,
|
||||
char *errormsg,
|
||||
unsigned int cberrormsg);
|
||||
|
||||
#endif /* SL_PP_PURIFY_H */
|
|
@ -1,854 +0,0 @@
|
|||
/**************************************************************************
|
||||
*
|
||||
* Copyright 2009 VMware, Inc.
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sub license, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the
|
||||
* next paragraph) shall be included in all copies or substantial portions
|
||||
* of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
|
||||
* IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
|
||||
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
**************************************************************************/
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "sl_pp_public.h"
|
||||
#include "sl_pp_context.h"
|
||||
#include "sl_pp_token.h"
|
||||
|
||||
|
||||
#define PURE_ERROR 256
|
||||
|
||||
static int
|
||||
_pure_getc(struct sl_pp_context *context)
|
||||
{
|
||||
char c;
|
||||
|
||||
if (context->getc_buf_size) {
|
||||
return context->getc_buf[--context->getc_buf_size];
|
||||
}
|
||||
|
||||
if (sl_pp_purify_getc(&context->pure, &c, &context->error_line, context->error_msg, sizeof(context->error_msg)) == 0) {
|
||||
return PURE_ERROR;
|
||||
}
|
||||
return c;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
_pure_ungetc(struct sl_pp_context *context,
|
||||
int c)
|
||||
{
|
||||
assert(c != PURE_ERROR);
|
||||
|
||||
if (context->getc_buf_size == context->getc_buf_capacity) {
|
||||
context->getc_buf_capacity += 64;
|
||||
context->getc_buf = realloc(context->getc_buf, context->getc_buf_capacity * sizeof(char));
|
||||
assert(context->getc_buf);
|
||||
}
|
||||
|
||||
context->getc_buf[context->getc_buf_size++] = (char)c;
|
||||
}
|
||||
|
||||
|
||||
struct lookahead_state {
|
||||
char buf[256];
|
||||
unsigned int pos;
|
||||
struct sl_pp_context *context;
|
||||
};
|
||||
|
||||
|
||||
static void
|
||||
_lookahead_init(struct lookahead_state *lookahead,
|
||||
struct sl_pp_context *context)
|
||||
{
|
||||
lookahead->pos = 0;
|
||||
lookahead->context = context;
|
||||
}
|
||||
|
||||
|
||||
static unsigned int
|
||||
_lookahead_tell(const struct lookahead_state *lookahead)
|
||||
{
|
||||
return lookahead->pos;
|
||||
}
|
||||
|
||||
|
||||
static const void *
|
||||
_lookahead_buf(const struct lookahead_state *lookahead)
|
||||
{
|
||||
return lookahead->buf;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
_lookahead_revert(struct lookahead_state *lookahead,
|
||||
unsigned int pos)
|
||||
{
|
||||
assert(pos <= lookahead->pos);
|
||||
|
||||
while (lookahead->pos > pos) {
|
||||
_pure_ungetc(lookahead->context, lookahead->buf[--lookahead->pos]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
_lookahead_getc(struct lookahead_state *lookahead)
|
||||
{
|
||||
int c;
|
||||
|
||||
assert(lookahead->pos < sizeof(lookahead->buf) / sizeof(lookahead->buf[0]));
|
||||
|
||||
c = _pure_getc(lookahead->context);
|
||||
if (c != PURE_ERROR) {
|
||||
lookahead->buf[lookahead->pos++] = (char)c;
|
||||
}
|
||||
return c;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
_is_identifier_char(char c)
|
||||
{
|
||||
return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || (c >= '0' && c <= '9') || c == '_';
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
_tokenise_identifier(struct sl_pp_context *context,
|
||||
struct sl_pp_token_info *out)
|
||||
{
|
||||
int c;
|
||||
char identifier[256]; /* XXX: Remove this artifical limit. */
|
||||
unsigned int i = 0;
|
||||
|
||||
out->token = SL_PP_IDENTIFIER;
|
||||
out->data.identifier = -1;
|
||||
|
||||
c = _pure_getc(context);
|
||||
if (c == PURE_ERROR) {
|
||||
return -1;
|
||||
}
|
||||
identifier[i++] = (char)c;
|
||||
for (;;) {
|
||||
c = _pure_getc(context);
|
||||
if (c == PURE_ERROR) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (_is_identifier_char((char)c)) {
|
||||
if (i >= sizeof(identifier) / sizeof(char) - 1) {
|
||||
strcpy(context->error_msg, "out of memory");
|
||||
_pure_ungetc(context, c);
|
||||
while (i) {
|
||||
_pure_ungetc(context, identifier[--i]);
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
identifier[i++] = (char)c;
|
||||
} else {
|
||||
_pure_ungetc(context, c);
|
||||
break;
|
||||
}
|
||||
}
|
||||
identifier[i] = '\0';
|
||||
|
||||
out->data.identifier = sl_pp_context_add_unique_str(context, identifier);
|
||||
if (out->data.identifier == -1) {
|
||||
while (i) {
|
||||
_pure_ungetc(context, identifier[--i]);
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Return the number of consecutive decimal digits in the input stream.
|
||||
*/
|
||||
static unsigned int
|
||||
_parse_float_digits(struct lookahead_state *lookahead)
|
||||
{
|
||||
unsigned int eaten;
|
||||
|
||||
for (eaten = 0;; eaten++) {
|
||||
unsigned int pos = _lookahead_tell(lookahead);
|
||||
char c = _lookahead_getc(lookahead);
|
||||
|
||||
if (c < '0' || c > '9') {
|
||||
_lookahead_revert(lookahead, pos);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return eaten;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Try to match one of the following patterns for the fractional part
|
||||
* of a floating point number.
|
||||
*
|
||||
* digits . [digits]
|
||||
* . digits
|
||||
*
|
||||
* Return 0 if the pattern could not be matched, otherwise the number
|
||||
* of eaten characters from the input stream.
|
||||
*/
|
||||
static unsigned int
|
||||
_parse_float_frac(struct lookahead_state *lookahead)
|
||||
{
|
||||
unsigned int pos;
|
||||
int c;
|
||||
unsigned int eaten;
|
||||
|
||||
pos = _lookahead_tell(lookahead);
|
||||
c = _lookahead_getc(lookahead);
|
||||
if (c == '.') {
|
||||
eaten = _parse_float_digits(lookahead);
|
||||
if (eaten) {
|
||||
return eaten + 1;
|
||||
}
|
||||
_lookahead_revert(lookahead, pos);
|
||||
return 0;
|
||||
}
|
||||
|
||||
_lookahead_revert(lookahead, pos);
|
||||
eaten = _parse_float_digits(lookahead);
|
||||
if (eaten) {
|
||||
c = _lookahead_getc(lookahead);
|
||||
if (c == '.') {
|
||||
return eaten + 1 + _parse_float_digits(lookahead);
|
||||
}
|
||||
}
|
||||
|
||||
_lookahead_revert(lookahead, pos);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Try to match the following pattern for the exponential part
|
||||
* of a floating point number.
|
||||
*
|
||||
* (e|E) [(+|-)] digits
|
||||
*
|
||||
* Return 0 if the pattern could not be matched, otherwise the number
|
||||
* of eaten characters from the input stream.
|
||||
*/
|
||||
static unsigned int
|
||||
_parse_float_exp(struct lookahead_state *lookahead)
|
||||
{
|
||||
unsigned int pos, pos2;
|
||||
int c;
|
||||
unsigned int eaten, digits;
|
||||
|
||||
pos = _lookahead_tell(lookahead);
|
||||
c = _lookahead_getc(lookahead);
|
||||
if (c != 'e' && c != 'E') {
|
||||
_lookahead_revert(lookahead, pos);
|
||||
return 0;
|
||||
}
|
||||
|
||||
pos2 = _lookahead_tell(lookahead);
|
||||
c = _lookahead_getc(lookahead);
|
||||
if (c == '-' || c == '+') {
|
||||
eaten = 2;
|
||||
} else {
|
||||
_lookahead_revert(lookahead, pos2);
|
||||
eaten = 1;
|
||||
}
|
||||
|
||||
digits = _parse_float_digits(lookahead);
|
||||
if (!digits) {
|
||||
_lookahead_revert(lookahead, pos);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return eaten + digits;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Try to match one of the following patterns for a floating point number.
|
||||
*
|
||||
* fract [exp] [(f|F)]
|
||||
* digits exp [(f|F)]
|
||||
*
|
||||
* Return 0 if the pattern could not be matched, otherwise the number
|
||||
* of eaten characters from the input stream.
|
||||
*/
|
||||
static unsigned int
|
||||
_parse_float(struct lookahead_state *lookahead)
|
||||
{
|
||||
unsigned int eaten;
|
||||
|
||||
eaten = _parse_float_frac(lookahead);
|
||||
if (eaten) {
|
||||
unsigned int pos;
|
||||
int c;
|
||||
|
||||
eaten += _parse_float_exp(lookahead);
|
||||
|
||||
pos = _lookahead_tell(lookahead);
|
||||
c = _lookahead_getc(lookahead);
|
||||
if (c == 'f' || c == 'F') {
|
||||
eaten++;
|
||||
} else {
|
||||
_lookahead_revert(lookahead, pos);
|
||||
}
|
||||
|
||||
return eaten;
|
||||
}
|
||||
|
||||
eaten = _parse_float_digits(lookahead);
|
||||
if (eaten) {
|
||||
unsigned int exponent;
|
||||
|
||||
exponent = _parse_float_exp(lookahead);
|
||||
if (exponent) {
|
||||
unsigned int pos;
|
||||
int c;
|
||||
|
||||
eaten += exponent;
|
||||
|
||||
pos = _lookahead_tell(lookahead);
|
||||
c = _lookahead_getc(lookahead);
|
||||
if (c == 'f' || c == 'F') {
|
||||
eaten++;
|
||||
} else {
|
||||
_lookahead_revert(lookahead, pos);
|
||||
}
|
||||
|
||||
return eaten;
|
||||
}
|
||||
}
|
||||
|
||||
_lookahead_revert(lookahead, 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static unsigned int
|
||||
_parse_hex(struct lookahead_state *lookahead)
|
||||
{
|
||||
int c;
|
||||
unsigned int n;
|
||||
|
||||
c = _lookahead_getc(lookahead);
|
||||
if (c != '0') {
|
||||
_lookahead_revert(lookahead, 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
c = _lookahead_getc(lookahead);
|
||||
if (c != 'x' && c != 'X') {
|
||||
_lookahead_revert(lookahead, 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
for (n = 2;;) {
|
||||
unsigned int pos = _lookahead_tell(lookahead);
|
||||
|
||||
c = _lookahead_getc(lookahead);
|
||||
if ((c >= '0' && c <= '9') || (c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F')) {
|
||||
n++;
|
||||
} else {
|
||||
_lookahead_revert(lookahead, pos);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (n > 2) {
|
||||
return n;
|
||||
}
|
||||
|
||||
_lookahead_revert(lookahead, 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static unsigned int
|
||||
_parse_oct(struct lookahead_state *lookahead)
|
||||
{
|
||||
int c;
|
||||
unsigned int n;
|
||||
|
||||
c = _lookahead_getc(lookahead);
|
||||
if (c != '0') {
|
||||
_lookahead_revert(lookahead, 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
for (n = 1;;) {
|
||||
unsigned int pos = _lookahead_tell(lookahead);
|
||||
|
||||
c = _lookahead_getc(lookahead);
|
||||
if ((c >= '0' && c <= '7')) {
|
||||
n++;
|
||||
} else {
|
||||
_lookahead_revert(lookahead, pos);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return n;
|
||||
}
|
||||
|
||||
|
||||
static unsigned int
|
||||
_parse_dec(struct lookahead_state *lookahead)
|
||||
{
|
||||
unsigned int n = 0;
|
||||
|
||||
for (;;) {
|
||||
unsigned int pos = _lookahead_tell(lookahead);
|
||||
int c = _lookahead_getc(lookahead);
|
||||
|
||||
if ((c >= '0' && c <= '9')) {
|
||||
n++;
|
||||
} else {
|
||||
_lookahead_revert(lookahead, pos);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return n;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
_tokenise_number(struct sl_pp_context *context,
|
||||
struct sl_pp_token_info *out)
|
||||
{
|
||||
struct lookahead_state lookahead;
|
||||
unsigned int eaten;
|
||||
unsigned int is_float = 0;
|
||||
unsigned int pos;
|
||||
int c;
|
||||
char number[256]; /* XXX: Remove this artifical limit. */
|
||||
|
||||
_lookahead_init(&lookahead, context);
|
||||
|
||||
eaten = _parse_float(&lookahead);
|
||||
if (!eaten) {
|
||||
eaten = _parse_hex(&lookahead);
|
||||
if (!eaten) {
|
||||
eaten = _parse_oct(&lookahead);
|
||||
if (!eaten) {
|
||||
eaten = _parse_dec(&lookahead);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
is_float = 1;
|
||||
}
|
||||
|
||||
if (!eaten) {
|
||||
strcpy(context->error_msg, "expected a number");
|
||||
return -1;
|
||||
}
|
||||
|
||||
pos = _lookahead_tell(&lookahead);
|
||||
c = _lookahead_getc(&lookahead);
|
||||
_lookahead_revert(&lookahead, pos);
|
||||
|
||||
if (_is_identifier_char(c)) {
|
||||
strcpy(context->error_msg, "expected a number");
|
||||
_lookahead_revert(&lookahead, 0);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (eaten > sizeof(number) - 1) {
|
||||
strcpy(context->error_msg, "out of memory");
|
||||
_lookahead_revert(&lookahead, 0);
|
||||
return -1;
|
||||
}
|
||||
|
||||
assert(_lookahead_tell(&lookahead) == eaten);
|
||||
|
||||
memcpy(number, _lookahead_buf(&lookahead), eaten);
|
||||
number[eaten] = '\0';
|
||||
|
||||
if (is_float) {
|
||||
out->token = SL_PP_FLOAT;
|
||||
out->data._float = sl_pp_context_add_unique_str(context, number);
|
||||
if (out->data._float == -1) {
|
||||
_lookahead_revert(&lookahead, 0);
|
||||
return -1;
|
||||
}
|
||||
} else {
|
||||
out->token = SL_PP_UINT;
|
||||
out->data._uint = sl_pp_context_add_unique_str(context, number);
|
||||
if (out->data._uint == -1) {
|
||||
_lookahead_revert(&lookahead, 0);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
sl_pp_token_get(struct sl_pp_context *context,
|
||||
struct sl_pp_token_info *out)
|
||||
{
|
||||
int c = _pure_getc(context);
|
||||
|
||||
switch (c) {
|
||||
case ' ':
|
||||
case '\t':
|
||||
out->token = SL_PP_WHITESPACE;
|
||||
break;
|
||||
|
||||
case '\n':
|
||||
out->token = SL_PP_NEWLINE;
|
||||
break;
|
||||
|
||||
case '#':
|
||||
out->token = SL_PP_HASH;
|
||||
break;
|
||||
|
||||
case ',':
|
||||
out->token = SL_PP_COMMA;
|
||||
break;
|
||||
|
||||
case ';':
|
||||
out->token = SL_PP_SEMICOLON;
|
||||
break;
|
||||
|
||||
case '{':
|
||||
out->token = SL_PP_LBRACE;
|
||||
break;
|
||||
|
||||
case '}':
|
||||
out->token = SL_PP_RBRACE;
|
||||
break;
|
||||
|
||||
case '(':
|
||||
out->token = SL_PP_LPAREN;
|
||||
break;
|
||||
|
||||
case ')':
|
||||
out->token = SL_PP_RPAREN;
|
||||
break;
|
||||
|
||||
case '[':
|
||||
out->token = SL_PP_LBRACKET;
|
||||
break;
|
||||
|
||||
case ']':
|
||||
out->token = SL_PP_RBRACKET;
|
||||
break;
|
||||
|
||||
case '.':
|
||||
{
|
||||
int c2 = _pure_getc(context);
|
||||
|
||||
if (c2 == PURE_ERROR) {
|
||||
return -1;
|
||||
}
|
||||
if (c2 >= '0' && c2 <= '9') {
|
||||
_pure_ungetc(context, c2);
|
||||
_pure_ungetc(context, c);
|
||||
if (_tokenise_number(context, out)) {
|
||||
return -1;
|
||||
}
|
||||
} else {
|
||||
_pure_ungetc(context, c2);
|
||||
out->token = SL_PP_DOT;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case '+':
|
||||
c = _pure_getc(context);
|
||||
if (c == PURE_ERROR) {
|
||||
return -1;
|
||||
}
|
||||
if (c == '+') {
|
||||
out->token = SL_PP_INCREMENT;
|
||||
} else if (c == '=') {
|
||||
out->token = SL_PP_ADDASSIGN;
|
||||
} else {
|
||||
_pure_ungetc(context, c);
|
||||
out->token = SL_PP_PLUS;
|
||||
}
|
||||
break;
|
||||
|
||||
case '-':
|
||||
c = _pure_getc(context);
|
||||
if (c == PURE_ERROR) {
|
||||
return -1;
|
||||
}
|
||||
if (c == '-') {
|
||||
out->token = SL_PP_DECREMENT;
|
||||
} else if (c == '=') {
|
||||
out->token = SL_PP_SUBASSIGN;
|
||||
} else {
|
||||
_pure_ungetc(context, c);
|
||||
out->token = SL_PP_MINUS;
|
||||
}
|
||||
break;
|
||||
|
||||
case '~':
|
||||
out->token = SL_PP_BITNOT;
|
||||
break;
|
||||
|
||||
case '!':
|
||||
c = _pure_getc(context);
|
||||
if (c == PURE_ERROR) {
|
||||
return -1;
|
||||
}
|
||||
if (c == '=') {
|
||||
out->token = SL_PP_NOTEQUAL;
|
||||
} else {
|
||||
_pure_ungetc(context, c);
|
||||
out->token = SL_PP_NOT;
|
||||
}
|
||||
break;
|
||||
|
||||
case '*':
|
||||
c = _pure_getc(context);
|
||||
if (c == PURE_ERROR) {
|
||||
return -1;
|
||||
}
|
||||
if (c == '=') {
|
||||
out->token = SL_PP_MULASSIGN;
|
||||
} else {
|
||||
_pure_ungetc(context, c);
|
||||
out->token = SL_PP_STAR;
|
||||
}
|
||||
break;
|
||||
|
||||
case '/':
|
||||
c = _pure_getc(context);
|
||||
if (c == PURE_ERROR) {
|
||||
return -1;
|
||||
}
|
||||
if (c == '=') {
|
||||
out->token = SL_PP_DIVASSIGN;
|
||||
} else {
|
||||
_pure_ungetc(context, c);
|
||||
out->token = SL_PP_SLASH;
|
||||
}
|
||||
break;
|
||||
|
||||
case '%':
|
||||
c = _pure_getc(context);
|
||||
if (c == PURE_ERROR) {
|
||||
return -1;
|
||||
}
|
||||
if (c == '=') {
|
||||
out->token = SL_PP_MODASSIGN;
|
||||
} else {
|
||||
_pure_ungetc(context, c);
|
||||
out->token = SL_PP_MODULO;
|
||||
}
|
||||
break;
|
||||
|
||||
case '<':
|
||||
c = _pure_getc(context);
|
||||
if (c == PURE_ERROR) {
|
||||
return -1;
|
||||
}
|
||||
if (c == '<') {
|
||||
c = _pure_getc(context);
|
||||
if (c == PURE_ERROR) {
|
||||
return -1;
|
||||
}
|
||||
if (c == '=') {
|
||||
out->token = SL_PP_LSHIFTASSIGN;
|
||||
} else {
|
||||
_pure_ungetc(context, c);
|
||||
out->token = SL_PP_LSHIFT;
|
||||
}
|
||||
} else if (c == '=') {
|
||||
out->token = SL_PP_LESSEQUAL;
|
||||
} else {
|
||||
_pure_ungetc(context, c);
|
||||
out->token = SL_PP_LESS;
|
||||
}
|
||||
break;
|
||||
|
||||
case '>':
|
||||
c = _pure_getc(context);
|
||||
if (c == PURE_ERROR) {
|
||||
return -1;
|
||||
}
|
||||
if (c == '>') {
|
||||
c = _pure_getc(context);
|
||||
if (c == PURE_ERROR) {
|
||||
return -1;
|
||||
}
|
||||
if (c == '=') {
|
||||
out->token = SL_PP_RSHIFTASSIGN;
|
||||
} else {
|
||||
_pure_ungetc(context, c);
|
||||
out->token = SL_PP_RSHIFT;
|
||||
}
|
||||
} else if (c == '=') {
|
||||
out->token = SL_PP_GREATEREQUAL;
|
||||
} else {
|
||||
_pure_ungetc(context, c);
|
||||
out->token = SL_PP_GREATER;
|
||||
}
|
||||
break;
|
||||
|
||||
case '=':
|
||||
c = _pure_getc(context);
|
||||
if (c == PURE_ERROR) {
|
||||
return -1;
|
||||
}
|
||||
if (c == '=') {
|
||||
out->token = SL_PP_EQUAL;
|
||||
} else {
|
||||
_pure_ungetc(context, c);
|
||||
out->token = SL_PP_ASSIGN;
|
||||
}
|
||||
break;
|
||||
|
||||
case '&':
|
||||
c = _pure_getc(context);
|
||||
if (c == PURE_ERROR) {
|
||||
return -1;
|
||||
}
|
||||
if (c == '&') {
|
||||
out->token = SL_PP_AND;
|
||||
} else if (c == '=') {
|
||||
out->token = SL_PP_BITANDASSIGN;
|
||||
} else {
|
||||
_pure_ungetc(context, c);
|
||||
out->token = SL_PP_BITAND;
|
||||
}
|
||||
break;
|
||||
|
||||
case '^':
|
||||
c = _pure_getc(context);
|
||||
if (c == PURE_ERROR) {
|
||||
return -1;
|
||||
}
|
||||
if (c == '^') {
|
||||
out->token = SL_PP_XOR;
|
||||
} else if (c == '=') {
|
||||
out->token = SL_PP_BITXORASSIGN;
|
||||
} else {
|
||||
_pure_ungetc(context, c);
|
||||
out->token = SL_PP_BITXOR;
|
||||
}
|
||||
break;
|
||||
|
||||
case '|':
|
||||
c = _pure_getc(context);
|
||||
if (c == PURE_ERROR) {
|
||||
return -1;
|
||||
}
|
||||
if (c == '|') {
|
||||
out->token = SL_PP_OR;
|
||||
} else if (c == '=') {
|
||||
out->token = SL_PP_BITORASSIGN;
|
||||
} else {
|
||||
_pure_ungetc(context, c);
|
||||
out->token = SL_PP_BITOR;
|
||||
}
|
||||
break;
|
||||
|
||||
case '?':
|
||||
out->token = SL_PP_QUESTION;
|
||||
break;
|
||||
|
||||
case ':':
|
||||
out->token = SL_PP_COLON;
|
||||
break;
|
||||
|
||||
case '\0':
|
||||
out->token = SL_PP_EOF;
|
||||
break;
|
||||
|
||||
case PURE_ERROR:
|
||||
return -1;
|
||||
|
||||
default:
|
||||
if ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || c == '_') {
|
||||
_pure_ungetc(context, c);
|
||||
if (_tokenise_identifier(context, out)) {
|
||||
return -1;
|
||||
}
|
||||
} else if (c >= '0' && c <= '9') {
|
||||
_pure_ungetc(context, c);
|
||||
if (_tokenise_number(context, out)) {
|
||||
return -1;
|
||||
}
|
||||
} else {
|
||||
out->data.other = c;
|
||||
out->token = SL_PP_OTHER;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
sl_pp_tokenise(struct sl_pp_context *context,
|
||||
struct sl_pp_token_info **output)
|
||||
{
|
||||
struct sl_pp_token_info *out = NULL;
|
||||
unsigned int out_len = 0;
|
||||
unsigned int out_max = 0;
|
||||
|
||||
for (;;) {
|
||||
struct sl_pp_token_info info;
|
||||
|
||||
if (sl_pp_token_buffer_get(&context->tokens, &info)) {
|
||||
free(out);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (out_len >= out_max) {
|
||||
unsigned int new_max = out_max;
|
||||
|
||||
if (new_max < 0x100) {
|
||||
new_max = 0x100;
|
||||
} else if (new_max < 0x10000) {
|
||||
new_max *= 2;
|
||||
} else {
|
||||
new_max += 0x10000;
|
||||
}
|
||||
|
||||
out = realloc(out, new_max * sizeof(struct sl_pp_token_info));
|
||||
if (!out) {
|
||||
strcpy(context->error_msg, "out of memory");
|
||||
return -1;
|
||||
}
|
||||
out_max = new_max;
|
||||
}
|
||||
|
||||
out[out_len++] = info;
|
||||
|
||||
if (info.token == SL_PP_EOF) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
*output = out;
|
||||
return 0;
|
||||
}
|
|
@ -1,133 +0,0 @@
|
|||
/**************************************************************************
|
||||
*
|
||||
* Copyright 2009 VMware, Inc.
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sub license, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the
|
||||
* next paragraph) shall be included in all copies or substantial portions
|
||||
* of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
|
||||
* IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
|
||||
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
**************************************************************************/
|
||||
|
||||
#ifndef SL_PP_TOKEN_H
|
||||
#define SL_PP_TOKEN_H
|
||||
|
||||
|
||||
struct sl_pp_context;
|
||||
|
||||
enum sl_pp_token {
|
||||
SL_PP_WHITESPACE,
|
||||
SL_PP_NEWLINE,
|
||||
SL_PP_HASH, /* # */
|
||||
|
||||
SL_PP_COMMA, /* , */
|
||||
SL_PP_SEMICOLON, /* ; */
|
||||
SL_PP_LBRACE, /* { */
|
||||
SL_PP_RBRACE, /* } */
|
||||
SL_PP_LPAREN, /* ( */
|
||||
SL_PP_RPAREN, /* ) */
|
||||
SL_PP_LBRACKET, /* [ */
|
||||
SL_PP_RBRACKET, /* ] */
|
||||
SL_PP_DOT, /* . */
|
||||
SL_PP_INCREMENT, /* ++ */
|
||||
SL_PP_ADDASSIGN, /* += */
|
||||
SL_PP_PLUS, /* + */
|
||||
SL_PP_DECREMENT, /* -- */
|
||||
SL_PP_SUBASSIGN, /* -= */
|
||||
SL_PP_MINUS, /* - */
|
||||
SL_PP_BITNOT, /* ~ */
|
||||
SL_PP_NOTEQUAL, /* != */
|
||||
SL_PP_NOT, /* ! */
|
||||
SL_PP_MULASSIGN, /* *= */
|
||||
SL_PP_STAR, /* * */
|
||||
SL_PP_DIVASSIGN, /* /= */
|
||||
SL_PP_SLASH, /* / */
|
||||
SL_PP_MODASSIGN, /* %= */
|
||||
SL_PP_MODULO, /* % */
|
||||
SL_PP_LSHIFTASSIGN, /* <<= */
|
||||
SL_PP_LSHIFT, /* << */
|
||||
SL_PP_LESSEQUAL, /* <= */
|
||||
SL_PP_LESS, /* < */
|
||||
SL_PP_RSHIFTASSIGN, /* >>= */
|
||||
SL_PP_RSHIFT, /* >> */
|
||||
SL_PP_GREATEREQUAL, /* >= */
|
||||
SL_PP_GREATER, /* > */
|
||||
SL_PP_EQUAL, /* == */
|
||||
SL_PP_ASSIGN, /* = */
|
||||
SL_PP_AND, /* && */
|
||||
SL_PP_BITANDASSIGN, /* &= */
|
||||
SL_PP_BITAND, /* & */
|
||||
SL_PP_XOR, /* ^^ */
|
||||
SL_PP_BITXORASSIGN, /* ^= */
|
||||
SL_PP_BITXOR, /* ^ */
|
||||
SL_PP_OR, /* || */
|
||||
SL_PP_BITORASSIGN, /* |= */
|
||||
SL_PP_BITOR, /* | */
|
||||
SL_PP_QUESTION, /* ? */
|
||||
SL_PP_COLON, /* : */
|
||||
|
||||
SL_PP_IDENTIFIER,
|
||||
|
||||
SL_PP_UINT,
|
||||
SL_PP_FLOAT,
|
||||
|
||||
SL_PP_OTHER,
|
||||
|
||||
SL_PP_PRAGMA_OPTIMIZE,
|
||||
SL_PP_PRAGMA_DEBUG,
|
||||
|
||||
SL_PP_EXTENSION_REQUIRE,
|
||||
SL_PP_EXTENSION_ENABLE,
|
||||
SL_PP_EXTENSION_WARN,
|
||||
SL_PP_EXTENSION_DISABLE,
|
||||
|
||||
SL_PP_LINE,
|
||||
|
||||
SL_PP_EOF
|
||||
};
|
||||
|
||||
union sl_pp_token_data {
|
||||
int identifier;
|
||||
int _uint;
|
||||
int _float;
|
||||
char other;
|
||||
int pragma;
|
||||
int extension;
|
||||
struct {
|
||||
unsigned int lineno: 24;
|
||||
unsigned int fileno: 8;
|
||||
} line;
|
||||
};
|
||||
|
||||
struct sl_pp_token_info {
|
||||
enum sl_pp_token token;
|
||||
union sl_pp_token_data data;
|
||||
};
|
||||
|
||||
struct sl_pp_purify_options;
|
||||
|
||||
int
|
||||
sl_pp_token_get(struct sl_pp_context *context,
|
||||
struct sl_pp_token_info *out);
|
||||
|
||||
int
|
||||
sl_pp_tokenise(struct sl_pp_context *context,
|
||||
struct sl_pp_token_info **output);
|
||||
|
||||
#endif /* SL_PP_TOKEN_H */
|
|
@ -1,183 +0,0 @@
|
|||
/**************************************************************************
|
||||
*
|
||||
* Copyright 2009 VMware, Inc.
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sub license, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the
|
||||
* next paragraph) shall be included in all copies or substantial portions
|
||||
* of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
|
||||
* IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
|
||||
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
**************************************************************************/
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdlib.h>
|
||||
#include "sl_pp_token_util.h"
|
||||
#include "sl_pp_token.h"
|
||||
|
||||
|
||||
int
|
||||
sl_pp_token_buffer_init(struct sl_pp_token_buffer *buffer,
|
||||
struct sl_pp_context *context)
|
||||
{
|
||||
buffer->context = context;
|
||||
buffer->size = 0;
|
||||
buffer->capacity = 64;
|
||||
buffer->tokens = malloc(buffer->capacity * sizeof(struct sl_pp_token_info));
|
||||
if (!buffer->tokens) {
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
sl_pp_token_buffer_destroy(struct sl_pp_token_buffer *buffer)
|
||||
{
|
||||
free(buffer->tokens);
|
||||
}
|
||||
|
||||
int
|
||||
sl_pp_token_buffer_get(struct sl_pp_token_buffer *buffer,
|
||||
struct sl_pp_token_info *out)
|
||||
{
|
||||
/* Pop from stack first if not empty. */
|
||||
if (buffer->size) {
|
||||
*out = buffer->tokens[--buffer->size];
|
||||
return 0;
|
||||
}
|
||||
|
||||
assert(buffer->context);
|
||||
return sl_pp_token_get(buffer->context, out);
|
||||
}
|
||||
|
||||
void
|
||||
sl_pp_token_buffer_unget(struct sl_pp_token_buffer *buffer,
|
||||
const struct sl_pp_token_info *in)
|
||||
{
|
||||
/* Resize if needed. */
|
||||
if (buffer->size == buffer->capacity) {
|
||||
buffer->capacity += 64;
|
||||
buffer->tokens = realloc(buffer->tokens,
|
||||
buffer->capacity * sizeof(struct sl_pp_token_info));
|
||||
assert(buffer->tokens);
|
||||
}
|
||||
|
||||
/* Push token on stack. */
|
||||
buffer->tokens[buffer->size++] = *in;
|
||||
}
|
||||
|
||||
int
|
||||
sl_pp_token_buffer_skip_white(struct sl_pp_token_buffer *buffer,
|
||||
struct sl_pp_token_info *out)
|
||||
{
|
||||
if (sl_pp_token_buffer_get(buffer, out)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
while (out->token == SL_PP_WHITESPACE) {
|
||||
if (sl_pp_token_buffer_get(buffer, out)) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
int
|
||||
sl_pp_token_peek_init(struct sl_pp_token_peek *peek,
|
||||
struct sl_pp_token_buffer *buffer)
|
||||
{
|
||||
peek->buffer = buffer;
|
||||
peek->size = 0;
|
||||
peek->capacity = 64;
|
||||
peek->tokens = malloc(peek->capacity * sizeof(struct sl_pp_token_info));
|
||||
if (!peek->tokens) {
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
sl_pp_token_peek_destroy(struct sl_pp_token_peek *peek)
|
||||
{
|
||||
/* Abort. */
|
||||
while (peek->size) {
|
||||
sl_pp_token_buffer_unget(peek->buffer, &peek->tokens[--peek->size]);
|
||||
}
|
||||
free(peek->tokens);
|
||||
}
|
||||
|
||||
int
|
||||
sl_pp_token_peek_get(struct sl_pp_token_peek *peek,
|
||||
struct sl_pp_token_info *out)
|
||||
{
|
||||
/* Get token from buffer. */
|
||||
if (sl_pp_token_buffer_get(peek->buffer, out)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Save it. */
|
||||
if (peek->size == peek->capacity) {
|
||||
peek->capacity += 64;
|
||||
peek->tokens = realloc(peek->tokens,
|
||||
peek->capacity * sizeof(struct sl_pp_token_info));
|
||||
assert(peek->tokens);
|
||||
}
|
||||
peek->tokens[peek->size++] = *out;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
sl_pp_token_peek_commit(struct sl_pp_token_peek *peek)
|
||||
{
|
||||
peek->size = 0;
|
||||
}
|
||||
|
||||
int
|
||||
sl_pp_token_peek_to_buffer(const struct sl_pp_token_peek *peek,
|
||||
struct sl_pp_token_buffer *buffer)
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
if (sl_pp_token_buffer_init(buffer, NULL)) {
|
||||
return -1;
|
||||
}
|
||||
for (i = peek->size; i > 0; i--) {
|
||||
sl_pp_token_buffer_unget(buffer, &peek->tokens[i - 1]);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
sl_pp_token_peek_skip_white(struct sl_pp_token_peek *peek,
|
||||
struct sl_pp_token_info *out)
|
||||
{
|
||||
if (sl_pp_token_peek_get(peek, out)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
while (out->token == SL_PP_WHITESPACE) {
|
||||
if (sl_pp_token_peek_get(peek, out)) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -1,98 +0,0 @@
|
|||
/**************************************************************************
|
||||
*
|
||||
* Copyright 2009 VMware, Inc.
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sub license, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the
|
||||
* next paragraph) shall be included in all copies or substantial portions
|
||||
* of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
|
||||
* IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
|
||||
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
**************************************************************************/
|
||||
|
||||
#ifndef SL_PP_TOKEN_UTIL_H
|
||||
#define SL_PP_TOKEN_UTIL_H
|
||||
|
||||
struct sl_pp_context;
|
||||
|
||||
/*
|
||||
* A token buffer allows one to get and unget a token
|
||||
* from a preprocessor context.
|
||||
*/
|
||||
struct sl_pp_token_buffer {
|
||||
struct sl_pp_context *context;
|
||||
unsigned int size;
|
||||
unsigned int capacity;
|
||||
struct sl_pp_token_info *tokens;
|
||||
};
|
||||
|
||||
int
|
||||
sl_pp_token_buffer_init(struct sl_pp_token_buffer *buffer,
|
||||
struct sl_pp_context *context);
|
||||
|
||||
void
|
||||
sl_pp_token_buffer_destroy(struct sl_pp_token_buffer *buffer);
|
||||
|
||||
int
|
||||
sl_pp_token_buffer_get(struct sl_pp_token_buffer *buffer,
|
||||
struct sl_pp_token_info *out);
|
||||
|
||||
void
|
||||
sl_pp_token_buffer_unget(struct sl_pp_token_buffer *buffer,
|
||||
const struct sl_pp_token_info *in);
|
||||
|
||||
int
|
||||
sl_pp_token_buffer_skip_white(struct sl_pp_token_buffer *buffer,
|
||||
struct sl_pp_token_info *out);
|
||||
|
||||
|
||||
/*
|
||||
* A token peek allows one to get a number of tokens from a buffer
|
||||
* and then either commit the operation or abort it,
|
||||
* effectively ungetting the peeked tokens.
|
||||
*/
|
||||
struct sl_pp_token_peek {
|
||||
struct sl_pp_token_buffer *buffer;
|
||||
unsigned int size;
|
||||
unsigned int capacity;
|
||||
struct sl_pp_token_info *tokens;
|
||||
};
|
||||
|
||||
int
|
||||
sl_pp_token_peek_init(struct sl_pp_token_peek *peek,
|
||||
struct sl_pp_token_buffer *buffer);
|
||||
|
||||
void
|
||||
sl_pp_token_peek_destroy(struct sl_pp_token_peek *peek);
|
||||
|
||||
int
|
||||
sl_pp_token_peek_get(struct sl_pp_token_peek *peek,
|
||||
struct sl_pp_token_info *out);
|
||||
|
||||
void
|
||||
sl_pp_token_peek_commit(struct sl_pp_token_peek *peek);
|
||||
|
||||
int
|
||||
sl_pp_token_peek_to_buffer(const struct sl_pp_token_peek *peek,
|
||||
struct sl_pp_token_buffer *buffer);
|
||||
|
||||
int
|
||||
sl_pp_token_peek_skip_white(struct sl_pp_token_peek *peek,
|
||||
struct sl_pp_token_info *out);
|
||||
|
||||
#endif /* SL_PP_TOKEN_UTIL_H */
|
|
@ -1,162 +0,0 @@
|
|||
/**************************************************************************
|
||||
*
|
||||
* Copyright 2009 VMware, Inc.
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sub license, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the
|
||||
* next paragraph) shall be included in all copies or substantial portions
|
||||
* of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
|
||||
* IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
|
||||
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
**************************************************************************/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "sl_pp_public.h"
|
||||
#include "sl_pp_context.h"
|
||||
#include "sl_pp_token.h"
|
||||
|
||||
|
||||
int
|
||||
sl_pp_version(struct sl_pp_context *context,
|
||||
unsigned int *version)
|
||||
{
|
||||
struct sl_pp_token_peek peek;
|
||||
unsigned int line = context->line;
|
||||
|
||||
/* Default values if `#version' is not present. */
|
||||
*version = 110;
|
||||
|
||||
if (sl_pp_token_peek_init(&peek, &context->tokens)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* There can be multiple `#version' directives present.
|
||||
* Accept the value of the last one.
|
||||
*/
|
||||
for (;;) {
|
||||
struct sl_pp_token_info input;
|
||||
int found_hash = 0;
|
||||
int found_version = 0;
|
||||
int found_number = 0;
|
||||
int found_end = 0;
|
||||
|
||||
/* Skip whitespace and newlines and seek for hash. */
|
||||
while (!found_hash) {
|
||||
if (sl_pp_token_peek_get(&peek, &input)) {
|
||||
sl_pp_token_peek_destroy(&peek);
|
||||
return -1;
|
||||
}
|
||||
|
||||
switch (input.token) {
|
||||
case SL_PP_NEWLINE:
|
||||
line++;
|
||||
break;
|
||||
|
||||
case SL_PP_WHITESPACE:
|
||||
break;
|
||||
|
||||
case SL_PP_HASH:
|
||||
found_hash = 1;
|
||||
break;
|
||||
|
||||
default:
|
||||
sl_pp_token_peek_destroy(&peek);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* Skip whitespace and seek for `version'. */
|
||||
while (!found_version) {
|
||||
if (sl_pp_token_peek_get(&peek, &input)) {
|
||||
sl_pp_token_peek_destroy(&peek);
|
||||
return -1;
|
||||
}
|
||||
|
||||
switch (input.token) {
|
||||
case SL_PP_WHITESPACE:
|
||||
break;
|
||||
|
||||
case SL_PP_IDENTIFIER:
|
||||
if (input.data.identifier != context->dict.version) {
|
||||
sl_pp_token_peek_destroy(&peek);
|
||||
return 0;
|
||||
}
|
||||
found_version = 1;
|
||||
break;
|
||||
|
||||
default:
|
||||
sl_pp_token_peek_destroy(&peek);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
sl_pp_token_peek_commit(&peek);
|
||||
|
||||
/* Skip whitespace and seek for version number. */
|
||||
while (!found_number) {
|
||||
if (sl_pp_token_buffer_get(&context->tokens, &input)) {
|
||||
sl_pp_token_peek_destroy(&peek);
|
||||
return -1;
|
||||
}
|
||||
|
||||
switch (input.token) {
|
||||
case SL_PP_WHITESPACE:
|
||||
break;
|
||||
|
||||
case SL_PP_UINT:
|
||||
*version = atoi(sl_pp_context_cstr(context, input.data._uint));
|
||||
found_number = 1;
|
||||
break;
|
||||
|
||||
default:
|
||||
strcpy(context->error_msg, "expected version number after `#version'");
|
||||
sl_pp_token_peek_destroy(&peek);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
/* Skip whitespace and seek for either newline or eof. */
|
||||
while (!found_end) {
|
||||
if (sl_pp_token_buffer_get(&context->tokens, &input)) {
|
||||
sl_pp_token_peek_destroy(&peek);
|
||||
return -1;
|
||||
}
|
||||
|
||||
switch (input.token) {
|
||||
case SL_PP_WHITESPACE:
|
||||
break;
|
||||
|
||||
case SL_PP_NEWLINE:
|
||||
line++;
|
||||
/* pass thru */
|
||||
case SL_PP_EOF:
|
||||
context->line = line;
|
||||
found_end = 1;
|
||||
break;
|
||||
|
||||
default:
|
||||
strcpy(context->error_msg, "expected end of line after version number");
|
||||
sl_pp_token_peek_destroy(&peek);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Should not get here. */
|
||||
}
|
|
@ -1,43 +0,0 @@
|
|||
# Makefile for stand-alone GL-SL compiler
|
||||
|
||||
TOP = ../../../..
|
||||
|
||||
include $(TOP)/configs/current
|
||||
|
||||
|
||||
PROGRAM = glslcompiler
|
||||
|
||||
OBJECTS = \
|
||||
glslcompiler.o \
|
||||
../common/driverfuncs.o \
|
||||
../../libmesa.a \
|
||||
$(TOP)/src/mapi/glapi/libglapi.a
|
||||
|
||||
INCLUDES = \
|
||||
-I$(TOP)/include \
|
||||
-I$(TOP)/include/GL/internal \
|
||||
-I$(TOP)/src/mapi \
|
||||
-I$(TOP)/src/mesa \
|
||||
-I$(TOP)/src/mesa/main \
|
||||
-I$(TOP)/src/mesa/glapi \
|
||||
-I$(TOP)/src/mesa/math \
|
||||
-I$(TOP)/src/mesa/transform \
|
||||
-I$(TOP)/src/mesa/shader \
|
||||
-I$(TOP)/src/mesa/swrast \
|
||||
-I$(TOP)/src/mesa/swrast_setup \
|
||||
|
||||
|
||||
default: $(PROGRAM)
|
||||
$(INSTALL) $(PROGRAM) $(TOP)/bin
|
||||
|
||||
|
||||
glslcompiler: $(OBJECTS)
|
||||
$(CC) $(OBJECTS) $(GL_LIB_DEPS) -o $@
|
||||
|
||||
|
||||
glslcompiler.o: glslcompiler.c
|
||||
$(CC) -c $(INCLUDES) $(CFLAGS) glslcompiler.c -o $@
|
||||
|
||||
|
||||
clean:
|
||||
-rm -f *.o *~ $(PROGRAM)
|
|
@ -1,436 +0,0 @@
|
|||
/*
|
||||
* Mesa 3-D graphics library
|
||||
* Version: 6.5.3
|
||||
*
|
||||
* Copyright (C) 1999-2007 Brian Paul, Tungsten Graphics, Inc.
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included
|
||||
* in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
|
||||
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
/**
|
||||
* \mainpage
|
||||
*
|
||||
* Stand-alone Shading Language compiler.
|
||||
* Basically, a command-line program which accepts GLSL shaders and emits
|
||||
* vertex/fragment programs (GPU instructions).
|
||||
*
|
||||
* This file is basically just a Mesa device driver but instead of building
|
||||
* a shared library we build an executable.
|
||||
*
|
||||
* We can emit programs in three different formats:
|
||||
* 1. ARB-style (GL_ARB_vertex/fragment_program)
|
||||
* 2. NV-style (GL_NV_vertex/fragment_program)
|
||||
* 3. debug-style (a slightly more sophisticated, internal format)
|
||||
*
|
||||
* Note that the ARB and NV program languages can't express all the
|
||||
* features that might be used by a fragment program (examples being
|
||||
* uniform and varying vars). So, the ARB/NV programs that are
|
||||
* emitted aren't always legal programs in those languages.
|
||||
*/
|
||||
|
||||
|
||||
#include "main/imports.h"
|
||||
#include "main/context.h"
|
||||
#include "main/extensions.h"
|
||||
#include "main/framebuffer.h"
|
||||
#include "main/shaderapi.h"
|
||||
#include "main/shaderobj.h"
|
||||
#include "program/prog_print.h"
|
||||
#include "drivers/common/driverfuncs.h"
|
||||
#include "tnl/tnl.h"
|
||||
#include "tnl/t_context.h"
|
||||
#include "tnl/t_pipeline.h"
|
||||
#include "swrast/swrast.h"
|
||||
#include "swrast_setup/swrast_setup.h"
|
||||
#include "vbo/vbo.h"
|
||||
|
||||
|
||||
static const char *Prog = "glslcompiler";
|
||||
|
||||
|
||||
struct options {
|
||||
GLboolean LineNumbers;
|
||||
GLboolean Link;
|
||||
gl_prog_print_mode Mode;
|
||||
const char *VertFile;
|
||||
const char *FragFile;
|
||||
const char *GeoFile;
|
||||
const char *OutputFile;
|
||||
GLboolean Params;
|
||||
struct gl_sl_pragmas Pragmas;
|
||||
};
|
||||
|
||||
static struct options Options;
|
||||
|
||||
|
||||
/**
|
||||
* GLSL compiler driver context. (kind of an artificial thing for now)
|
||||
*/
|
||||
struct compiler_context
|
||||
{
|
||||
GLcontext MesaContext;
|
||||
int foo;
|
||||
};
|
||||
|
||||
typedef struct compiler_context CompilerContext;
|
||||
|
||||
|
||||
|
||||
static void
|
||||
UpdateState(GLcontext *ctx, GLuint new_state)
|
||||
{
|
||||
/* easy - just propogate */
|
||||
_swrast_InvalidateState( ctx, new_state );
|
||||
_swsetup_InvalidateState( ctx, new_state );
|
||||
_tnl_InvalidateState( ctx, new_state );
|
||||
_vbo_InvalidateState( ctx, new_state );
|
||||
}
|
||||
|
||||
|
||||
|
||||
static GLboolean
|
||||
CreateContext(void)
|
||||
{
|
||||
struct dd_function_table ddFuncs;
|
||||
GLvisual *vis;
|
||||
GLframebuffer *buf;
|
||||
GLcontext *ctx;
|
||||
CompilerContext *cc;
|
||||
|
||||
vis = _mesa_create_visual(GL_FALSE, GL_FALSE, /* RGB */
|
||||
8, 8, 8, 8, /* color */
|
||||
0, 0, /* z, stencil */
|
||||
0, 0, 0, 0, 1); /* accum */
|
||||
buf = _mesa_create_framebuffer(vis);
|
||||
|
||||
cc = calloc(1, sizeof(*cc));
|
||||
if (!vis || !buf || !cc) {
|
||||
if (vis)
|
||||
_mesa_destroy_visual(vis);
|
||||
if (buf)
|
||||
_mesa_destroy_framebuffer(buf);
|
||||
free(cc);
|
||||
return GL_FALSE;
|
||||
}
|
||||
|
||||
_mesa_init_driver_functions(&ddFuncs);
|
||||
ddFuncs.GetString = NULL;/*get_string;*/
|
||||
ddFuncs.UpdateState = UpdateState;
|
||||
ddFuncs.GetBufferSize = NULL;
|
||||
|
||||
ctx = &cc->MesaContext;
|
||||
_mesa_initialize_context(ctx, vis, NULL, &ddFuncs, cc);
|
||||
_mesa_enable_sw_extensions(ctx);
|
||||
|
||||
if (!_swrast_CreateContext( ctx ) ||
|
||||
!_vbo_CreateContext( ctx ) ||
|
||||
!_tnl_CreateContext( ctx ) ||
|
||||
!_swsetup_CreateContext( ctx )) {
|
||||
_mesa_destroy_visual(vis);
|
||||
_mesa_destroy_framebuffer(buf);
|
||||
_mesa_free_context_data(ctx);
|
||||
free(cc);
|
||||
return GL_FALSE;
|
||||
}
|
||||
TNL_CONTEXT(ctx)->Driver.RunPipeline = _tnl_run_pipeline;
|
||||
_swsetup_Wakeup( ctx );
|
||||
|
||||
/* Override the context's default pragma settings */
|
||||
ctx->Shader.DefaultPragmas = Options.Pragmas;
|
||||
|
||||
_mesa_make_current(ctx, buf, buf);
|
||||
|
||||
return GL_TRUE;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
LoadAndCompileShader(GLuint shader, const char *text)
|
||||
{
|
||||
GLint stat;
|
||||
_mesa_ShaderSourceARB(shader, 1, (const GLchar **) &text, NULL);
|
||||
_mesa_CompileShaderARB(shader);
|
||||
_mesa_GetShaderiv(shader, GL_COMPILE_STATUS, &stat);
|
||||
if (!stat) {
|
||||
GLchar log[1000];
|
||||
GLsizei len;
|
||||
_mesa_GetShaderInfoLog(shader, 1000, &len, log);
|
||||
fprintf(stderr, "%s: problem compiling shader: %s\n", Prog, log);
|
||||
exit(1);
|
||||
}
|
||||
else {
|
||||
printf("Shader compiled OK\n");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Read a shader from a file.
|
||||
*/
|
||||
static void
|
||||
ReadShader(GLuint shader, const char *filename)
|
||||
{
|
||||
const int max = 100*1000;
|
||||
int n;
|
||||
char *buffer = (char*) malloc(max);
|
||||
FILE *f = fopen(filename, "r");
|
||||
if (!f) {
|
||||
fprintf(stderr, "%s: Unable to open shader file %s\n", Prog, filename);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
n = fread(buffer, 1, max, f);
|
||||
/*
|
||||
printf("%s: read %d bytes from shader file %s\n", Prog, n, filename);
|
||||
*/
|
||||
if (n > 0) {
|
||||
buffer[n] = 0;
|
||||
LoadAndCompileShader(shader, buffer);
|
||||
}
|
||||
|
||||
fclose(f);
|
||||
free(buffer);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
CheckLink(GLuint v_shader, GLuint f_shader)
|
||||
{
|
||||
GLuint prog;
|
||||
GLint stat;
|
||||
|
||||
prog = _mesa_CreateProgram();
|
||||
|
||||
_mesa_AttachShader(prog, v_shader);
|
||||
_mesa_AttachShader(prog, f_shader);
|
||||
|
||||
_mesa_LinkProgramARB(prog);
|
||||
_mesa_GetProgramiv(prog, GL_LINK_STATUS, &stat);
|
||||
if (!stat) {
|
||||
GLchar log[1000];
|
||||
GLsizei len;
|
||||
_mesa_GetProgramInfoLog(prog, 1000, &len, log);
|
||||
fprintf(stderr, "Linker error:\n%s\n", log);
|
||||
}
|
||||
else {
|
||||
fprintf(stderr, "Link success!\n");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
PrintShaderInstructions(GLuint shader, FILE *f)
|
||||
{
|
||||
GET_CURRENT_CONTEXT(ctx);
|
||||
struct gl_shader *sh = _mesa_lookup_shader(ctx, shader);
|
||||
struct gl_program *prog = sh->Program;
|
||||
_mesa_fprint_program_opt(stdout, prog, Options.Mode, Options.LineNumbers);
|
||||
if (Options.Params)
|
||||
_mesa_print_program_parameters(ctx, prog);
|
||||
}
|
||||
|
||||
|
||||
static GLuint
|
||||
CompileShader(const char *filename, GLenum type)
|
||||
{
|
||||
GLuint shader;
|
||||
|
||||
assert(type == GL_FRAGMENT_SHADER ||
|
||||
type == GL_VERTEX_SHADER ||
|
||||
type == GL_GEOMETRY_SHADER_ARB);
|
||||
|
||||
shader = _mesa_CreateShader(type);
|
||||
ReadShader(shader, filename);
|
||||
|
||||
return shader;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
Usage(void)
|
||||
{
|
||||
printf("Mesa GLSL stand-alone compiler\n");
|
||||
printf("Usage:\n");
|
||||
printf(" --vs FILE vertex shader input filename\n");
|
||||
printf(" --fs FILE fragment shader input filename\n");
|
||||
printf(" --gs FILE geometry shader input filename\n");
|
||||
printf(" --arb emit ARB-style instructions\n");
|
||||
printf(" --nv emit NV-style instructions\n");
|
||||
printf(" --link run linker\n");
|
||||
printf(" --debug force #pragma debug(on)\n");
|
||||
printf(" --nodebug force #pragma debug(off)\n");
|
||||
printf(" --opt force #pragma optimize(on)\n");
|
||||
printf(" --noopt force #pragma optimize(off)\n");
|
||||
printf(" --number, -n emit line numbers (if --arb or --nv)\n");
|
||||
printf(" --output, -o FILE output filename\n");
|
||||
printf(" --params also emit program parameter info\n");
|
||||
printf(" --help display this information\n");
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
ParseOptions(int argc, char *argv[])
|
||||
{
|
||||
int i;
|
||||
|
||||
Options.LineNumbers = GL_FALSE;
|
||||
Options.Mode = PROG_PRINT_DEBUG;
|
||||
Options.VertFile = NULL;
|
||||
Options.FragFile = NULL;
|
||||
Options.GeoFile = NULL;
|
||||
Options.OutputFile = NULL;
|
||||
Options.Params = GL_FALSE;
|
||||
Options.Pragmas.IgnoreOptimize = GL_FALSE;
|
||||
Options.Pragmas.IgnoreDebug = GL_FALSE;
|
||||
Options.Pragmas.Debug = GL_FALSE;
|
||||
Options.Pragmas.Optimize = GL_TRUE;
|
||||
|
||||
if (argc == 1) {
|
||||
Usage();
|
||||
exit(0);
|
||||
}
|
||||
|
||||
for (i = 1; i < argc; i++) {
|
||||
if (strcmp(argv[i], "--vs") == 0) {
|
||||
Options.VertFile = argv[i + 1];
|
||||
i++;
|
||||
}
|
||||
else if (strcmp(argv[i], "--fs") == 0) {
|
||||
Options.FragFile = argv[i + 1];
|
||||
i++;
|
||||
}
|
||||
else if (strcmp(argv[i], "--gs") == 0) {
|
||||
Options.GeoFile = argv[i + 1];
|
||||
i++;
|
||||
}
|
||||
else if (strcmp(argv[i], "--arb") == 0) {
|
||||
Options.Mode = PROG_PRINT_ARB;
|
||||
}
|
||||
else if (strcmp(argv[i], "--nv") == 0) {
|
||||
Options.Mode = PROG_PRINT_NV;
|
||||
}
|
||||
else if (strcmp(argv[i], "--link") == 0) {
|
||||
Options.Link = GL_TRUE;
|
||||
}
|
||||
else if (strcmp(argv[i], "--debug") == 0) {
|
||||
Options.Pragmas.IgnoreDebug = GL_TRUE;
|
||||
Options.Pragmas.Debug = GL_TRUE;
|
||||
}
|
||||
else if (strcmp(argv[i], "--nodebug") == 0) {
|
||||
Options.Pragmas.IgnoreDebug = GL_TRUE;
|
||||
Options.Pragmas.Debug = GL_FALSE;
|
||||
}
|
||||
else if (strcmp(argv[i], "--opt") == 0) {
|
||||
Options.Pragmas.IgnoreOptimize = GL_TRUE;
|
||||
Options.Pragmas.Optimize = GL_TRUE;
|
||||
}
|
||||
else if (strcmp(argv[i], "--noopt") == 0) {
|
||||
Options.Pragmas.IgnoreOptimize = GL_TRUE;
|
||||
Options.Pragmas.Optimize = GL_FALSE;
|
||||
}
|
||||
else if (strcmp(argv[i], "--number") == 0 ||
|
||||
strcmp(argv[i], "-n") == 0) {
|
||||
Options.LineNumbers = GL_TRUE;
|
||||
}
|
||||
else if (strcmp(argv[i], "--output") == 0 ||
|
||||
strcmp(argv[i], "-o") == 0) {
|
||||
Options.OutputFile = argv[i + 1];
|
||||
i++;
|
||||
}
|
||||
else if (strcmp(argv[i], "--params") == 0) {
|
||||
Options.Params = GL_TRUE;
|
||||
}
|
||||
else if (strcmp(argv[i], "--help") == 0) {
|
||||
Usage();
|
||||
exit(0);
|
||||
}
|
||||
else {
|
||||
printf("Unknown option: %s\n", argv[i]);
|
||||
Usage();
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
if (Options.Mode == PROG_PRINT_DEBUG) {
|
||||
/* always print line numbers when emitting debug-style output */
|
||||
Options.LineNumbers = GL_TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
main(int argc, char *argv[])
|
||||
{
|
||||
GLuint v_shader = 0, f_shader = 0, g_shader = 0;
|
||||
|
||||
ParseOptions(argc, argv);
|
||||
|
||||
if (!CreateContext()) {
|
||||
fprintf(stderr, "%s: Failed to create compiler context\n", Prog);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (Options.VertFile) {
|
||||
v_shader = CompileShader(Options.VertFile, GL_VERTEX_SHADER);
|
||||
}
|
||||
|
||||
if (Options.FragFile) {
|
||||
f_shader = CompileShader(Options.FragFile, GL_FRAGMENT_SHADER);
|
||||
}
|
||||
|
||||
if (Options.GeoFile) {
|
||||
g_shader = CompileShader(Options.GeoFile, GL_GEOMETRY_SHADER_ARB);
|
||||
}
|
||||
|
||||
|
||||
if (v_shader || f_shader || g_shader) {
|
||||
if (Options.OutputFile) {
|
||||
FILE *f;
|
||||
fclose(stdout);
|
||||
/*stdout =*/ f = freopen(Options.OutputFile, "w", stdout);
|
||||
if (!f) {
|
||||
fprintf(stderr, "freopen error\n");
|
||||
}
|
||||
}
|
||||
if (stdout && v_shader) {
|
||||
PrintShaderInstructions(v_shader, stdout);
|
||||
}
|
||||
if (stdout && f_shader) {
|
||||
PrintShaderInstructions(f_shader, stdout);
|
||||
}
|
||||
if (stdout && g_shader) {
|
||||
PrintShaderInstructions(g_shader, stdout);
|
||||
}
|
||||
if (Options.OutputFile) {
|
||||
fclose(stdout);
|
||||
}
|
||||
}
|
||||
|
||||
if (Options.Link) {
|
||||
if (!v_shader || !f_shader) {
|
||||
fprintf(stderr,
|
||||
"--link option requires both a vertex and fragment shader.\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
CheckLink(v_shader, f_shader);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -1,67 +0,0 @@
|
|||
# Makefile for core library for VMS
|
||||
# contributed by Jouk Jansen joukj@hrem.nano.tudelft.nl
|
||||
# Last revision : 3 October 2007
|
||||
|
||||
.first
|
||||
define gl [----.include.gl]
|
||||
define math [--.math]
|
||||
define swrast [--.swrast]
|
||||
define array_cache [--.array_cache]
|
||||
define main [--.main]
|
||||
define glapi [--.glapi]
|
||||
define shader [--.shader]
|
||||
|
||||
.include [----]mms-config.
|
||||
|
||||
##### MACROS #####
|
||||
|
||||
VPATH = RCS
|
||||
|
||||
INCDIR = [----.include],[--.main],[--.glapi],[-.slang],[-]
|
||||
LIBDIR = [----.lib]
|
||||
CFLAGS = /include=($(INCDIR),[])/define=(PTHREADS=1)/name=(as_is,short)/float=ieee/ieee=denorm
|
||||
|
||||
SOURCES = \
|
||||
slang_compile.c
|
||||
|
||||
OBJECTS = slang_builtin.obj,slang_codegen.obj,slang_compile.obj,\
|
||||
slang_compile_function.obj,slang_compile_operation.obj,\
|
||||
slang_compile_struct.obj,slang_compile_variable.obj,slang_emit.obj,\
|
||||
slang_ir.obj,slang_label.obj,slang_library_noise.obj,slang_link.obj,\
|
||||
slang_log.obj,slang_mem.obj,slang_preprocess.obj,slang_print.obj,\
|
||||
slang_simplify.obj,slang_storage.obj,slang_typeinfo.obj,\
|
||||
slang_utility.obj,slang_vartable.obj
|
||||
|
||||
##### RULES #####
|
||||
|
||||
VERSION=Mesa V3.4
|
||||
|
||||
##### TARGETS #####
|
||||
# Make the library
|
||||
$(LIBDIR)$(GL_LIB) : $(OBJECTS)
|
||||
@ library $(LIBDIR)$(GL_LIB) $(OBJECTS)
|
||||
|
||||
clean :
|
||||
purge
|
||||
delete *.obj;*
|
||||
|
||||
slang_builtin.obj : slang_builtin.c
|
||||
slang_codegen.obj : slang_codegen.c
|
||||
slang_compile.obj : slang_compile.c
|
||||
slang_compile_function.obj : slang_compile_function.c
|
||||
slang_compile_operation.obj : slang_compile_operation.c
|
||||
slang_compile_struct.obj : slang_compile_struct.c
|
||||
slang_compile_variable.obj : slang_compile_variable.c
|
||||
slang_emit.obj : slang_emit.c
|
||||
slang_ir.obj : slang_ir.c
|
||||
slang_label.obj : slang_label.c
|
||||
slang_library_noise.obj : slang_library_noise.c
|
||||
slang_link.obj : slang_link.c
|
||||
slang_log.obj : slang_log.c
|
||||
slang_mem.obj : slang_mem.c
|
||||
slang_print.obj : slang_print.c
|
||||
slang_simplify.obj : slang_simplify.c
|
||||
slang_storage.obj : slang_storage.c
|
||||
slang_typeinfo.obj : slang_typeinfo.c
|
||||
slang_utility.obj : slang_utility.c
|
||||
slang_vartable.obj : slang_vartable.c
|
|
@ -1 +0,0 @@
|
|||
*_gc.h
|
|
@ -1,54 +0,0 @@
|
|||
# src/mesa/slang/library/Makefile
|
||||
|
||||
TOP = ../../../..
|
||||
|
||||
include $(TOP)/configs/current
|
||||
|
||||
GLSL_CL = $(TOP)/src/glsl/apps/compile
|
||||
|
||||
#
|
||||
# targets
|
||||
#
|
||||
|
||||
.PHONY: default clean
|
||||
|
||||
default: builtin
|
||||
|
||||
clean:
|
||||
-rm -f *_gc.h
|
||||
|
||||
builtin: builtin_110 builtin_120
|
||||
|
||||
#
|
||||
# builtin library sources
|
||||
#
|
||||
|
||||
builtin_110: slang_common_builtin_gc.h slang_core_gc.h slang_fragment_builtin_gc.h slang_vertex_builtin_gc.h slang_geometry_builtin_gc.h
|
||||
|
||||
builtin_120: slang_120_core_gc.h slang_builtin_120_common_gc.h slang_builtin_120_fragment_gc.h
|
||||
|
||||
|
||||
slang_120_core_gc.h: slang_120_core.gc
|
||||
$(GLSL_CL) fragment slang_120_core.gc slang_120_core_gc.h
|
||||
|
||||
slang_builtin_120_common_gc.h: slang_builtin_120_common.gc
|
||||
$(GLSL_CL) fragment slang_builtin_120_common.gc slang_builtin_120_common_gc.h
|
||||
|
||||
slang_builtin_120_fragment_gc.h: slang_builtin_120_fragment.gc
|
||||
$(GLSL_CL) fragment slang_builtin_120_fragment.gc slang_builtin_120_fragment_gc.h
|
||||
|
||||
slang_common_builtin_gc.h: slang_common_builtin.gc
|
||||
$(GLSL_CL) fragment slang_common_builtin.gc slang_common_builtin_gc.h
|
||||
|
||||
slang_core_gc.h: slang_core.gc
|
||||
$(GLSL_CL) fragment slang_core.gc slang_core_gc.h
|
||||
|
||||
slang_fragment_builtin_gc.h: slang_fragment_builtin.gc
|
||||
$(GLSL_CL) fragment slang_fragment_builtin.gc slang_fragment_builtin_gc.h
|
||||
|
||||
slang_vertex_builtin_gc.h: slang_vertex_builtin.gc
|
||||
$(GLSL_CL) vertex slang_vertex_builtin.gc slang_vertex_builtin_gc.h
|
||||
|
||||
slang_geometry_builtin_gc.h: slang_geometry_builtin.gc
|
||||
$(GLSL_CL) geometry slang_geometry_builtin.gc slang_geometry_builtin_gc.h
|
||||
|
|
@ -1,62 +0,0 @@
|
|||
#######################################################################
|
||||
# SConscript for GLSL builtin library
|
||||
|
||||
Import('*')
|
||||
|
||||
env = env.Clone()
|
||||
|
||||
# See also http://www.scons.org/wiki/UsingCodeGenerators
|
||||
|
||||
def glsl_compile_emitter(target, source, env):
|
||||
env.Depends(target, glsl_compile)
|
||||
return (target, source)
|
||||
|
||||
bld_frag = Builder(
|
||||
action = Action(glsl_compile[0].abspath + ' fragment $SOURCE $TARGET', '$CODEGENCODESTR'),
|
||||
emitter = glsl_compile_emitter,
|
||||
suffix = '.gc',
|
||||
src_suffix = '_gc.h')
|
||||
|
||||
bld_vert = Builder(
|
||||
action = Action(glsl_compile[0].abspath + ' vertex $SOURCE $TARGET', '$CODEGENCODESTR'),
|
||||
emitter = glsl_compile_emitter,
|
||||
suffix = '.gc',
|
||||
src_suffix = '_gc.h')
|
||||
|
||||
bld_geom = Builder(
|
||||
action = Action(glsl_compile[0].abspath + ' geometry $SOURCE $TARGET', '$CODEGENCODESTR'),
|
||||
emitter = glsl_compile_emitter,
|
||||
suffix = '.gc',
|
||||
src_suffix = '_gc.h')
|
||||
|
||||
env['BUILDERS']['bld_frag'] = bld_frag
|
||||
env['BUILDERS']['bld_vert'] = bld_vert
|
||||
env['BUILDERS']['bld_geom'] = bld_geom
|
||||
|
||||
# Generate GLSL builtin library binaries
|
||||
env.bld_frag(
|
||||
'#src/mesa/slang/library/slang_core_gc.h',
|
||||
'#src/mesa/slang/library/slang_core.gc')
|
||||
env.bld_frag(
|
||||
'#src/mesa/slang/library/slang_common_builtin_gc.h',
|
||||
'#src/mesa/slang/library/slang_common_builtin.gc')
|
||||
env.bld_frag(
|
||||
'#src/mesa/slang/library/slang_fragment_builtin_gc.h',
|
||||
'#src/mesa/slang/library/slang_fragment_builtin.gc')
|
||||
env.bld_vert(
|
||||
'#src/mesa/slang/library/slang_vertex_builtin_gc.h',
|
||||
'#src/mesa/slang/library/slang_vertex_builtin.gc')
|
||||
env.bld_geom(
|
||||
'#src/mesa/slang/library/slang_geometry_builtin_gc.h',
|
||||
'#src/mesa/slang/library/slang_geometry_builtin.gc')
|
||||
|
||||
# Generate GLSL 1.20 builtin library binaries
|
||||
env.bld_frag(
|
||||
'#src/mesa/slang/library/slang_120_core_gc.h',
|
||||
'#src/mesa/slang/library/slang_120_core.gc')
|
||||
env.bld_frag(
|
||||
'#src/mesa/slang/library/slang_builtin_120_common_gc.h',
|
||||
'#src/mesa/slang/library/slang_builtin_120_common.gc')
|
||||
env.bld_frag(
|
||||
'#src/mesa/slang/library/slang_builtin_120_fragment_gc.h',
|
||||
'#src/mesa/slang/library/slang_builtin_120_fragment.gc')
|
File diff suppressed because it is too large
Load Diff
|
@ -1,200 +0,0 @@
|
|||
/*
|
||||
* Mesa 3-D graphics library
|
||||
* Version: 6.6
|
||||
*
|
||||
* Copyright (C) 2006 Brian Paul All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included
|
||||
* in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
|
||||
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
//
|
||||
// From Shader Spec, ver. 1.20, rev. 6
|
||||
//
|
||||
|
||||
//
|
||||
// 8.5 Matrix Functions
|
||||
//
|
||||
|
||||
mat2x3 matrixCompMult (mat2x3 m, mat2x3 n) {
|
||||
return mat2x3 (m[0] * n[0], m[1] * n[1]);
|
||||
}
|
||||
|
||||
mat2x4 matrixCompMult (mat2x4 m, mat2x4 n) {
|
||||
return mat2x4 (m[0] * n[0], m[1] * n[1]);
|
||||
}
|
||||
|
||||
mat3x2 matrixCompMult (mat3x2 m, mat3x2 n) {
|
||||
return mat3x2 (m[0] * n[0], m[1] * n[1], m[2] * n[2]);
|
||||
}
|
||||
|
||||
mat3x4 matrixCompMult (mat3x4 m, mat3x4 n) {
|
||||
return mat3x4 (m[0] * n[0], m[1] * n[1], m[2] * n[2]);
|
||||
}
|
||||
|
||||
mat4x2 matrixCompMult (mat4x2 m, mat4x2 n) {
|
||||
return mat4x2 (m[0] * n[0], m[1] * n[1], m[2] * n[2], m[3] * n[3]);
|
||||
}
|
||||
|
||||
mat4x3 matrixCompMult (mat4x3 m, mat4x3 n) {
|
||||
return mat4x3 (m[0] * n[0], m[1] * n[1], m[2] * n[2], m[3] * n[3]);
|
||||
}
|
||||
|
||||
mat2 outerProduct (vec2 c, vec2 r) {
|
||||
return mat2 (
|
||||
c.x * r.x, c.y * r.x,
|
||||
c.x * r.y, c.y * r.y
|
||||
);
|
||||
}
|
||||
|
||||
mat3 outerProduct (vec3 c, vec3 r) {
|
||||
return mat3 (
|
||||
c.x * r.x, c.y * r.x, c.z * r.x,
|
||||
c.x * r.y, c.y * r.y, c.z * r.y,
|
||||
c.x * r.z, c.y * r.z, c.z * r.z
|
||||
);
|
||||
}
|
||||
|
||||
mat4 outerProduct (vec4 c, vec4 r) {
|
||||
return mat4 (
|
||||
c.x * r.x, c.y * r.x, c.z * r.x, c.w * r.x,
|
||||
c.x * r.y, c.y * r.y, c.z * r.y, c.w * r.y,
|
||||
c.x * r.z, c.y * r.z, c.z * r.z, c.w * r.z,
|
||||
c.x * r.w, c.y * r.w, c.z * r.w, c.w * r.w
|
||||
);
|
||||
}
|
||||
|
||||
mat2x3 outerProduct (vec3 c, vec2 r) {
|
||||
return mat2x3 (
|
||||
c.x * r.x, c.y * r.x, c.z * r.x,
|
||||
c.x * r.y, c.y * r.y, c.z * r.y
|
||||
);
|
||||
}
|
||||
|
||||
mat3x2 outerProduct (vec2 c, vec3 r) {
|
||||
return mat3x2 (
|
||||
c.x * r.x, c.y * r.x,
|
||||
c.x * r.y, c.y * r.y,
|
||||
c.x * r.z, c.y * r.z
|
||||
);
|
||||
}
|
||||
|
||||
mat2x4 outerProduct (vec4 c, vec2 r) {
|
||||
return mat2x4 (
|
||||
c.x * r.x, c.y * r.x, c.z * r.x, c.w * r.x,
|
||||
c.x * r.y, c.y * r.y, c.z * r.y, c.w * r.y
|
||||
);
|
||||
}
|
||||
|
||||
mat4x2 outerProduct (vec2 c, vec4 r) {
|
||||
return mat4x2 (
|
||||
c.x * r.x, c.y * r.x,
|
||||
c.x * r.y, c.y * r.y,
|
||||
c.x * r.z, c.y * r.z,
|
||||
c.x * r.w, c.y * r.w
|
||||
);
|
||||
}
|
||||
|
||||
mat3x4 outerProduct (vec4 c, vec3 r) {
|
||||
return mat3x4 (
|
||||
c.x * r.x, c.y * r.x, c.z * r.x, c.w * r.x,
|
||||
c.x * r.y, c.y * r.y, c.z * r.y, c.w * r.y,
|
||||
c.x * r.z, c.y * r.z, c.z * r.z, c.w * r.z
|
||||
);
|
||||
}
|
||||
|
||||
mat4x3 outerProduct (vec3 c, vec4 r) {
|
||||
return mat4x3 (
|
||||
c.x * r.x, c.y * r.x, c.z * r.x,
|
||||
c.x * r.y, c.y * r.y, c.z * r.y,
|
||||
c.x * r.z, c.y * r.z, c.z * r.z,
|
||||
c.x * r.w, c.y * r.w, c.z * r.w
|
||||
);
|
||||
}
|
||||
|
||||
mat2 transpose (mat2 m) {
|
||||
return mat2 (
|
||||
m[0].x, m[1].x,
|
||||
m[0].y, m[1].y
|
||||
);
|
||||
}
|
||||
|
||||
mat3 transpose (mat3 m) {
|
||||
return mat3 (
|
||||
m[0].x, m[1].x, m[2].x,
|
||||
m[0].y, m[1].y, m[2].y,
|
||||
m[0].z, m[1].z, m[2].z
|
||||
);
|
||||
}
|
||||
|
||||
mat4 transpose (mat4 m) {
|
||||
return mat4 (
|
||||
m[0].x, m[1].x, m[2].x, m[3].x,
|
||||
m[0].y, m[1].y, m[2].y, m[3].y,
|
||||
m[0].z, m[1].z, m[2].z, m[3].z,
|
||||
m[0].w, m[1].w, m[2].w, m[3].w
|
||||
);
|
||||
}
|
||||
|
||||
mat2x3 transpose (mat3x2 m) {
|
||||
return mat2x3 (
|
||||
m[0].x, m[1].x, m[2].x,
|
||||
m[0].y, m[1].y, m[2].y
|
||||
);
|
||||
}
|
||||
|
||||
mat3x2 transpose (mat2x3 m) {
|
||||
return mat3x2 (
|
||||
m[0].x, m[1].x,
|
||||
m[0].y, m[1].y,
|
||||
m[0].z, m[1].z
|
||||
);
|
||||
}
|
||||
|
||||
mat2x4 transpose (mat4x2 m) {
|
||||
return mat2x4 (
|
||||
m[0].x, m[1].x, m[2].x, m[3].x,
|
||||
m[0].y, m[1].y, m[2].y, m[3].y
|
||||
);
|
||||
}
|
||||
|
||||
mat4x2 transpose (mat2x4 m) {
|
||||
return mat4x2 (
|
||||
m[0].x, m[1].x,
|
||||
m[0].y, m[1].y,
|
||||
m[0].z, m[1].z,
|
||||
m[0].w, m[1].w
|
||||
);
|
||||
}
|
||||
|
||||
mat3x4 transpose (mat4x3 m) {
|
||||
return mat3x4 (
|
||||
m[0].x, m[1].x, m[2].x, m[3].x,
|
||||
m[0].y, m[1].y, m[2].y, m[3].y,
|
||||
m[0].z, m[1].z, m[2].z, m[3].z
|
||||
);
|
||||
}
|
||||
|
||||
mat4x3 transpose (mat3x4 m) {
|
||||
return mat4x3 (
|
||||
m[0].x, m[1].x, m[2].x,
|
||||
m[0].y, m[1].y, m[2].y,
|
||||
m[0].z, m[1].z, m[2].z,
|
||||
m[0].w, m[1].w, m[2].w
|
||||
);
|
||||
}
|
||||
|
|
@ -1,30 +0,0 @@
|
|||
/*
|
||||
* Mesa 3-D graphics library
|
||||
* Version: 6.5
|
||||
*
|
||||
* Copyright (C) 2006 Brian Paul All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included
|
||||
* in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
|
||||
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
//
|
||||
// From Shader Spec, ver. 1.20, rev. 6
|
||||
//
|
||||
|
||||
varying vec2 gl_PointCoord;
|
||||
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -1,299 +0,0 @@
|
|||
/*
|
||||
* Mesa 3-D graphics library
|
||||
* Version: 6.5
|
||||
*
|
||||
* Copyright (C) 2006 Brian Paul All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included
|
||||
* in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
|
||||
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
//
|
||||
// From Shader Spec, ver. 1.10, rev. 59
|
||||
//
|
||||
|
||||
__fixed_input vec4 gl_FragCoord;
|
||||
__fixed_input bool gl_FrontFacing;
|
||||
__fixed_output vec4 gl_FragColor;
|
||||
__fixed_output vec4 gl_FragData[gl_MaxDrawBuffers];
|
||||
__fixed_output float gl_FragDepth;
|
||||
|
||||
varying vec4 gl_Color;
|
||||
varying vec4 gl_SecondaryColor;
|
||||
varying vec4 gl_TexCoord[gl_MaxTextureCoords];
|
||||
varying float gl_FogFragCoord;
|
||||
|
||||
|
||||
|
||||
//// 8.7 Texture Lookup Functions (with bias)
|
||||
|
||||
vec4 texture1D(const sampler1D sampler, const float coord, const float bias)
|
||||
{
|
||||
vec4 coord4;
|
||||
coord4.x = coord;
|
||||
coord4.w = bias;
|
||||
__asm vec4_tex_1d_bias __retVal, sampler, coord4;
|
||||
}
|
||||
|
||||
vec4 texture1DProj(const sampler1D sampler, const vec2 coord, const float bias)
|
||||
{
|
||||
// do projection here (there's no vec4_texbp1d instruction)
|
||||
vec4 pcoord;
|
||||
pcoord.x = coord.x / coord.y;
|
||||
pcoord.w = bias;
|
||||
__asm vec4_tex_1d_bias __retVal, sampler, pcoord;
|
||||
}
|
||||
|
||||
vec4 texture1DProj(const sampler1D sampler, const vec4 coord, const float bias)
|
||||
{
|
||||
// do projection here (there's no vec4_texbp1d instruction)
|
||||
vec4 pcoord;
|
||||
pcoord.x = coord.x / coord.z;
|
||||
pcoord.w = bias;
|
||||
__asm vec4_tex_1d_bias __retVal, sampler, pcoord;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
vec4 texture2D(const sampler2D sampler, const vec2 coord, const float bias)
|
||||
{
|
||||
vec4 coord4;
|
||||
coord4.xy = coord.xy;
|
||||
coord4.w = bias;
|
||||
__asm vec4_tex_2d_bias __retVal, sampler, coord4;
|
||||
}
|
||||
|
||||
vec4 texture2DProj(const sampler2D sampler, const vec3 coord, const float bias)
|
||||
{
|
||||
// do projection here (there's no vec4_texbp2d instruction)
|
||||
vec4 pcoord;
|
||||
pcoord.xy = coord.xy / coord.z;
|
||||
pcoord.w = bias;
|
||||
__asm vec4_tex_2d_bias __retVal, sampler, pcoord;
|
||||
}
|
||||
|
||||
vec4 texture2DProj(const sampler2D sampler, const vec4 coord, const float bias)
|
||||
{
|
||||
// do projection here (there's no vec4_texbp2d instruction)
|
||||
vec4 pcoord;
|
||||
pcoord.xy = coord.xy / coord.w;
|
||||
pcoord.w = bias;
|
||||
__asm vec4_tex_2d_bias __retVal, sampler, pcoord;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
vec4 texture3D(const sampler3D sampler, const vec3 coord, const float bias)
|
||||
{
|
||||
vec4 coord4;
|
||||
coord4.xyz = coord.xyz;
|
||||
coord4.w = bias;
|
||||
__asm vec4_tex_3d_bias __retVal, sampler, coord4;
|
||||
}
|
||||
|
||||
vec4 texture3DProj(const sampler3D sampler, const vec4 coord, const float bias)
|
||||
{
|
||||
// do projection here (there's no vec4_texbp3d instruction)
|
||||
vec4 pcoord;
|
||||
pcoord.xyz = coord.xyz / coord.w;
|
||||
pcoord.w = bias;
|
||||
__asm vec4_tex_3d_bias __retVal, sampler, pcoord;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
vec4 textureCube(const samplerCube sampler, const vec3 coord, const float bias)
|
||||
{
|
||||
vec4 coord4;
|
||||
coord4.xyz = coord;
|
||||
coord4.w = bias;
|
||||
__asm vec4_tex_cube __retVal, sampler, coord4;
|
||||
}
|
||||
|
||||
|
||||
|
||||
vec4 shadow1D(const sampler1DShadow sampler, const vec3 coord, const float bias)
|
||||
{
|
||||
vec4 coord4;
|
||||
coord4.xyz = coord;
|
||||
coord4.w = bias;
|
||||
__asm vec4_tex_1d_bias_shadow __retVal, sampler, coord4;
|
||||
}
|
||||
|
||||
vec4 shadow1DProj(const sampler1DShadow sampler, const vec4 coord, const float bias)
|
||||
{
|
||||
vec4 pcoord;
|
||||
pcoord.x = coord.x / coord.w;
|
||||
pcoord.z = coord.z;
|
||||
pcoord.w = bias;
|
||||
__asm vec4_tex_1d_bias_shadow __retVal, sampler, pcoord;
|
||||
}
|
||||
|
||||
vec4 shadow2D(const sampler2DShadow sampler, const vec3 coord, const float bias)
|
||||
{
|
||||
vec4 coord4;
|
||||
coord4.xyz = coord;
|
||||
coord4.w = bias;
|
||||
__asm vec4_tex_2d_bias_shadow __retVal, sampler, coord4;
|
||||
}
|
||||
|
||||
vec4 shadow2DProj(const sampler2DShadow sampler, const vec4 coord, const float bias)
|
||||
{
|
||||
vec4 pcoord;
|
||||
pcoord.xy = coord.xy / coord.w;
|
||||
pcoord.z = coord.z;
|
||||
pcoord.w = bias;
|
||||
__asm vec4_tex_2d_bias_shadow __retVal, sampler, pcoord;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//// GL_EXT_texture_array
|
||||
|
||||
vec4 texture1DArray(const sampler1DArray sampler, const vec2 coord)
|
||||
{
|
||||
vec4 coord4;
|
||||
coord4.xy = coord;
|
||||
__asm vec4_tex_1d_array __retVal, sampler, coord4;
|
||||
}
|
||||
|
||||
vec4 texture1DArray(const sampler1DArray sampler, const vec2 coord, const float bias)
|
||||
{
|
||||
vec4 coord4;
|
||||
coord4.xy = coord;
|
||||
coord4.w = bias;
|
||||
__asm vec4_tex_1d_array_bias __retVal, sampler, coord4;
|
||||
}
|
||||
|
||||
vec4 texure2DArray(const sampler2DArray sampler, const vec3 coord)
|
||||
{
|
||||
vec4 coord4;
|
||||
coord4.xyz = coord;
|
||||
__asm vec4_tex_2d_array __retVal, sampler, coord4;
|
||||
}
|
||||
|
||||
vec4 texture2DArray(const sampler2DArray sampler, const vec3 coord, const float bias)
|
||||
{
|
||||
vec4 coord4;
|
||||
coord4.xyz = coord;
|
||||
coord4.w = bias;
|
||||
__asm vec4_tex_2d_array_bias __retVal, sampler, coord4;
|
||||
}
|
||||
|
||||
vec4 shadow1DArray(const sampler1DArrayShadow sampler, const vec2 coord)
|
||||
{
|
||||
vec4 coord4;
|
||||
coord4.xy = coord;
|
||||
__asm vec4_tex_1d_array_shadow __retVal, sampler, coord4;
|
||||
}
|
||||
|
||||
vec4 shadow1DArray(const sampler1DArrayShadow sampler, const vec2 coord, const float bias)
|
||||
{
|
||||
vec4 coord4;
|
||||
coord4.xy = coord;
|
||||
coord4.w = bias;
|
||||
__asm vec4_tex_1d_array_bias_shadow __retVal, sampler, coord4;
|
||||
}
|
||||
|
||||
vec4 shadow2DArray(const sampler2DArrayShadow sampler, const vec3 coord)
|
||||
{
|
||||
vec4 coord4;
|
||||
coord4.xyz = coord;
|
||||
__asm vec4_tex_2d_array_shadow __retVal, sampler, coord4;
|
||||
}
|
||||
|
||||
vec4 shadow2DArray(const sampler2DArrayShadow sampler, const vec3 coord, const float bias)
|
||||
{
|
||||
vec4 coord4;
|
||||
coord4.xyz = coord;
|
||||
coord4.w = bias;
|
||||
__asm vec4_tex_2d_array_bias_shadow __retVal, sampler, coord4;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//
|
||||
// 8.8 Fragment Processing Functions
|
||||
//
|
||||
|
||||
float dFdx(const float p)
|
||||
{
|
||||
__asm vec4_ddx __retVal.x, p.xxxx;
|
||||
}
|
||||
|
||||
vec2 dFdx(const vec2 p)
|
||||
{
|
||||
__asm vec4_ddx __retVal.xy, p.xyyy;
|
||||
}
|
||||
|
||||
vec3 dFdx(const vec3 p)
|
||||
{
|
||||
__asm vec4_ddx __retVal.xyz, p.xyzz;
|
||||
}
|
||||
|
||||
vec4 dFdx(const vec4 p)
|
||||
{
|
||||
__asm vec4_ddx __retVal, p;
|
||||
}
|
||||
|
||||
float dFdy(const float p)
|
||||
{
|
||||
__asm vec4_ddy __retVal.x, p.xxxx;
|
||||
}
|
||||
|
||||
vec2 dFdy(const vec2 p)
|
||||
{
|
||||
__asm vec4_ddy __retVal.xy, p.xyyy;
|
||||
}
|
||||
|
||||
vec3 dFdy(const vec3 p)
|
||||
{
|
||||
__asm vec4_ddy __retVal.xyz, p.xyzz;
|
||||
}
|
||||
|
||||
vec4 dFdy(const vec4 p)
|
||||
{
|
||||
__asm vec4_ddy __retVal, p;
|
||||
}
|
||||
|
||||
float fwidth (const float p)
|
||||
{
|
||||
// XXX hand-write with __asm
|
||||
return abs(dFdx(p)) + abs(dFdy(p));
|
||||
}
|
||||
|
||||
vec2 fwidth(const vec2 p)
|
||||
{
|
||||
// XXX hand-write with __asm
|
||||
return abs(dFdx(p)) + abs(dFdy(p));
|
||||
}
|
||||
|
||||
vec3 fwidth(const vec3 p)
|
||||
{
|
||||
// XXX hand-write with __asm
|
||||
return abs(dFdx(p)) + abs(dFdy(p));
|
||||
}
|
||||
|
||||
vec4 fwidth(const vec4 p)
|
||||
{
|
||||
// XXX hand-write with __asm
|
||||
return abs(dFdx(p)) + abs(dFdy(p));
|
||||
}
|
||||
|
|
@ -1,55 +0,0 @@
|
|||
/*
|
||||
* Mesa 3-D graphics library
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included
|
||||
* in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
|
||||
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
const int _mesa_VerticesInMax = 6;
|
||||
|
||||
__fixed_input int gl_PrimitiveIDIn;
|
||||
__fixed_output int gl_PrimitiveID;
|
||||
__fixed_output int gl_Layer;
|
||||
|
||||
|
||||
varying in vec4 gl_FrontColorIn[_mesa_VerticesInMax];
|
||||
varying in vec4 gl_BackColorIn[_mesa_VerticesInMax];
|
||||
varying in vec4 gl_FrontSecondaryColorIn[_mesa_VerticesInMax];
|
||||
varying in vec4 gl_BackSecondaryColorIn[_mesa_VerticesInMax];
|
||||
/*varying in vec4 gl_TexCoordIn[_mesa_VerticesInMax][gl_MaxTextureCoords];*/
|
||||
varying in float gl_FogFragCoordIn[_mesa_VerticesInMax];
|
||||
varying in vec4 gl_PositionIn[_mesa_VerticesInMax];
|
||||
varying in float gl_PointSizeIn[_mesa_VerticesInMax];
|
||||
varying in vec4 gl_ClipVertexIn[_mesa_VerticesInMax];
|
||||
|
||||
varying out vec4 gl_Position;
|
||||
varying out vec4 gl_FrontColor;
|
||||
varying out vec4 gl_BackColor;
|
||||
varying out vec4 gl_FrontSecondaryColor;
|
||||
varying out vec4 gl_BackSecondaryColor;
|
||||
varying out vec4 gl_TexCoord[gl_MaxTextureCoords];
|
||||
varying out float gl_FogFragCoord;
|
||||
|
||||
void EmitVertex()
|
||||
{
|
||||
__asm emit_vertex;
|
||||
}
|
||||
|
||||
void EndPrimitive()
|
||||
{
|
||||
__asm end_primitive;
|
||||
}
|
|
@ -1,210 +0,0 @@
|
|||
/*
|
||||
* Mesa 3-D graphics library
|
||||
* Version: 6.5
|
||||
*
|
||||
* Copyright (C) 2006 Brian Paul All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included
|
||||
* in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
|
||||
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
//
|
||||
// From Shader Spec, ver. 1.10, rev. 59
|
||||
//
|
||||
|
||||
__fixed_output vec4 gl_Position;
|
||||
__fixed_output float gl_PointSize;
|
||||
__fixed_output vec4 gl_ClipVertex;
|
||||
|
||||
attribute vec4 gl_Color;
|
||||
attribute vec4 gl_SecondaryColor;
|
||||
attribute vec3 gl_Normal;
|
||||
attribute vec4 gl_Vertex;
|
||||
attribute vec4 gl_MultiTexCoord0;
|
||||
attribute vec4 gl_MultiTexCoord1;
|
||||
attribute vec4 gl_MultiTexCoord2;
|
||||
attribute vec4 gl_MultiTexCoord3;
|
||||
attribute vec4 gl_MultiTexCoord4;
|
||||
attribute vec4 gl_MultiTexCoord5;
|
||||
attribute vec4 gl_MultiTexCoord6;
|
||||
attribute vec4 gl_MultiTexCoord7;
|
||||
attribute float gl_FogCoord;
|
||||
|
||||
varying vec4 gl_FrontColor;
|
||||
varying vec4 gl_BackColor;
|
||||
varying vec4 gl_FrontSecondaryColor;
|
||||
varying vec4 gl_BackSecondaryColor;
|
||||
varying vec4 gl_TexCoord[gl_MaxTextureCoords];
|
||||
varying float gl_FogFragCoord;
|
||||
|
||||
//
|
||||
// Geometric Functions
|
||||
//
|
||||
|
||||
vec4 ftransform()
|
||||
{
|
||||
__retVal = gl_ModelViewProjectionMatrix[0] * gl_Vertex.xxxx
|
||||
+ gl_ModelViewProjectionMatrix[1] * gl_Vertex.yyyy
|
||||
+ gl_ModelViewProjectionMatrix[2] * gl_Vertex.zzzz
|
||||
+ gl_ModelViewProjectionMatrix[3] * gl_Vertex.wwww;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//
|
||||
// 8.7 Texture Lookup Functions
|
||||
// These are pretty much identical to the ones in slang_fragment_builtin.gc
|
||||
// When used in a vertex program, the texture sample instructions should not
|
||||
// be using a LOD term so it's effectively zero. Adding 'lod' to that does
|
||||
// what we want.
|
||||
//
|
||||
|
||||
vec4 texture1DLod(const sampler1D sampler, const float coord, const float lod)
|
||||
{
|
||||
vec4 coord4;
|
||||
coord4.x = coord;
|
||||
coord4.w = lod;
|
||||
__asm vec4_tex_1d_bias __retVal, sampler, coord4;
|
||||
}
|
||||
|
||||
vec4 texture1DProjLod(const sampler1D sampler, const vec2 coord, const float lod)
|
||||
{
|
||||
vec4 pcoord;
|
||||
pcoord.x = coord.x / coord.y;
|
||||
pcoord.w = lod;
|
||||
__asm vec4_tex_1d_bias __retVal, sampler, pcoord;
|
||||
}
|
||||
|
||||
vec4 texture1DProjLod(const sampler1D sampler, const vec4 coord, const float lod)
|
||||
{
|
||||
vec4 pcoord;
|
||||
pcoord.x = coord.x / coord.z;
|
||||
pcoord.w = lod;
|
||||
__asm vec4_tex_1d_bias __retVal, sampler, pcoord;
|
||||
}
|
||||
|
||||
|
||||
|
||||
vec4 texture2DLod(const sampler2D sampler, const vec2 coord, const float lod)
|
||||
{
|
||||
vec4 coord4;
|
||||
coord4.xy = coord.xy;
|
||||
coord4.w = lod;
|
||||
__asm vec4_tex_2d_bias __retVal, sampler, coord4;
|
||||
}
|
||||
|
||||
vec4 texture2DProjLod(const sampler2D sampler, const vec3 coord, const float lod)
|
||||
{
|
||||
vec4 pcoord;
|
||||
pcoord.xy = coord.xy / coord.z;
|
||||
pcoord.w = lod;
|
||||
__asm vec4_tex_2d_bias __retVal, sampler, pcoord;
|
||||
}
|
||||
|
||||
vec4 texture2DProjLod(const sampler2D sampler, const vec4 coord, const float lod)
|
||||
{
|
||||
vec4 pcoord;
|
||||
pcoord.xy = coord.xy / coord.z;
|
||||
pcoord.w = lod;
|
||||
__asm vec4_tex_2d_bias __retVal, sampler, pcoord;
|
||||
}
|
||||
|
||||
|
||||
vec4 texture3DLod(const sampler3D sampler, const vec3 coord, const float lod)
|
||||
{
|
||||
vec4 coord4;
|
||||
coord4.xyz = coord.xyz;
|
||||
coord4.w = lod;
|
||||
__asm vec4_tex_3d_bias __retVal, sampler, coord4;
|
||||
}
|
||||
|
||||
vec4 texture3DProjLod(const sampler3D sampler, const vec4 coord, const float lod)
|
||||
{
|
||||
// do projection here (there's no vec4_tex_3d_bias_proj instruction)
|
||||
vec4 pcoord;
|
||||
pcoord.xyz = coord.xyz / coord.w;
|
||||
pcoord.w = lod;
|
||||
__asm vec4_tex_3d_bias __retVal, sampler, pcoord;
|
||||
}
|
||||
|
||||
|
||||
vec4 textureCubeLod(const samplerCube sampler, const vec3 coord, const float lod)
|
||||
{
|
||||
vec4 coord4;
|
||||
coord4.xyz = coord;
|
||||
coord4.w = lod;
|
||||
__asm vec4_tex_cube __retVal, sampler, coord4;
|
||||
}
|
||||
|
||||
|
||||
vec4 shadow1DLod(const sampler1DShadow sampler, const vec3 coord, const float lod)
|
||||
{
|
||||
vec4 coord4;
|
||||
coord4.xyz = coord;
|
||||
coord4.w = lod;
|
||||
__asm vec4_tex_1d_bias_shadow __retVal, sampler, coord4;
|
||||
}
|
||||
|
||||
vec4 shadow1DProjLod(const sampler1DShadow sampler, const vec4 coord,
|
||||
const float lod)
|
||||
{
|
||||
vec4 pcoord;
|
||||
pcoord.x = coord.x / coord.w;
|
||||
pcoord.z = coord.z;
|
||||
pcoord.w = lod;
|
||||
__asm vec4_tex_1d_bias_shadow __retVal, sampler, pcoord;
|
||||
}
|
||||
|
||||
|
||||
vec4 shadow2DLod(const sampler2DShadow sampler, const vec3 coord, const float lod)
|
||||
{
|
||||
vec4 coord4;
|
||||
coord4.xyz = coord;
|
||||
coord4.w = lod;
|
||||
__asm vec4_tex_2d_bias_shadow __retVal, sampler, coord4;
|
||||
}
|
||||
|
||||
vec4 shadow2DProjLod(const sampler2DShadow sampler, const vec4 coord,
|
||||
const float lod)
|
||||
{
|
||||
vec4 pcoord;
|
||||
pcoord.xy = coord.xy / coord.w;
|
||||
pcoord.z = coord.z;
|
||||
pcoord.w = lod;
|
||||
__asm vec4_tex_2d_bias_shadow __retVal, sampler, pcoord;
|
||||
}
|
||||
|
||||
|
||||
//// GL_EXT_texture_array
|
||||
|
||||
vec4 texture1DArrayLod(const sampler1DArray sampler, const vec2 coord, const float lod)
|
||||
{
|
||||
vec4 coord4;
|
||||
coord4.xy = coord;
|
||||
coord4.w = lod;
|
||||
__asm vec4_tex_1d_array_bias __retVal, sampler, coord4;
|
||||
}
|
||||
|
||||
|
||||
vec4 texture2DArrayLod(const sampler2DArray sampler, const vec3 coord, const float lod)
|
||||
{
|
||||
vec4 coord4;
|
||||
coord4.xyz = coord;
|
||||
coord4.w = lod;
|
||||
__asm vec4_tex_2d_array_bias __retVal, sampler, coord4;
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
|
@ -1,68 +0,0 @@
|
|||
/*
|
||||
* Mesa 3-D graphics library
|
||||
* Version: 6.5.3
|
||||
*
|
||||
* Copyright (C) 2005-2007 Brian Paul All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included
|
||||
* in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
|
||||
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
|
||||
#ifndef SLANG_BUILTIN_H
|
||||
#define SLANG_BUILTIN_H
|
||||
|
||||
#include "main/glheader.h"
|
||||
#include "main/mtypes.h"
|
||||
#include "slang_ir.h"
|
||||
|
||||
|
||||
extern GLint
|
||||
_slang_alloc_statevar(slang_ir_node *n,
|
||||
struct gl_program_parameter_list *paramList,
|
||||
GLboolean *direct);
|
||||
|
||||
|
||||
extern GLint
|
||||
_slang_input_index(const char *name, GLenum target, GLuint *swizzleOut,
|
||||
GLboolean *is_array);
|
||||
|
||||
extern GLint
|
||||
_slang_output_index(const char *name, GLenum target);
|
||||
|
||||
|
||||
extern const char *
|
||||
_slang_vert_attrib_name(GLuint attrib);
|
||||
|
||||
extern GLenum
|
||||
_slang_vert_attrib_type(GLuint attrib);
|
||||
|
||||
|
||||
const char *
|
||||
_slang_vertex_output_name(gl_vert_result index);
|
||||
|
||||
const char *
|
||||
_slang_fragment_output_name(gl_frag_result index);
|
||||
|
||||
const char *
|
||||
_slang_geometry_output_name(gl_geom_result index);
|
||||
|
||||
GLenum
|
||||
_slang_vertex_output_type(gl_vert_result index);
|
||||
|
||||
|
||||
#endif /* SLANG_BUILTIN_H */
|
File diff suppressed because it is too large
Load Diff
|
@ -1,78 +0,0 @@
|
|||
/*
|
||||
* Mesa 3-D graphics library
|
||||
* Version: 6.5.3
|
||||
*
|
||||
* Copyright (C) 2005-2007 Brian Paul All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included
|
||||
* in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
|
||||
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
|
||||
#ifndef SLANG_CODEGEN_H
|
||||
#define SLANG_CODEGEN_H
|
||||
|
||||
|
||||
#include "main/glheader.h"
|
||||
#include "slang_compile.h"
|
||||
#include "slang_compile_variable.h"
|
||||
#include "slang_typeinfo.h"
|
||||
#include "slang_utility.h"
|
||||
#include "slang_vartable.h"
|
||||
|
||||
struct slang_function_;
|
||||
|
||||
#define MAX_LOOP_DEPTH 30
|
||||
|
||||
|
||||
typedef struct slang_assemble_ctx_
|
||||
{
|
||||
slang_atom_pool *atoms;
|
||||
slang_name_space space;
|
||||
struct gl_program *program;
|
||||
struct gl_sl_pragmas *pragmas;
|
||||
slang_var_table *vartable;
|
||||
slang_info_log *log;
|
||||
GLboolean allow_uniform_initializers;
|
||||
|
||||
/* current loop stack */
|
||||
const slang_operation *LoopOperStack[MAX_LOOP_DEPTH];
|
||||
struct slang_ir_node_ *LoopIRStack[MAX_LOOP_DEPTH];
|
||||
GLuint LoopDepth;
|
||||
|
||||
/* current function */
|
||||
struct slang_function_ *CurFunction;
|
||||
struct slang_label_ *curFuncEndLabel;
|
||||
GLboolean UseReturnFlag;
|
||||
|
||||
GLboolean UnresolvedRefs;
|
||||
GLboolean EmitContReturn;
|
||||
} slang_assemble_ctx;
|
||||
|
||||
|
||||
extern GLuint
|
||||
_slang_sizeof_type_specifier(const slang_type_specifier *spec);
|
||||
|
||||
extern GLboolean
|
||||
_slang_codegen_function(slang_assemble_ctx *A , struct slang_function_ *fun);
|
||||
|
||||
extern GLboolean
|
||||
_slang_codegen_global_variable(slang_assemble_ctx *A, slang_variable *var,
|
||||
slang_unit_type type);
|
||||
|
||||
|
||||
#endif /* SLANG_CODEGEN_H */
|
File diff suppressed because it is too large
Load Diff
|
@ -1,103 +0,0 @@
|
|||
/*
|
||||
* Mesa 3-D graphics library
|
||||
* Version: 6.5
|
||||
*
|
||||
* Copyright (C) 2005-2006 Brian Paul All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included
|
||||
* in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
|
||||
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#if !defined SLANG_COMPILE_H
|
||||
#define SLANG_COMPILE_H
|
||||
|
||||
#include "main/glheader.h"
|
||||
#include "main/mtypes.h"
|
||||
#include "slang_compile_function.h"
|
||||
#include "slang_compile_struct.h"
|
||||
#include "slang_compile_variable.h"
|
||||
#include "slang_utility.h"
|
||||
|
||||
struct slang_code_object_;
|
||||
|
||||
#if defined __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef struct slang_name_space_
|
||||
{
|
||||
struct slang_function_scope_ *funcs;
|
||||
struct slang_struct_scope_ *structs;
|
||||
struct slang_variable_scope_ *vars;
|
||||
} slang_name_space;
|
||||
|
||||
typedef enum slang_unit_type_
|
||||
{
|
||||
SLANG_UNIT_FRAGMENT_SHADER,
|
||||
SLANG_UNIT_VERTEX_SHADER,
|
||||
SLANG_UNIT_GEOMETRY_SHADER,
|
||||
SLANG_UNIT_FRAGMENT_BUILTIN,
|
||||
SLANG_UNIT_VERTEX_BUILTIN,
|
||||
SLANG_UNIT_GEOMETRY_BUILTIN
|
||||
} slang_unit_type;
|
||||
|
||||
|
||||
typedef struct slang_code_unit_
|
||||
{
|
||||
slang_variable_scope vars;
|
||||
slang_function_scope funs;
|
||||
slang_struct_scope structs;
|
||||
slang_unit_type type;
|
||||
struct slang_code_object_ *object;
|
||||
} slang_code_unit;
|
||||
|
||||
|
||||
extern GLvoid
|
||||
_slang_code_unit_ctr (slang_code_unit *, struct slang_code_object_ *);
|
||||
|
||||
extern GLvoid
|
||||
_slang_code_unit_dtr (slang_code_unit *);
|
||||
|
||||
#define SLANG_BUILTIN_CORE 0
|
||||
#define SLANG_BUILTIN_120_CORE 1
|
||||
#define SLANG_BUILTIN_COMMON 2
|
||||
#define SLANG_BUILTIN_TARGET 3
|
||||
|
||||
#define SLANG_BUILTIN_TOTAL 4
|
||||
|
||||
typedef struct slang_code_object_
|
||||
{
|
||||
slang_code_unit builtin[SLANG_BUILTIN_TOTAL];
|
||||
slang_code_unit unit;
|
||||
slang_atom_pool atompool;
|
||||
} slang_code_object;
|
||||
|
||||
extern GLvoid
|
||||
_slang_code_object_ctr (slang_code_object *);
|
||||
|
||||
extern GLvoid
|
||||
_slang_code_object_dtr (slang_code_object *);
|
||||
|
||||
extern GLboolean
|
||||
_slang_compile (GLcontext *ctx, struct gl_shader *shader);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
@ -1,262 +0,0 @@
|
|||
/*
|
||||
* Mesa 3-D graphics library
|
||||
* Version: 6.5
|
||||
*
|
||||
* Copyright (C) 2005-2006 Brian Paul All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included
|
||||
* in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
|
||||
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
/**
|
||||
* \file slang_compile_function.c
|
||||
* slang front-end compiler
|
||||
* \author Michal Krol
|
||||
*/
|
||||
|
||||
#include "main/imports.h"
|
||||
#include "slang_compile.h"
|
||||
#include "slang_mem.h"
|
||||
|
||||
|
||||
int
|
||||
slang_function_construct(slang_function * func)
|
||||
{
|
||||
func->kind = SLANG_FUNC_ORDINARY;
|
||||
if (!slang_variable_construct(&func->header))
|
||||
return 0;
|
||||
|
||||
func->parameters = (slang_variable_scope *)
|
||||
_slang_alloc(sizeof(slang_variable_scope));
|
||||
if (func->parameters == NULL) {
|
||||
slang_variable_destruct(&func->header);
|
||||
return 0;
|
||||
}
|
||||
|
||||
_slang_variable_scope_ctr(func->parameters);
|
||||
func->param_count = 0;
|
||||
func->body = NULL;
|
||||
return 1;
|
||||
}
|
||||
|
||||
void
|
||||
slang_function_destruct(slang_function * func)
|
||||
{
|
||||
slang_variable_destruct(&func->header);
|
||||
slang_variable_scope_destruct(func->parameters);
|
||||
_slang_free(func->parameters);
|
||||
if (func->body != NULL) {
|
||||
slang_operation_destruct(func->body);
|
||||
_slang_free(func->body);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
slang_function *
|
||||
slang_function_new(slang_function_kind kind)
|
||||
{
|
||||
slang_function *fun = (slang_function *)
|
||||
_slang_alloc(sizeof(slang_function));
|
||||
if (fun) {
|
||||
slang_function_construct(fun);
|
||||
fun->kind = kind;
|
||||
}
|
||||
return fun;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* slang_function_scope
|
||||
*/
|
||||
|
||||
GLvoid
|
||||
_slang_function_scope_ctr(slang_function_scope * self)
|
||||
{
|
||||
self->functions = NULL;
|
||||
self->num_functions = 0;
|
||||
self->outer_scope = NULL;
|
||||
}
|
||||
|
||||
void
|
||||
slang_function_scope_destruct(slang_function_scope * scope)
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
for (i = 0; i < scope->num_functions; i++)
|
||||
slang_function_destruct(scope->functions + i);
|
||||
_slang_free(scope->functions);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Does this function have a non-void return value?
|
||||
*/
|
||||
GLboolean
|
||||
_slang_function_has_return_value(const slang_function *fun)
|
||||
{
|
||||
return fun->header.type.specifier.type != SLANG_SPEC_VOID;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Search a list of functions for a particular function by name.
|
||||
* \param funcs the list of functions to search
|
||||
* \param a_name the name to search for
|
||||
* \param all_scopes if non-zero, search containing scopes too.
|
||||
* \return pointer to found function, or NULL.
|
||||
*/
|
||||
int
|
||||
slang_function_scope_find_by_name(slang_function_scope * funcs,
|
||||
slang_atom a_name, int all_scopes)
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
for (i = 0; i < funcs->num_functions; i++)
|
||||
if (a_name == funcs->functions[i].header.a_name)
|
||||
return 1;
|
||||
if (all_scopes && funcs->outer_scope != NULL)
|
||||
return slang_function_scope_find_by_name(funcs->outer_scope, a_name, 1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Search a list of functions for a particular function (for implementing
|
||||
* function calls. Matching is done by first comparing the function's name,
|
||||
* then the function's parameter list.
|
||||
*
|
||||
* \param funcs the list of functions to search
|
||||
* \param fun the function to search for
|
||||
* \param all_scopes if non-zero, search containing scopes too.
|
||||
* \return pointer to found function, or NULL.
|
||||
*/
|
||||
slang_function *
|
||||
slang_function_scope_find(slang_function_scope * funcs, slang_function * fun,
|
||||
int all_scopes)
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
for (i = 0; i < funcs->num_functions; i++) {
|
||||
slang_function *f = &funcs->functions[i];
|
||||
const GLuint haveRetValue = 0;
|
||||
#if 0
|
||||
= (f->header.type.specifier.type != SLANG_SPEC_VOID);
|
||||
#endif
|
||||
unsigned int j;
|
||||
|
||||
/*
|
||||
printf("Compare name %s to %s (ret %u, %d, %d)\n",
|
||||
(char *) fun->header.a_name, (char *) f->header.a_name,
|
||||
haveRetValue,
|
||||
fun->param_count, f->param_count);
|
||||
*/
|
||||
|
||||
if (fun->header.a_name != f->header.a_name)
|
||||
continue;
|
||||
if (fun->param_count != f->param_count)
|
||||
continue;
|
||||
for (j = haveRetValue; j < fun->param_count; j++) {
|
||||
if (!slang_type_specifier_equal
|
||||
(&fun->parameters->variables[j]->type.specifier,
|
||||
&f->parameters->variables[j]->type.specifier))
|
||||
break;
|
||||
}
|
||||
if (j == fun->param_count) {
|
||||
/*
|
||||
printf("Found match\n");
|
||||
*/
|
||||
return f;
|
||||
}
|
||||
}
|
||||
/*
|
||||
printf("Not found\n");
|
||||
*/
|
||||
if (all_scopes && funcs->outer_scope != NULL)
|
||||
return slang_function_scope_find(funcs->outer_scope, fun, 1);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Lookup a function according to name and parameter count/types.
|
||||
*/
|
||||
slang_function *
|
||||
_slang_function_locate(const slang_function_scope * funcs, slang_atom a_name,
|
||||
slang_operation * args, GLuint num_args,
|
||||
const slang_name_space * space, slang_atom_pool * atoms,
|
||||
slang_info_log *log, GLboolean *error)
|
||||
{
|
||||
slang_typeinfo arg_ti[100];
|
||||
GLuint i;
|
||||
|
||||
*error = GL_FALSE;
|
||||
|
||||
/* determine type of each argument */
|
||||
assert(num_args < 100);
|
||||
for (i = 0; i < num_args; i++) {
|
||||
if (!slang_typeinfo_construct(&arg_ti[i]))
|
||||
return NULL;
|
||||
if (!_slang_typeof_operation(&args[i], space, &arg_ti[i], atoms, log)) {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/* loop over function scopes */
|
||||
while (funcs) {
|
||||
|
||||
/* look for function with matching name and argument/param types */
|
||||
for (i = 0; i < funcs->num_functions; i++) {
|
||||
slang_function *f = &funcs->functions[i];
|
||||
const GLuint haveRetValue = _slang_function_has_return_value(f);
|
||||
GLuint j;
|
||||
|
||||
if (a_name != f->header.a_name)
|
||||
continue;
|
||||
if (f->param_count - haveRetValue != num_args)
|
||||
continue;
|
||||
|
||||
/* compare parameter / argument types */
|
||||
for (j = 0; j < num_args; j++) {
|
||||
if (!slang_type_specifier_compatible(&arg_ti[j].spec,
|
||||
&f->parameters->variables[j]->type.specifier)) {
|
||||
/* param/arg types don't match */
|
||||
break;
|
||||
}
|
||||
|
||||
/* "out" and "inout" formal parameter requires the actual
|
||||
* argument to be an l-value.
|
||||
*/
|
||||
if (!arg_ti[j].can_be_referenced &&
|
||||
(f->parameters->variables[j]->type.qualifier == SLANG_QUAL_OUT ||
|
||||
f->parameters->variables[j]->type.qualifier == SLANG_QUAL_INOUT)) {
|
||||
/* param is not an lvalue! */
|
||||
*error = GL_TRUE;
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
if (j == num_args) {
|
||||
/* name and args match! */
|
||||
return f;
|
||||
}
|
||||
}
|
||||
|
||||
funcs = funcs->outer_scope;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
|
@ -1,100 +0,0 @@
|
|||
/*
|
||||
* Mesa 3-D graphics library
|
||||
* Version: 6.5.2
|
||||
*
|
||||
* Copyright (C) 2005-2006 Brian Paul All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included
|
||||
* in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
|
||||
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef SLANG_COMPILE_FUNCTION_H
|
||||
#define SLANG_COMPILE_FUNCTION_H
|
||||
|
||||
#include "main/glheader.h"
|
||||
#include "slang_compile_operation.h"
|
||||
#include "slang_compile_variable.h"
|
||||
#include "slang_log.h"
|
||||
#include "slang_utility.h"
|
||||
|
||||
struct slang_name_space_;
|
||||
struct slang_operation_;
|
||||
|
||||
/**
|
||||
* Types of functions.
|
||||
*/
|
||||
typedef enum slang_function_kind_
|
||||
{
|
||||
SLANG_FUNC_ORDINARY,
|
||||
SLANG_FUNC_CONSTRUCTOR,
|
||||
SLANG_FUNC_OPERATOR
|
||||
} slang_function_kind;
|
||||
|
||||
|
||||
/**
|
||||
* Description of a compiled shader function.
|
||||
*/
|
||||
typedef struct slang_function_
|
||||
{
|
||||
slang_function_kind kind;
|
||||
slang_variable header; /**< The function's name and return type */
|
||||
slang_variable_scope *parameters; /**< formal parameters AND local vars */
|
||||
unsigned int param_count; /**< number of formal params (no locals) */
|
||||
slang_operation *body; /**< The instruction tree */
|
||||
} slang_function;
|
||||
|
||||
extern int slang_function_construct(slang_function *);
|
||||
extern void slang_function_destruct(slang_function *);
|
||||
extern slang_function *slang_function_new(slang_function_kind kind);
|
||||
|
||||
extern GLboolean
|
||||
_slang_function_has_return_value(const slang_function *fun);
|
||||
|
||||
|
||||
/**
|
||||
* Basically, a list of compiled functions.
|
||||
*/
|
||||
typedef struct slang_function_scope_
|
||||
{
|
||||
slang_function *functions;
|
||||
GLuint num_functions;
|
||||
struct slang_function_scope_ *outer_scope;
|
||||
} slang_function_scope;
|
||||
|
||||
|
||||
extern GLvoid
|
||||
_slang_function_scope_ctr(slang_function_scope *);
|
||||
|
||||
extern void
|
||||
slang_function_scope_destruct(slang_function_scope *);
|
||||
|
||||
extern int
|
||||
slang_function_scope_find_by_name(slang_function_scope *, slang_atom, int);
|
||||
|
||||
extern slang_function *
|
||||
slang_function_scope_find(slang_function_scope *, slang_function *, int);
|
||||
|
||||
extern struct slang_function_ *
|
||||
_slang_function_locate(const struct slang_function_scope_ *funcs,
|
||||
slang_atom name, struct slang_operation_ *params,
|
||||
GLuint num_params,
|
||||
const struct slang_name_space_ *space,
|
||||
slang_atom_pool *atoms, slang_info_log *log,
|
||||
GLboolean *error);
|
||||
|
||||
|
||||
#endif /* SLANG_COMPILE_FUNCTION_H */
|
|
@ -1,334 +0,0 @@
|
|||
/*
|
||||
* Mesa 3-D graphics library
|
||||
* Version: 6.5.2
|
||||
*
|
||||
* Copyright (C) 2005-2006 Brian Paul All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included
|
||||
* in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
|
||||
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
/**
|
||||
* \file slang_compile_operation.c
|
||||
* slang front-end compiler
|
||||
* \author Michal Krol
|
||||
*/
|
||||
|
||||
#include "main/imports.h"
|
||||
#include "slang_compile.h"
|
||||
#include "slang_mem.h"
|
||||
|
||||
|
||||
/**
|
||||
* Init a slang_operation object
|
||||
*/
|
||||
GLboolean
|
||||
slang_operation_construct(slang_operation * oper)
|
||||
{
|
||||
oper->type = SLANG_OPER_NONE;
|
||||
oper->children = NULL;
|
||||
oper->num_children = 0;
|
||||
oper->literal[0] = 0.0;
|
||||
oper->literal_size = 1;
|
||||
oper->array_constructor = GL_FALSE;
|
||||
oper->a_id = SLANG_ATOM_NULL;
|
||||
oper->a_obj = SLANG_ATOM_NULL;
|
||||
oper->locals = _slang_variable_scope_new(NULL);
|
||||
if (oper->locals == NULL)
|
||||
return GL_FALSE;
|
||||
_slang_variable_scope_ctr(oper->locals);
|
||||
oper->fun = NULL;
|
||||
oper->var = NULL;
|
||||
oper->label = NULL;
|
||||
return GL_TRUE;
|
||||
}
|
||||
|
||||
void
|
||||
slang_operation_destruct(slang_operation * oper)
|
||||
{
|
||||
GLuint i;
|
||||
|
||||
for (i = 0; i < oper->num_children; i++)
|
||||
slang_operation_destruct(oper->children + i);
|
||||
_slang_free(oper->children);
|
||||
slang_variable_scope_destruct(oper->locals);
|
||||
_slang_free(oper->locals);
|
||||
oper->children = NULL;
|
||||
oper->num_children = 0;
|
||||
oper->locals = NULL;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Recursively traverse 'oper', replacing occurances of 'oldScope' with
|
||||
* 'newScope' in the oper->locals->outer_scope field.
|
||||
*/
|
||||
void
|
||||
slang_replace_scope(slang_operation *oper,
|
||||
slang_variable_scope *oldScope,
|
||||
slang_variable_scope *newScope)
|
||||
{
|
||||
GLuint i;
|
||||
|
||||
if (oper->locals != newScope &&
|
||||
oper->locals->outer_scope == oldScope) {
|
||||
/* found. replace old w/ new */
|
||||
oper->locals->outer_scope = newScope;
|
||||
}
|
||||
|
||||
if (oper->type == SLANG_OPER_VARIABLE_DECL) {
|
||||
/* search/replace in the initializer */
|
||||
slang_variable *var;
|
||||
var = _slang_variable_locate(oper->locals, oper->a_id, GL_TRUE);
|
||||
if (var && var->initializer) {
|
||||
slang_replace_scope(var->initializer, oldScope, newScope);
|
||||
}
|
||||
}
|
||||
|
||||
/* search/replace in children */
|
||||
for (i = 0; i < oper->num_children; i++) {
|
||||
slang_replace_scope(&oper->children[i], oldScope, newScope);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Recursively copy a slang_operation node.
|
||||
* \param x copy target
|
||||
* \param y copy source
|
||||
* \return GL_TRUE for success, GL_FALSE if failure
|
||||
*/
|
||||
GLboolean
|
||||
slang_operation_copy(slang_operation * x, const slang_operation * y)
|
||||
{
|
||||
slang_operation z;
|
||||
GLuint i;
|
||||
|
||||
if (!slang_operation_construct(&z))
|
||||
return GL_FALSE;
|
||||
z.type = y->type;
|
||||
if (y->num_children > 0) {
|
||||
z.children = (slang_operation *)
|
||||
_slang_alloc(y->num_children * sizeof(slang_operation));
|
||||
if (z.children == NULL) {
|
||||
slang_operation_destruct(&z);
|
||||
return GL_FALSE;
|
||||
}
|
||||
}
|
||||
for (z.num_children = 0; z.num_children < y->num_children;
|
||||
z.num_children++) {
|
||||
if (!slang_operation_construct(&z.children[z.num_children])) {
|
||||
slang_operation_destruct(&z);
|
||||
return GL_FALSE;
|
||||
}
|
||||
}
|
||||
for (i = 0; i < z.num_children; i++) {
|
||||
if (!slang_operation_copy(&z.children[i], &y->children[i])) {
|
||||
slang_operation_destruct(&z);
|
||||
return GL_FALSE;
|
||||
}
|
||||
}
|
||||
z.literal[0] = y->literal[0];
|
||||
z.literal[1] = y->literal[1];
|
||||
z.literal[2] = y->literal[2];
|
||||
z.literal[3] = y->literal[3];
|
||||
z.literal_size = y->literal_size;
|
||||
assert(y->literal_size >= 1);
|
||||
assert(y->literal_size <= 4);
|
||||
z.a_id = y->a_id;
|
||||
if (y->locals) {
|
||||
if (!slang_variable_scope_copy(z.locals, y->locals)) {
|
||||
slang_operation_destruct(&z);
|
||||
return GL_FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
/* update scoping for children */
|
||||
for (i = 0; i < y->num_children; i++) {
|
||||
if (y->children[i].locals &&
|
||||
y->children[i].locals->outer_scope == y->locals) {
|
||||
z.children[i].locals->outer_scope = z.locals;
|
||||
}
|
||||
}
|
||||
|
||||
#if 0
|
||||
z.var = y->var;
|
||||
z.fun = y->fun;
|
||||
#endif
|
||||
slang_operation_destruct(x);
|
||||
*x = z;
|
||||
|
||||
/* If this operation declares a new scope, we need to make sure
|
||||
* all children point to it, not the original operation's scope!
|
||||
*/
|
||||
if (x->type == SLANG_OPER_BLOCK_NEW_SCOPE ||
|
||||
x->type == SLANG_OPER_WHILE ||
|
||||
x->type == SLANG_OPER_FOR) {
|
||||
slang_replace_scope(x, y->locals, x->locals);
|
||||
}
|
||||
|
||||
return GL_TRUE;
|
||||
}
|
||||
|
||||
|
||||
slang_operation *
|
||||
slang_operation_new(GLuint count)
|
||||
{
|
||||
slang_operation *ops
|
||||
= (slang_operation *) _slang_alloc(count * sizeof(slang_operation));
|
||||
assert(count > 0);
|
||||
if (ops) {
|
||||
GLuint i;
|
||||
for (i = 0; i < count; i++)
|
||||
slang_operation_construct(ops + i);
|
||||
}
|
||||
return ops;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Delete operation and all children
|
||||
*/
|
||||
void
|
||||
slang_operation_delete(slang_operation *oper)
|
||||
{
|
||||
slang_operation_destruct(oper);
|
||||
_slang_free(oper);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
slang_operation_free_children(slang_operation *oper)
|
||||
{
|
||||
GLuint i;
|
||||
for (i = 0; i < slang_oper_num_children(oper); i++) {
|
||||
slang_operation *child = slang_oper_child(oper, i);
|
||||
slang_operation_destruct(child);
|
||||
}
|
||||
_slang_free(oper->children);
|
||||
oper->children = NULL;
|
||||
oper->num_children = 0;
|
||||
}
|
||||
|
||||
|
||||
slang_operation *
|
||||
slang_operation_grow(GLuint *numChildren, slang_operation **children)
|
||||
{
|
||||
slang_operation *ops;
|
||||
|
||||
ops = (slang_operation *)
|
||||
_slang_realloc(*children,
|
||||
*numChildren * sizeof(slang_operation),
|
||||
(*numChildren + 1) * sizeof(slang_operation));
|
||||
if (ops) {
|
||||
slang_operation *newOp = ops + *numChildren;
|
||||
if (!slang_operation_construct(newOp)) {
|
||||
_slang_free(ops);
|
||||
*children = NULL;
|
||||
return NULL;
|
||||
}
|
||||
*children = ops;
|
||||
(*numChildren)++;
|
||||
return newOp;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Insert a new slang_operation into an array.
|
||||
* \param numElements pointer to current array size (in/out)
|
||||
* \param array address of the array (in/out)
|
||||
* \param pos position to insert new element
|
||||
* \return pointer to the new operation/element
|
||||
*/
|
||||
slang_operation *
|
||||
slang_operation_insert(GLuint *numElements, slang_operation **array,
|
||||
GLuint pos)
|
||||
{
|
||||
slang_operation *ops;
|
||||
|
||||
assert(pos <= *numElements);
|
||||
|
||||
ops = (slang_operation *)
|
||||
_slang_alloc((*numElements + 1) * sizeof(slang_operation));
|
||||
if (ops) {
|
||||
slang_operation *newOp;
|
||||
newOp = ops + pos;
|
||||
if (pos > 0)
|
||||
memcpy(ops, *array, pos * sizeof(slang_operation));
|
||||
if (pos < *numElements)
|
||||
memcpy(newOp + 1, (*array) + pos,
|
||||
(*numElements - pos) * sizeof(slang_operation));
|
||||
|
||||
if (!slang_operation_construct(newOp)) {
|
||||
_slang_free(ops);
|
||||
*numElements = 0;
|
||||
*array = NULL;
|
||||
return NULL;
|
||||
}
|
||||
if (*array)
|
||||
_slang_free(*array);
|
||||
*array = ops;
|
||||
(*numElements)++;
|
||||
return newOp;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Add/insert new child into given node at given position.
|
||||
* \return pointer to the new child node
|
||||
*/
|
||||
slang_operation *
|
||||
slang_operation_insert_child(slang_operation *oper, GLuint pos)
|
||||
{
|
||||
slang_operation *newOp;
|
||||
|
||||
newOp = slang_operation_insert(&oper->num_children,
|
||||
&oper->children,
|
||||
pos);
|
||||
if (newOp) {
|
||||
newOp->locals->outer_scope = oper->locals;
|
||||
}
|
||||
|
||||
return newOp;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
_slang_operation_swap(slang_operation *oper0, slang_operation *oper1)
|
||||
{
|
||||
slang_operation tmp = *oper0;
|
||||
*oper0 = *oper1;
|
||||
*oper1 = tmp;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
slang_operation_add_children(slang_operation *oper, GLuint num_children)
|
||||
{
|
||||
GLuint i;
|
||||
assert(oper->num_children == 0);
|
||||
assert(oper->children == NULL);
|
||||
oper->num_children = num_children;
|
||||
oper->children = slang_operation_new(num_children);
|
||||
for (i = 0; i < num_children; i++) {
|
||||
oper->children[i].locals = _slang_variable_scope_new(oper->locals);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,230 +0,0 @@
|
|||
/*
|
||||
* Mesa 3-D graphics library
|
||||
* Version: 6.5.2
|
||||
*
|
||||
* Copyright (C) 2005-2006 Brian Paul All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included
|
||||
* in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
|
||||
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef SLANG_COMPILE_OPERATION_H
|
||||
#define SLANG_COMPILE_OPERATION_H
|
||||
|
||||
|
||||
#include "main/compiler.h"
|
||||
#include "main/glheader.h"
|
||||
#include "slang_compile_variable.h"
|
||||
#include "slang_utility.h"
|
||||
|
||||
/**
|
||||
* Types of slang operations.
|
||||
* These are the types of the AST (abstract syntax tree) nodes.
|
||||
* [foo] indicates a sub-tree or reference to another type of node
|
||||
*/
|
||||
typedef enum slang_operation_type_
|
||||
{
|
||||
SLANG_OPER_NONE,
|
||||
SLANG_OPER_BLOCK_NO_NEW_SCOPE, /* "{" sequence "}" */
|
||||
SLANG_OPER_BLOCK_NEW_SCOPE, /* "{" sequence "}" */
|
||||
SLANG_OPER_VARIABLE_DECL, /* [type] [var] or [var] = [expr] */
|
||||
SLANG_OPER_ASM,
|
||||
SLANG_OPER_BREAK, /* "break" statement */
|
||||
SLANG_OPER_CONTINUE, /* "continue" statement */
|
||||
SLANG_OPER_DISCARD, /* "discard" (kill fragment) statement */
|
||||
SLANG_OPER_RETURN, /* "return" [expr] */
|
||||
SLANG_OPER_RETURN_INLINED, /* "return" [expr] from inlined function */
|
||||
SLANG_OPER_LABEL, /* a jump target */
|
||||
SLANG_OPER_EXPRESSION, /* [expr] */
|
||||
SLANG_OPER_IF, /* "if" [0] then [1] else [2] */
|
||||
SLANG_OPER_WHILE, /* "while" [cond] [body] */
|
||||
SLANG_OPER_DO, /* "do" [body] "while" [cond] */
|
||||
SLANG_OPER_FOR, /* "for" [init] [while] [incr] [body] */
|
||||
SLANG_OPER_VOID, /* nop */
|
||||
SLANG_OPER_LITERAL_BOOL, /* "true" or "false" */
|
||||
SLANG_OPER_LITERAL_INT, /* integer literal */
|
||||
SLANG_OPER_LITERAL_FLOAT, /* float literal */
|
||||
SLANG_OPER_IDENTIFIER, /* var name, func name, etc */
|
||||
SLANG_OPER_SEQUENCE, /* [expr] "," [expr] "," etc */
|
||||
SLANG_OPER_ASSIGN, /* [var] "=" [expr] */
|
||||
SLANG_OPER_ADDASSIGN, /* [var] "+=" [expr] */
|
||||
SLANG_OPER_SUBASSIGN, /* [var] "-=" [expr] */
|
||||
SLANG_OPER_MULASSIGN, /* [var] "*=" [expr] */
|
||||
SLANG_OPER_DIVASSIGN, /* [var] "/=" [expr] */
|
||||
/*SLANG_OPER_MODASSIGN, */
|
||||
/*SLANG_OPER_LSHASSIGN, */
|
||||
/*SLANG_OPER_RSHASSIGN, */
|
||||
/*SLANG_OPER_ORASSIGN, */
|
||||
/*SLANG_OPER_XORASSIGN, */
|
||||
/*SLANG_OPER_ANDASSIGN, */
|
||||
SLANG_OPER_SELECT, /* [expr] "?" [expr] ":" [expr] */
|
||||
SLANG_OPER_LOGICALOR, /* [expr] "||" [expr] */
|
||||
SLANG_OPER_LOGICALXOR, /* [expr] "^^" [expr] */
|
||||
SLANG_OPER_LOGICALAND, /* [expr] "&&" [expr] */
|
||||
/*SLANG_OPER_BITOR, */
|
||||
/*SLANG_OPER_BITXOR, */
|
||||
/*SLANG_OPER_BITAND, */
|
||||
SLANG_OPER_EQUAL, /* [expr] "==" [expr] */
|
||||
SLANG_OPER_NOTEQUAL, /* [expr] "!=" [expr] */
|
||||
SLANG_OPER_LESS, /* [expr] "<" [expr] */
|
||||
SLANG_OPER_GREATER, /* [expr] ">" [expr] */
|
||||
SLANG_OPER_LESSEQUAL, /* [expr] "<=" [expr] */
|
||||
SLANG_OPER_GREATEREQUAL, /* [expr] ">=" [expr] */
|
||||
/*SLANG_OPER_LSHIFT, */
|
||||
/*SLANG_OPER_RSHIFT, */
|
||||
SLANG_OPER_ADD, /* [expr] "+" [expr] */
|
||||
SLANG_OPER_SUBTRACT, /* [expr] "-" [expr] */
|
||||
SLANG_OPER_MULTIPLY, /* [expr] "*" [expr] */
|
||||
SLANG_OPER_DIVIDE, /* [expr] "/" [expr] */
|
||||
/*SLANG_OPER_MODULUS, */
|
||||
SLANG_OPER_PREINCREMENT, /* "++" [var] */
|
||||
SLANG_OPER_PREDECREMENT, /* "--" [var] */
|
||||
SLANG_OPER_PLUS, /* "-" [expr] */
|
||||
SLANG_OPER_MINUS, /* "+" [expr] */
|
||||
/*SLANG_OPER_COMPLEMENT, */
|
||||
SLANG_OPER_NOT, /* "!" [expr] */
|
||||
SLANG_OPER_SUBSCRIPT, /* [expr] "[" [expr] "]" */
|
||||
SLANG_OPER_CALL, /* [func name] [param] [param] [...] */
|
||||
SLANG_OPER_NON_INLINED_CALL, /* a real function call */
|
||||
SLANG_OPER_METHOD, /* method call, such as v.length() */
|
||||
SLANG_OPER_FIELD, /* i.e.: ".next" or ".xzy" or ".xxx" etc */
|
||||
SLANG_OPER_POSTINCREMENT, /* [var] "++" */
|
||||
SLANG_OPER_POSTDECREMENT /* [var] "--" */
|
||||
} slang_operation_type;
|
||||
|
||||
|
||||
/**
|
||||
* A slang_operation is basically a compiled instruction (such as assignment,
|
||||
* a while-loop, a conditional, a multiply, a function call, etc).
|
||||
* The AST (abstract syntax tree) is built from these nodes.
|
||||
* NOTE: This structure could have been implemented as a union of simpler
|
||||
* structs which would correspond to the operation types above.
|
||||
*/
|
||||
typedef struct slang_operation_
|
||||
{
|
||||
slang_operation_type type;
|
||||
struct slang_operation_ *children;
|
||||
GLuint num_children;
|
||||
GLfloat literal[4]; /**< Used for float, int and bool values */
|
||||
GLuint literal_size; /**< 1, 2, 3, or 4 */
|
||||
slang_atom a_id; /**< type: asm, identifier, call, field */
|
||||
slang_atom a_obj; /**< object in a method call */
|
||||
slang_variable_scope *locals; /**< local vars for scope */
|
||||
struct slang_function_ *fun; /**< If type == SLANG_OPER_CALL */
|
||||
struct slang_variable_ *var; /**< If type == slang_oper_identier */
|
||||
struct slang_label_ *label; /**< If type == SLANG_OPER_LABEL */
|
||||
/** If type==SLANG_OPER_CALL and we're calling an array constructor,
|
||||
* for which there's no real function, we need to have a flag to
|
||||
* indicate such. num_children indicates number of elements.
|
||||
*/
|
||||
GLboolean array_constructor;
|
||||
} slang_operation;
|
||||
|
||||
|
||||
extern GLboolean
|
||||
slang_operation_construct(slang_operation *);
|
||||
|
||||
extern void
|
||||
slang_operation_destruct(slang_operation *);
|
||||
|
||||
extern void
|
||||
slang_replace_scope(slang_operation *oper,
|
||||
slang_variable_scope *oldScope,
|
||||
slang_variable_scope *newScope);
|
||||
|
||||
extern GLboolean
|
||||
slang_operation_copy(slang_operation *, const slang_operation *);
|
||||
|
||||
extern slang_operation *
|
||||
slang_operation_new(GLuint count);
|
||||
|
||||
extern void
|
||||
slang_operation_delete(slang_operation *oper);
|
||||
|
||||
extern void
|
||||
slang_operation_free_children(slang_operation *oper);
|
||||
|
||||
extern slang_operation *
|
||||
slang_operation_grow(GLuint *numChildren, slang_operation **children);
|
||||
|
||||
extern slang_operation *
|
||||
slang_operation_insert(GLuint *numChildren, slang_operation **children,
|
||||
GLuint pos);
|
||||
|
||||
extern slang_operation *
|
||||
slang_operation_insert_child(slang_operation *oper, GLuint pos);
|
||||
|
||||
extern void
|
||||
_slang_operation_swap(slang_operation *oper0, slang_operation *oper1);
|
||||
|
||||
|
||||
extern void
|
||||
slang_operation_add_children(slang_operation *oper, GLuint num_children);
|
||||
|
||||
|
||||
/** Return number of children of given node */
|
||||
static INLINE GLuint
|
||||
slang_oper_num_children(const slang_operation *oper)
|
||||
{
|
||||
return oper->num_children;
|
||||
}
|
||||
|
||||
/** Return child of given operation node */
|
||||
static INLINE slang_operation *
|
||||
slang_oper_child(slang_operation *oper, GLuint child)
|
||||
{
|
||||
assert(child < oper->num_children);
|
||||
return &oper->children[child];
|
||||
}
|
||||
|
||||
|
||||
/** Return child of given operation node, const version */
|
||||
static INLINE const slang_operation *
|
||||
slang_oper_child_const(const slang_operation *oper, GLuint child)
|
||||
{
|
||||
assert(child < oper->num_children);
|
||||
return &oper->children[child];
|
||||
}
|
||||
|
||||
|
||||
/** Init oper to a boolean literal. */
|
||||
static INLINE void
|
||||
slang_operation_literal_bool(slang_operation *oper, GLboolean value)
|
||||
{
|
||||
oper->type = SLANG_OPER_LITERAL_BOOL;
|
||||
oper->literal[0] =
|
||||
oper->literal[1] =
|
||||
oper->literal[2] =
|
||||
oper->literal[3] = (float) value;
|
||||
oper->literal_size = 1;
|
||||
}
|
||||
|
||||
|
||||
/** Init oper to an int literal. */
|
||||
static INLINE void
|
||||
slang_operation_literal_int(slang_operation *oper, GLint value)
|
||||
{
|
||||
oper->type = SLANG_OPER_LITERAL_INT;
|
||||
oper->literal[0] =
|
||||
oper->literal[1] =
|
||||
oper->literal[2] =
|
||||
oper->literal[3] = (float) value;
|
||||
oper->literal_size = 1;
|
||||
}
|
||||
|
||||
|
||||
#endif /* SLANG_COMPILE_OPERATION_H */
|
|
@ -1,174 +0,0 @@
|
|||
/*
|
||||
* Mesa 3-D graphics library
|
||||
* Version: 6.5.3
|
||||
*
|
||||
* Copyright (C) 2005-2007 Brian Paul All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included
|
||||
* in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
|
||||
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
/**
|
||||
* \file slang_compile_struct.c
|
||||
* slang front-end compiler
|
||||
* \author Michal Krol
|
||||
*/
|
||||
|
||||
#include "main/imports.h"
|
||||
#include "slang_mem.h"
|
||||
#include "slang_compile.h"
|
||||
|
||||
|
||||
GLvoid
|
||||
_slang_struct_scope_ctr(slang_struct_scope * self)
|
||||
{
|
||||
self->structs = NULL;
|
||||
self->num_structs = 0;
|
||||
self->outer_scope = NULL;
|
||||
}
|
||||
|
||||
void
|
||||
slang_struct_scope_destruct(slang_struct_scope * scope)
|
||||
{
|
||||
GLuint i;
|
||||
|
||||
for (i = 0; i < scope->num_structs; i++)
|
||||
slang_struct_destruct(scope->structs + i);
|
||||
_slang_free(scope->structs);
|
||||
/* do not free scope->outer_scope */
|
||||
}
|
||||
|
||||
int
|
||||
slang_struct_scope_copy(slang_struct_scope * x, const slang_struct_scope * y)
|
||||
{
|
||||
slang_struct_scope z;
|
||||
GLuint i;
|
||||
|
||||
_slang_struct_scope_ctr(&z);
|
||||
z.structs = (slang_struct *)
|
||||
_slang_alloc(y->num_structs * sizeof(slang_struct));
|
||||
if (z.structs == NULL) {
|
||||
slang_struct_scope_destruct(&z);
|
||||
return 0;
|
||||
}
|
||||
for (z.num_structs = 0; z.num_structs < y->num_structs; z.num_structs++)
|
||||
if (!slang_struct_construct(&z.structs[z.num_structs])) {
|
||||
slang_struct_scope_destruct(&z);
|
||||
return 0;
|
||||
}
|
||||
for (i = 0; i < z.num_structs; i++)
|
||||
if (!slang_struct_copy(&z.structs[i], &y->structs[i])) {
|
||||
slang_struct_scope_destruct(&z);
|
||||
return 0;
|
||||
}
|
||||
z.outer_scope = y->outer_scope;
|
||||
slang_struct_scope_destruct(x);
|
||||
*x = z;
|
||||
return 1;
|
||||
}
|
||||
|
||||
slang_struct *
|
||||
slang_struct_scope_find(slang_struct_scope * stru, slang_atom a_name,
|
||||
int all_scopes)
|
||||
{
|
||||
GLuint i;
|
||||
|
||||
for (i = 0; i < stru->num_structs; i++)
|
||||
if (a_name == stru->structs[i].a_name)
|
||||
return &stru->structs[i];
|
||||
if (all_scopes && stru->outer_scope != NULL)
|
||||
return slang_struct_scope_find(stru->outer_scope, a_name, 1);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* slang_struct */
|
||||
|
||||
int
|
||||
slang_struct_construct(slang_struct * stru)
|
||||
{
|
||||
stru->a_name = SLANG_ATOM_NULL;
|
||||
stru->fields = (slang_variable_scope *)
|
||||
_slang_alloc(sizeof(slang_variable_scope));
|
||||
if (stru->fields == NULL)
|
||||
return 0;
|
||||
_slang_variable_scope_ctr(stru->fields);
|
||||
|
||||
stru->structs =
|
||||
(slang_struct_scope *) _slang_alloc(sizeof(slang_struct_scope));
|
||||
if (stru->structs == NULL) {
|
||||
slang_variable_scope_destruct(stru->fields);
|
||||
_slang_free(stru->fields);
|
||||
return 0;
|
||||
}
|
||||
_slang_struct_scope_ctr(stru->structs);
|
||||
stru->constructor = NULL;
|
||||
return 1;
|
||||
}
|
||||
|
||||
void
|
||||
slang_struct_destruct(slang_struct * stru)
|
||||
{
|
||||
slang_variable_scope_destruct(stru->fields);
|
||||
_slang_free(stru->fields);
|
||||
slang_struct_scope_destruct(stru->structs);
|
||||
_slang_free(stru->structs);
|
||||
}
|
||||
|
||||
int
|
||||
slang_struct_copy(slang_struct * x, const slang_struct * y)
|
||||
{
|
||||
slang_struct z;
|
||||
|
||||
if (!slang_struct_construct(&z))
|
||||
return 0;
|
||||
z.a_name = y->a_name;
|
||||
if (!slang_variable_scope_copy(z.fields, y->fields)) {
|
||||
slang_struct_destruct(&z);
|
||||
return 0;
|
||||
}
|
||||
if (!slang_struct_scope_copy(z.structs, y->structs)) {
|
||||
slang_struct_destruct(&z);
|
||||
return 0;
|
||||
}
|
||||
slang_struct_destruct(x);
|
||||
*x = z;
|
||||
return 1;
|
||||
}
|
||||
|
||||
int
|
||||
slang_struct_equal(const slang_struct * x, const slang_struct * y)
|
||||
{
|
||||
GLuint i;
|
||||
|
||||
if (x->fields->num_variables != y->fields->num_variables)
|
||||
return 0;
|
||||
|
||||
for (i = 0; i < x->fields->num_variables; i++) {
|
||||
const slang_variable *varx = x->fields->variables[i];
|
||||
const slang_variable *vary = y->fields->variables[i];
|
||||
|
||||
if (varx->a_name != vary->a_name)
|
||||
return 0;
|
||||
if (!slang_type_specifier_equal(&varx->type.specifier,
|
||||
&vary->type.specifier))
|
||||
return 0;
|
||||
if (varx->type.specifier.type == SLANG_SPEC_ARRAY)
|
||||
if (varx->array_len != vary->array_len)
|
||||
return GL_FALSE;
|
||||
}
|
||||
return 1;
|
||||
}
|
|
@ -1,69 +0,0 @@
|
|||
/*
|
||||
* Mesa 3-D graphics library
|
||||
* Version: 6.5
|
||||
*
|
||||
* Copyright (C) 2005-2006 Brian Paul All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included
|
||||
* in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
|
||||
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#if !defined SLANG_COMPILE_STRUCT_H
|
||||
#define SLANG_COMPILE_STRUCT_H
|
||||
|
||||
#if defined __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "main/glheader.h"
|
||||
#include "slang_utility.h"
|
||||
|
||||
struct slang_function_;
|
||||
|
||||
typedef struct slang_struct_scope_
|
||||
{
|
||||
struct slang_struct_ *structs;
|
||||
GLuint num_structs;
|
||||
struct slang_struct_scope_ *outer_scope;
|
||||
} slang_struct_scope;
|
||||
|
||||
extern GLvoid
|
||||
_slang_struct_scope_ctr (slang_struct_scope *);
|
||||
|
||||
void slang_struct_scope_destruct (slang_struct_scope *);
|
||||
int slang_struct_scope_copy (slang_struct_scope *, const slang_struct_scope *);
|
||||
struct slang_struct_ *slang_struct_scope_find (slang_struct_scope *, slang_atom, int);
|
||||
|
||||
typedef struct slang_struct_
|
||||
{
|
||||
slang_atom a_name;
|
||||
struct slang_variable_scope_ *fields;
|
||||
slang_struct_scope *structs;
|
||||
struct slang_function_ *constructor;
|
||||
} slang_struct;
|
||||
|
||||
int slang_struct_construct (slang_struct *);
|
||||
void slang_struct_destruct (slang_struct *);
|
||||
int slang_struct_copy (slang_struct *, const slang_struct *);
|
||||
int slang_struct_equal (const slang_struct *, const slang_struct *);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
@ -1,247 +0,0 @@
|
|||
/*
|
||||
* Mesa 3-D graphics library
|
||||
* Version: 6.5.3
|
||||
*
|
||||
* Copyright (C) 2005-2007 Brian Paul All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included
|
||||
* in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
|
||||
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
/**
|
||||
* \file slang_compile_variable.c
|
||||
* slang front-end compiler
|
||||
* \author Michal Krol
|
||||
*/
|
||||
|
||||
#include "main/imports.h"
|
||||
#include "slang_compile.h"
|
||||
#include "slang_mem.h"
|
||||
|
||||
|
||||
static slang_variable *
|
||||
slang_variable_new(void)
|
||||
{
|
||||
slang_variable *v = (slang_variable *) _slang_alloc(sizeof(slang_variable));
|
||||
if (v) {
|
||||
if (!slang_variable_construct(v)) {
|
||||
_slang_free(v);
|
||||
v = NULL;
|
||||
}
|
||||
}
|
||||
return v;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
slang_variable_delete(slang_variable * var)
|
||||
{
|
||||
slang_variable_destruct(var);
|
||||
_slang_free(var);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* slang_variable_scope
|
||||
*/
|
||||
|
||||
slang_variable_scope *
|
||||
_slang_variable_scope_new(slang_variable_scope *parent)
|
||||
{
|
||||
slang_variable_scope *s;
|
||||
s = (slang_variable_scope *) _slang_alloc(sizeof(slang_variable_scope));
|
||||
if (s)
|
||||
s->outer_scope = parent;
|
||||
return s;
|
||||
}
|
||||
|
||||
|
||||
GLvoid
|
||||
_slang_variable_scope_ctr(slang_variable_scope * self)
|
||||
{
|
||||
self->variables = NULL;
|
||||
self->num_variables = 0;
|
||||
self->outer_scope = NULL;
|
||||
}
|
||||
|
||||
void
|
||||
slang_variable_scope_destruct(slang_variable_scope * scope)
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
if (!scope)
|
||||
return;
|
||||
for (i = 0; i < scope->num_variables; i++) {
|
||||
if (scope->variables[i])
|
||||
slang_variable_delete(scope->variables[i]);
|
||||
}
|
||||
_slang_free(scope->variables);
|
||||
/* do not free scope->outer_scope */
|
||||
}
|
||||
|
||||
int
|
||||
slang_variable_scope_copy(slang_variable_scope * x,
|
||||
const slang_variable_scope * y)
|
||||
{
|
||||
slang_variable_scope z;
|
||||
unsigned int i;
|
||||
|
||||
_slang_variable_scope_ctr(&z);
|
||||
z.variables = (slang_variable **)
|
||||
_slang_alloc(y->num_variables * sizeof(slang_variable *));
|
||||
if (z.variables == NULL) {
|
||||
slang_variable_scope_destruct(&z);
|
||||
return 0;
|
||||
}
|
||||
for (z.num_variables = 0; z.num_variables < y->num_variables;
|
||||
z.num_variables++) {
|
||||
z.variables[z.num_variables] = slang_variable_new();
|
||||
if (!z.variables[z.num_variables]) {
|
||||
slang_variable_scope_destruct(&z);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
for (i = 0; i < z.num_variables; i++) {
|
||||
if (!slang_variable_copy(z.variables[i], y->variables[i])) {
|
||||
slang_variable_scope_destruct(&z);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
z.outer_scope = y->outer_scope;
|
||||
slang_variable_scope_destruct(x);
|
||||
*x = z;
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Grow the variable list by one.
|
||||
* \return pointer to space for the new variable (will be initialized)
|
||||
*/
|
||||
slang_variable *
|
||||
slang_variable_scope_grow(slang_variable_scope *scope)
|
||||
{
|
||||
const int n = scope->num_variables;
|
||||
scope->variables = (slang_variable **)
|
||||
_slang_realloc(scope->variables,
|
||||
n * sizeof(slang_variable *),
|
||||
(n + 1) * sizeof(slang_variable *));
|
||||
if (!scope->variables)
|
||||
return NULL;
|
||||
|
||||
scope->num_variables++;
|
||||
|
||||
scope->variables[n] = slang_variable_new();
|
||||
if (!scope->variables[n])
|
||||
return NULL;
|
||||
|
||||
return scope->variables[n];
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* slang_variable */
|
||||
|
||||
int
|
||||
slang_variable_construct(slang_variable * var)
|
||||
{
|
||||
if (!slang_fully_specified_type_construct(&var->type))
|
||||
return 0;
|
||||
var->a_name = SLANG_ATOM_NULL;
|
||||
var->array_len = 0;
|
||||
var->initializer = NULL;
|
||||
var->size = 0;
|
||||
var->isTemp = GL_FALSE;
|
||||
var->store = NULL;
|
||||
var->declared = 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
slang_variable_destruct(slang_variable * var)
|
||||
{
|
||||
slang_fully_specified_type_destruct(&var->type);
|
||||
if (var->initializer != NULL) {
|
||||
slang_operation_destruct(var->initializer);
|
||||
_slang_free(var->initializer);
|
||||
}
|
||||
#if 0
|
||||
if (var->aux) {
|
||||
free(var->aux);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
slang_variable_copy(slang_variable * x, const slang_variable * y)
|
||||
{
|
||||
slang_variable z;
|
||||
|
||||
if (!slang_variable_construct(&z))
|
||||
return 0;
|
||||
if (!slang_fully_specified_type_copy(&z.type, &y->type)) {
|
||||
slang_variable_destruct(&z);
|
||||
return 0;
|
||||
}
|
||||
z.a_name = y->a_name;
|
||||
z.array_len = y->array_len;
|
||||
if (y->initializer != NULL) {
|
||||
z.initializer
|
||||
= (slang_operation *) _slang_alloc(sizeof(slang_operation));
|
||||
if (z.initializer == NULL) {
|
||||
slang_variable_destruct(&z);
|
||||
return 0;
|
||||
}
|
||||
if (!slang_operation_construct(z.initializer)) {
|
||||
_slang_free(z.initializer);
|
||||
slang_variable_destruct(&z);
|
||||
return 0;
|
||||
}
|
||||
if (!slang_operation_copy(z.initializer, y->initializer)) {
|
||||
slang_variable_destruct(&z);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
z.size = y->size;
|
||||
slang_variable_destruct(x);
|
||||
*x = z;
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Search for named variable in given scope.
|
||||
* \param all if true, search parent scopes too.
|
||||
*/
|
||||
slang_variable *
|
||||
_slang_variable_locate(const slang_variable_scope * scope,
|
||||
const slang_atom a_name, GLboolean all)
|
||||
{
|
||||
while (scope) {
|
||||
GLuint i;
|
||||
for (i = 0; i < scope->num_variables; i++)
|
||||
if (a_name == scope->variables[i]->a_name)
|
||||
return scope->variables[i];
|
||||
if (all)
|
||||
scope = scope->outer_scope;
|
||||
else
|
||||
scope = NULL;
|
||||
}
|
||||
return NULL;
|
||||
}
|
|
@ -1,92 +0,0 @@
|
|||
/*
|
||||
* Mesa 3-D graphics library
|
||||
* Version: 6.5.2
|
||||
*
|
||||
* Copyright (C) 2005-2006 Brian Paul All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included
|
||||
* in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
|
||||
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef SLANG_COMPILE_VARIABLE_H
|
||||
#define SLANG_COMPILE_VARIABLE_H
|
||||
|
||||
|
||||
#include "main/glheader.h"
|
||||
#include "slang_typeinfo.h"
|
||||
#include "slang_utility.h"
|
||||
|
||||
|
||||
/**
|
||||
* A shading language program variable.
|
||||
*/
|
||||
typedef struct slang_variable_
|
||||
{
|
||||
slang_fully_specified_type type; /**< Variable's data type */
|
||||
slang_atom a_name; /**< The variable's name (char *) */
|
||||
GLuint array_len; /**< only if type == SLANG_SPEC_ARRAy */
|
||||
struct slang_operation_ *initializer; /**< Optional initializer code */
|
||||
GLuint size; /**< Variable's size in bytes */
|
||||
GLboolean is_global;
|
||||
GLboolean isTemp; /**< a named temporary (__resultTmp) */
|
||||
GLboolean declared; /**< has the var been declared? */
|
||||
struct slang_ir_storage_ *store; /**< Storage for this var */
|
||||
} slang_variable;
|
||||
|
||||
|
||||
/**
|
||||
* Basically a list of variables, with a pointer to the parent scope.
|
||||
*/
|
||||
typedef struct slang_variable_scope_
|
||||
{
|
||||
slang_variable **variables; /**< Array [num_variables] of ptrs to vars */
|
||||
GLuint num_variables;
|
||||
struct slang_variable_scope_ *outer_scope;
|
||||
} slang_variable_scope;
|
||||
|
||||
|
||||
extern slang_variable_scope *
|
||||
_slang_variable_scope_new(slang_variable_scope *parent);
|
||||
|
||||
extern GLvoid
|
||||
_slang_variable_scope_ctr(slang_variable_scope *);
|
||||
|
||||
extern void
|
||||
slang_variable_scope_destruct(slang_variable_scope *);
|
||||
|
||||
extern int
|
||||
slang_variable_scope_copy(slang_variable_scope *,
|
||||
const slang_variable_scope *);
|
||||
|
||||
extern slang_variable *
|
||||
slang_variable_scope_grow(slang_variable_scope *);
|
||||
|
||||
extern int
|
||||
slang_variable_construct(slang_variable *);
|
||||
|
||||
extern void
|
||||
slang_variable_destruct(slang_variable *);
|
||||
|
||||
extern int
|
||||
slang_variable_copy(slang_variable *, const slang_variable *);
|
||||
|
||||
extern slang_variable *
|
||||
_slang_variable_locate(const slang_variable_scope *, const slang_atom a_name,
|
||||
GLboolean all);
|
||||
|
||||
|
||||
#endif /* SLANG_COMPILE_VARIABLE_H */
|
File diff suppressed because it is too large
Load Diff
|
@ -1,49 +0,0 @@
|
|||
/*
|
||||
* Mesa 3-D graphics library
|
||||
* Version: 7.1
|
||||
*
|
||||
* Copyright (C) 2005-2008 Brian Paul All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included
|
||||
* in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
|
||||
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef SLANG_EMIT_H
|
||||
#define SLANG_EMIT_H
|
||||
|
||||
#include "main/glheader.h"
|
||||
#include "slang_ir.h"
|
||||
#include "slang_vartable.h"
|
||||
|
||||
|
||||
extern GLuint
|
||||
_slang_swizzle_swizzle(GLuint swz1, GLuint swz2);
|
||||
|
||||
|
||||
extern GLuint
|
||||
_slang_var_swizzle(GLint size, GLint comp);
|
||||
|
||||
|
||||
extern GLboolean
|
||||
_slang_emit_code(slang_ir_node *n, slang_var_table *vartable,
|
||||
struct gl_program *prog,
|
||||
const struct gl_sl_pragmas *pragmas,
|
||||
GLboolean withEnd,
|
||||
slang_info_log *log);
|
||||
|
||||
|
||||
#endif /* SLANG_EMIT_H */
|
|
@ -1,534 +0,0 @@
|
|||
/*
|
||||
* Mesa 3-D graphics library
|
||||
*
|
||||
* Copyright (C) 2005-2008 Brian Paul All Rights Reserved.
|
||||
* Copyright (C) 2009 VMware, Inc. All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included
|
||||
* in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
|
||||
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
|
||||
#include "main/imports.h"
|
||||
#include "main/context.h"
|
||||
#include "slang_ir.h"
|
||||
#include "slang_mem.h"
|
||||
#include "program/prog_instruction.h"
|
||||
#include "program/prog_print.h"
|
||||
|
||||
|
||||
static const slang_ir_info IrInfo[] = {
|
||||
/* binary ops */
|
||||
{ IR_ADD, "IR_ADD", OPCODE_ADD, 4, 2 },
|
||||
{ IR_SUB, "IR_SUB", OPCODE_SUB, 4, 2 },
|
||||
{ IR_MUL, "IR_MUL", OPCODE_MUL, 4, 2 },
|
||||
{ IR_DIV, "IR_DIV", OPCODE_NOP, 0, 2 }, /* XXX broke */
|
||||
{ IR_DOT4, "IR_DOT4", OPCODE_DP4, 1, 2 },
|
||||
{ IR_DOT3, "IR_DOT3", OPCODE_DP3, 1, 2 },
|
||||
{ IR_DOT2, "IR_DOT2", OPCODE_DP2, 1, 2 },
|
||||
{ IR_NRM4, "IR_NRM4", OPCODE_NRM4, 1, 1 },
|
||||
{ IR_NRM3, "IR_NRM3", OPCODE_NRM3, 1, 1 },
|
||||
{ IR_CROSS, "IR_CROSS", OPCODE_XPD, 3, 2 },
|
||||
{ IR_LRP, "IR_LRP", OPCODE_LRP, 4, 3 },
|
||||
{ IR_MIN, "IR_MIN", OPCODE_MIN, 4, 2 },
|
||||
{ IR_MAX, "IR_MAX", OPCODE_MAX, 4, 2 },
|
||||
{ IR_CLAMP, "IR_CLAMP", OPCODE_NOP, 4, 3 }, /* special case: emit_clamp() */
|
||||
{ IR_SEQUAL, "IR_SEQUAL", OPCODE_SEQ, 4, 2 },
|
||||
{ IR_SNEQUAL, "IR_SNEQUAL", OPCODE_SNE, 4, 2 },
|
||||
{ IR_SGE, "IR_SGE", OPCODE_SGE, 4, 2 },
|
||||
{ IR_SGT, "IR_SGT", OPCODE_SGT, 4, 2 },
|
||||
{ IR_SLE, "IR_SLE", OPCODE_SLE, 4, 2 },
|
||||
{ IR_SLT, "IR_SLT", OPCODE_SLT, 4, 2 },
|
||||
{ IR_POW, "IR_POW", OPCODE_POW, 1, 2 },
|
||||
{ IR_EQUAL, "IR_EQUAL", OPCODE_NOP, 1, 2 },
|
||||
{ IR_NOTEQUAL, "IR_NOTEQUAL", OPCODE_NOP, 1, 2 },
|
||||
|
||||
/* unary ops */
|
||||
{ IR_MOVE, "IR_MOVE", OPCODE_MOV, 4, 1 },
|
||||
{ IR_I_TO_F, "IR_I_TO_F", OPCODE_MOV, 4, 1 }, /* int[4] to float[4] */
|
||||
{ IR_F_TO_I, "IR_F_TO_I", OPCODE_TRUNC, 4, 1 },
|
||||
{ IR_EXP, "IR_EXP", OPCODE_EXP, 1, 1 },
|
||||
{ IR_EXP2, "IR_EXP2", OPCODE_EX2, 1, 1 },
|
||||
{ IR_LOG2, "IR_LOG2", OPCODE_LG2, 1, 1 },
|
||||
{ IR_RSQ, "IR_RSQ", OPCODE_RSQ, 1, 1 },
|
||||
{ IR_RCP, "IR_RCP", OPCODE_RCP, 1, 1 },
|
||||
{ IR_FLOOR, "IR_FLOOR", OPCODE_FLR, 4, 1 },
|
||||
{ IR_FRAC, "IR_FRAC", OPCODE_FRC, 4, 1 },
|
||||
{ IR_ABS, "IR_ABS", OPCODE_ABS, 4, 1 },
|
||||
{ IR_NEG, "IR_NEG", OPCODE_NOP, 4, 1 }, /* special case: emit_negation() */
|
||||
{ IR_DDX, "IR_DDX", OPCODE_DDX, 4, 1 },
|
||||
{ IR_DDY, "IR_DDY", OPCODE_DDY, 4, 1 },
|
||||
{ IR_SIN, "IR_SIN", OPCODE_SIN, 1, 1 },
|
||||
{ IR_COS, "IR_COS", OPCODE_COS, 1, 1 },
|
||||
{ IR_NOISE1, "IR_NOISE1", OPCODE_NOISE1, 1, 1 },
|
||||
{ IR_NOISE2, "IR_NOISE2", OPCODE_NOISE2, 1, 1 },
|
||||
{ IR_NOISE3, "IR_NOISE3", OPCODE_NOISE3, 1, 1 },
|
||||
{ IR_NOISE4, "IR_NOISE4", OPCODE_NOISE4, 1, 1 },
|
||||
|
||||
/* other */
|
||||
{ IR_CMP, "IR_CMP", OPCODE_CMP, 4, 3 }, /* compare/select */
|
||||
{ IR_SEQ, "IR_SEQ", OPCODE_NOP, 0, 0 },
|
||||
{ IR_SCOPE, "IR_SCOPE", OPCODE_NOP, 0, 0 },
|
||||
{ IR_LABEL, "IR_LABEL", OPCODE_NOP, 0, 0 },
|
||||
{ IR_IF, "IR_IF", OPCODE_NOP, 0, 0 },
|
||||
{ IR_KILL, "IR_KILL", OPCODE_NOP, 0, 0 },
|
||||
{ IR_COND, "IR_COND", OPCODE_NOP, 0, 0 },
|
||||
{ IR_CALL, "IR_CALL", OPCODE_NOP, 0, 0 },
|
||||
{ IR_COPY, "IR_COPY", OPCODE_NOP, 0, 1 },
|
||||
{ IR_NOT, "IR_NOT", OPCODE_NOP, 1, 1 },
|
||||
{ IR_VAR, "IR_VAR", OPCODE_NOP, 0, 0 },
|
||||
{ IR_VAR_DECL, "IR_VAR_DECL", OPCODE_NOP, 0, 0 },
|
||||
{ IR_TEX, "IR_TEX", OPCODE_TEX, 4, 1 },
|
||||
{ IR_TEXB, "IR_TEXB", OPCODE_TXB, 4, 1 },
|
||||
{ IR_TEXP, "IR_TEXP", OPCODE_TXP, 4, 1 },
|
||||
{ IR_TEX_SH, "IR_TEX_SH", OPCODE_TEX, 4, 1 },
|
||||
{ IR_TEXB_SH, "IR_TEXB_SH", OPCODE_TXB, 4, 1 },
|
||||
{ IR_TEXP_SH, "IR_TEXP_SH", OPCODE_TXP, 4, 1 },
|
||||
{ IR_FLOAT, "IR_FLOAT", OPCODE_NOP, 0, 0 }, /* float literal */
|
||||
{ IR_FIELD, "IR_FIELD", OPCODE_NOP, 0, 0 },
|
||||
{ IR_ELEMENT, "IR_ELEMENT", OPCODE_NOP, 0, 0 },
|
||||
{ IR_SWIZZLE, "IR_SWIZZLE", OPCODE_NOP, 0, 0 },
|
||||
{ IR_NOP, "IR_NOP", OPCODE_NOP, 0, 0 },
|
||||
{ IR_EMIT_VERTEX, "IR_EMIT_VERTEX", OPCODE_EMIT_VERTEX, 0, 0 },
|
||||
{ IR_END_PRIMITIVE, "IR_END_PRIMITIVE", OPCODE_END_PRIMITIVE, 0, 0 },
|
||||
{ 0, NULL, 0, 0, 0 }
|
||||
};
|
||||
|
||||
|
||||
const slang_ir_info *
|
||||
_slang_ir_info(slang_ir_opcode opcode)
|
||||
{
|
||||
GLuint i;
|
||||
for (i = 0; IrInfo[i].IrName; i++) {
|
||||
if (IrInfo[i].IrOpcode == opcode) {
|
||||
return IrInfo + i;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
_slang_init_ir_storage(slang_ir_storage *st,
|
||||
gl_register_file file, GLint index, GLint size,
|
||||
GLuint swizzle)
|
||||
{
|
||||
st->File = file;
|
||||
st->Index = index;
|
||||
st->Size = size;
|
||||
st->Swizzle = swizzle;
|
||||
st->Parent = NULL;
|
||||
st->IsIndirect = GL_FALSE;
|
||||
st->Is2D = GL_FALSE;
|
||||
st->Index2 = 0;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Return a new slang_ir_storage object.
|
||||
*/
|
||||
slang_ir_storage *
|
||||
_slang_new_ir_storage(gl_register_file file, GLint index, GLint size)
|
||||
{
|
||||
slang_ir_storage *st;
|
||||
st = (slang_ir_storage *) _slang_alloc(sizeof(slang_ir_storage));
|
||||
if (st) {
|
||||
st->File = file;
|
||||
st->Index = index;
|
||||
st->Size = size;
|
||||
st->Swizzle = SWIZZLE_NOOP;
|
||||
st->Parent = NULL;
|
||||
st->IsIndirect = GL_FALSE;
|
||||
st->Is2D = GL_FALSE;
|
||||
st->Index2 = 0;
|
||||
}
|
||||
return st;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Return a new slang_ir_storage object.
|
||||
*/
|
||||
slang_ir_storage *
|
||||
_slang_new_ir_storage_swz(gl_register_file file, GLint index, GLint size,
|
||||
GLuint swizzle)
|
||||
{
|
||||
slang_ir_storage *st;
|
||||
st = (slang_ir_storage *) _slang_alloc(sizeof(slang_ir_storage));
|
||||
if (st) {
|
||||
st->File = file;
|
||||
st->Index = index;
|
||||
st->Size = size;
|
||||
st->Swizzle = swizzle;
|
||||
st->Parent = NULL;
|
||||
st->IsIndirect = GL_FALSE;
|
||||
st->Is2D = GL_FALSE;
|
||||
st->Index2 = 0;
|
||||
}
|
||||
return st;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a new slang_ir_storage object.
|
||||
*/
|
||||
slang_ir_storage *
|
||||
_slang_new_ir_storage_2d(gl_register_file file,
|
||||
GLint index, GLint index2,
|
||||
GLint size, GLuint swizzle)
|
||||
{
|
||||
slang_ir_storage *st;
|
||||
st = (slang_ir_storage *) _slang_alloc(sizeof(slang_ir_storage));
|
||||
if (st) {
|
||||
st->File = file;
|
||||
st->Index = index;
|
||||
st->Size = size;
|
||||
st->Swizzle = swizzle;
|
||||
st->Parent = NULL;
|
||||
st->IsIndirect = GL_FALSE;
|
||||
st->Is2D = GL_TRUE;
|
||||
st->Index2 = index2;
|
||||
}
|
||||
return st;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Return a new slang_ir_storage object.
|
||||
*/
|
||||
slang_ir_storage *
|
||||
_slang_new_ir_storage_relative(GLint index, GLint size,
|
||||
slang_ir_storage *parent)
|
||||
{
|
||||
slang_ir_storage *st;
|
||||
st = (slang_ir_storage *) _slang_alloc(sizeof(slang_ir_storage));
|
||||
if (st) {
|
||||
st->File = PROGRAM_UNDEFINED;
|
||||
st->Index = index;
|
||||
st->Size = size;
|
||||
st->Swizzle = SWIZZLE_NOOP;
|
||||
st->Parent = parent;
|
||||
st->IsIndirect = GL_FALSE;
|
||||
st->Is2D = GL_FALSE;
|
||||
st->Index2 = 0;
|
||||
}
|
||||
return st;
|
||||
}
|
||||
|
||||
|
||||
slang_ir_storage *
|
||||
_slang_new_ir_storage_indirect(gl_register_file file,
|
||||
GLint index,
|
||||
GLint size,
|
||||
gl_register_file indirectFile,
|
||||
GLint indirectIndex,
|
||||
GLuint indirectSwizzle)
|
||||
{
|
||||
slang_ir_storage *st;
|
||||
st = (slang_ir_storage *) _slang_alloc(sizeof(slang_ir_storage));
|
||||
if (st) {
|
||||
st->File = file;
|
||||
st->Index = index;
|
||||
st->Size = size;
|
||||
st->Swizzle = SWIZZLE_NOOP;
|
||||
st->IsIndirect = GL_TRUE;
|
||||
st->IndirectFile = indirectFile;
|
||||
st->IndirectIndex = indirectIndex;
|
||||
st->IndirectSwizzle = indirectSwizzle;
|
||||
st->Is2D = GL_FALSE;
|
||||
st->Index2 = 0;
|
||||
}
|
||||
return st;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Allocate IR storage for a texture sampler.
|
||||
* \param sampNum the sampler number/index
|
||||
* \param texTarget one of TEXTURE_x_INDEX values
|
||||
* \param size number of samplers (in case of sampler array)
|
||||
*/
|
||||
slang_ir_storage *
|
||||
_slang_new_ir_storage_sampler(GLint sampNum, GLuint texTarget, GLint size)
|
||||
{
|
||||
slang_ir_storage *st;
|
||||
assert(texTarget < NUM_TEXTURE_TARGETS);
|
||||
st = _slang_new_ir_storage(PROGRAM_SAMPLER, sampNum, size);
|
||||
if (st) {
|
||||
st->TexTarget = texTarget;
|
||||
}
|
||||
return st;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* XXX temporary function */
|
||||
void
|
||||
_slang_copy_ir_storage(slang_ir_storage *dst, const slang_ir_storage *src)
|
||||
{
|
||||
*dst = *src;
|
||||
dst->Parent = NULL;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static const char *
|
||||
_slang_ir_name(slang_ir_opcode opcode)
|
||||
{
|
||||
return _slang_ir_info(opcode)->IrName;
|
||||
}
|
||||
|
||||
|
||||
|
||||
#if 0 /* no longer needed with mempool */
|
||||
/**
|
||||
* Since many IR nodes might point to the same IR storage info, we need
|
||||
* to be careful when deleting things.
|
||||
* Before deleting an IR tree, traverse it and do refcounting on the
|
||||
* IR storage nodes. Use the refcount info during delete to free things
|
||||
* properly.
|
||||
*/
|
||||
static void
|
||||
_slang_refcount_storage(slang_ir_node *n)
|
||||
{
|
||||
GLuint i;
|
||||
if (!n)
|
||||
return;
|
||||
if (n->Store)
|
||||
n->Store->RefCount++;
|
||||
for (i = 0; i < 3; i++)
|
||||
_slang_refcount_storage(n->Children[i]);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
static void
|
||||
_slang_free_ir(slang_ir_node *n)
|
||||
{
|
||||
GLuint i;
|
||||
if (!n)
|
||||
return;
|
||||
|
||||
#if 0
|
||||
if (n->Store) {
|
||||
n->Store->RefCount--;
|
||||
if (n->Store->RefCount == 0) {
|
||||
_slang_free(n->Store);
|
||||
n->Store = NULL;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
for (i = 0; i < 3; i++)
|
||||
_slang_free_ir(n->Children[i]);
|
||||
/* Do not free n->List since it's a child elsewhere */
|
||||
_slang_free(n);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Recursively free an IR tree.
|
||||
*/
|
||||
void
|
||||
_slang_free_ir_tree(slang_ir_node *n)
|
||||
{
|
||||
#if 0
|
||||
_slang_refcount_storage(n);
|
||||
#endif
|
||||
_slang_free_ir(n);
|
||||
}
|
||||
|
||||
|
||||
static const char *
|
||||
storage_string(const slang_ir_storage *st)
|
||||
{
|
||||
static const char *files[] = {
|
||||
"TEMP",
|
||||
"LOCAL_PARAM",
|
||||
"ENV_PARAM",
|
||||
"STATE",
|
||||
"INPUT",
|
||||
"OUTPUT",
|
||||
"NAMED_PARAM",
|
||||
"CONSTANT",
|
||||
"UNIFORM",
|
||||
"VARYING",
|
||||
"WRITE_ONLY",
|
||||
"ADDRESS",
|
||||
"SAMPLER",
|
||||
"UNDEFINED"
|
||||
};
|
||||
static char s[100];
|
||||
assert(Elements(files) == PROGRAM_FILE_MAX);
|
||||
#if 0
|
||||
if (st->Size == 1)
|
||||
_mesa_snprintf(s, "%s[%d]", files[st->File], st->Index);
|
||||
else
|
||||
_mesa_snprintf(s, "%s[%d..%d]", files[st->File], st->Index,
|
||||
st->Index + st->Size - 1);
|
||||
#endif
|
||||
assert(st->File < (GLint) (sizeof(files) / sizeof(files[0])));
|
||||
_mesa_snprintf(s, sizeof(s), "%s[%d]", files[st->File], st->Index);
|
||||
return s;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
spaces(int n)
|
||||
{
|
||||
while (n-- > 0) {
|
||||
printf(" ");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
_slang_print_ir_tree(const slang_ir_node *n, int indent)
|
||||
{
|
||||
#define IND 0
|
||||
|
||||
if (!n)
|
||||
return;
|
||||
#if !IND
|
||||
if (n->Opcode != IR_SEQ)
|
||||
#else
|
||||
printf("%3d:", indent);
|
||||
#endif
|
||||
spaces(indent);
|
||||
|
||||
switch (n->Opcode) {
|
||||
case IR_SEQ:
|
||||
#if IND
|
||||
printf("SEQ at %p\n", (void*) n);
|
||||
#endif
|
||||
assert(n->Children[0]);
|
||||
assert(n->Children[1]);
|
||||
_slang_print_ir_tree(n->Children[0], indent + IND);
|
||||
_slang_print_ir_tree(n->Children[1], indent + IND);
|
||||
break;
|
||||
case IR_SCOPE:
|
||||
printf("NEW SCOPE\n");
|
||||
assert(!n->Children[1]);
|
||||
_slang_print_ir_tree(n->Children[0], indent + 3);
|
||||
break;
|
||||
case IR_COPY:
|
||||
printf("COPY\n");
|
||||
_slang_print_ir_tree(n->Children[0], indent+3);
|
||||
_slang_print_ir_tree(n->Children[1], indent+3);
|
||||
break;
|
||||
case IR_LABEL:
|
||||
printf("LABEL: %s\n", n->Label->Name);
|
||||
break;
|
||||
case IR_COND:
|
||||
printf("COND\n");
|
||||
_slang_print_ir_tree(n->Children[0], indent + 3);
|
||||
break;
|
||||
|
||||
case IR_IF:
|
||||
printf("IF \n");
|
||||
_slang_print_ir_tree(n->Children[0], indent+3);
|
||||
spaces(indent);
|
||||
printf("THEN\n");
|
||||
_slang_print_ir_tree(n->Children[1], indent+3);
|
||||
if (n->Children[2]) {
|
||||
spaces(indent);
|
||||
printf("ELSE\n");
|
||||
_slang_print_ir_tree(n->Children[2], indent+3);
|
||||
}
|
||||
spaces(indent);
|
||||
printf("ENDIF\n");
|
||||
break;
|
||||
|
||||
case IR_BEGIN_SUB:
|
||||
printf("BEGIN_SUB\n");
|
||||
break;
|
||||
case IR_END_SUB:
|
||||
printf("END_SUB\n");
|
||||
break;
|
||||
case IR_RETURN:
|
||||
printf("RETURN\n");
|
||||
break;
|
||||
case IR_CALL:
|
||||
printf("CALL %s\n", n->Label->Name);
|
||||
break;
|
||||
|
||||
case IR_LOOP:
|
||||
printf("LOOP\n");
|
||||
_slang_print_ir_tree(n->Children[0], indent+3);
|
||||
if (n->Children[1]) {
|
||||
spaces(indent);
|
||||
printf("TAIL:\n");
|
||||
_slang_print_ir_tree(n->Children[1], indent+3);
|
||||
}
|
||||
spaces(indent);
|
||||
printf("ENDLOOP\n");
|
||||
break;
|
||||
case IR_CONT:
|
||||
printf("CONT\n");
|
||||
break;
|
||||
case IR_BREAK:
|
||||
printf("BREAK\n");
|
||||
break;
|
||||
case IR_BREAK_IF_TRUE:
|
||||
printf("BREAK_IF_TRUE\n");
|
||||
_slang_print_ir_tree(n->Children[0], indent+3);
|
||||
break;
|
||||
case IR_CONT_IF_TRUE:
|
||||
printf("CONT_IF_TRUE\n");
|
||||
_slang_print_ir_tree(n->Children[0], indent+3);
|
||||
break;
|
||||
|
||||
case IR_VAR:
|
||||
printf("VAR %s%s at %s store %p\n",
|
||||
(n->Var ? (char *) n->Var->a_name : "TEMP"),
|
||||
_mesa_swizzle_string(n->Store->Swizzle, 0, 0),
|
||||
storage_string(n->Store), (void*) n->Store);
|
||||
break;
|
||||
case IR_VAR_DECL:
|
||||
printf("VAR_DECL %s (%p) at %s store %p\n",
|
||||
(n->Var ? (char *) n->Var->a_name : "TEMP"),
|
||||
(void*) n->Var, storage_string(n->Store),
|
||||
(void*) n->Store);
|
||||
break;
|
||||
case IR_FIELD:
|
||||
printf("FIELD %s of\n", n->Field);
|
||||
_slang_print_ir_tree(n->Children[0], indent+3);
|
||||
break;
|
||||
case IR_FLOAT:
|
||||
printf("FLOAT %g %g %g %g\n",
|
||||
n->Value[0], n->Value[1], n->Value[2], n->Value[3]);
|
||||
break;
|
||||
case IR_I_TO_F:
|
||||
printf("INT_TO_FLOAT\n");
|
||||
_slang_print_ir_tree(n->Children[0], indent+3);
|
||||
break;
|
||||
case IR_F_TO_I:
|
||||
printf("FLOAT_TO_INT\n");
|
||||
_slang_print_ir_tree(n->Children[0], indent+3);
|
||||
break;
|
||||
case IR_SWIZZLE:
|
||||
printf("SWIZZLE %s of (store %p) \n",
|
||||
_mesa_swizzle_string(n->Store->Swizzle, 0, 0), (void*) n->Store);
|
||||
_slang_print_ir_tree(n->Children[0], indent + 3);
|
||||
break;
|
||||
default:
|
||||
printf("%s (%p, %p) (store %p)\n", _slang_ir_name(n->Opcode),
|
||||
(void*) n->Children[0], (void*) n->Children[1], (void*) n->Store);
|
||||
_slang_print_ir_tree(n->Children[0], indent+3);
|
||||
_slang_print_ir_tree(n->Children[1], indent+3);
|
||||
}
|
||||
}
|
|
@ -1,293 +0,0 @@
|
|||
/*
|
||||
* Mesa 3-D graphics library
|
||||
*
|
||||
* Copyright (C) 2005-2008 Brian Paul All Rights Reserved.
|
||||
* Copyright (C) 2009 VMware, Inc. All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included
|
||||
* in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
|
||||
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
/**
|
||||
* \file slang_ir.h
|
||||
* Mesa GLSL Intermediate Representation tree types and constants.
|
||||
* \author Brian Paul
|
||||
*/
|
||||
|
||||
|
||||
#ifndef SLANG_IR_H
|
||||
#define SLANG_IR_H
|
||||
|
||||
|
||||
#include "main/glheader.h"
|
||||
#include "main/mtypes.h"
|
||||
#include "program/prog_instruction.h"
|
||||
#include "slang_compile_variable.h"
|
||||
#include "slang_label.h"
|
||||
|
||||
|
||||
/**
|
||||
* Intermediate Representation opcodes
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
IR_NOP = 0,
|
||||
IR_SEQ, /* sequence (eval left, then right) */
|
||||
IR_SCOPE, /* new variable scope (one child) */
|
||||
|
||||
IR_LABEL, /* target of a jump or cjump */
|
||||
|
||||
IR_COND, /* conditional expression/predicate */
|
||||
|
||||
IR_IF, /* high-level IF/then/else */
|
||||
/* Children[0] = conditional expression */
|
||||
/* Children[1] = if-true part */
|
||||
/* Children[2] = if-else part, or NULL */
|
||||
|
||||
IR_BEGIN_SUB, /* begin subroutine */
|
||||
IR_END_SUB, /* end subroutine */
|
||||
IR_RETURN, /* return from subroutine */
|
||||
IR_CALL, /* call subroutine */
|
||||
|
||||
IR_LOOP, /* high-level loop-begin / loop-end */
|
||||
/* Children[0] = loop body */
|
||||
/* Children[1] = loop tail code, or NULL */
|
||||
|
||||
IR_CONT, /* continue loop */
|
||||
/* n->Parent = ptr to parent IR_LOOP Node */
|
||||
IR_BREAK, /* break loop */
|
||||
|
||||
IR_BREAK_IF_TRUE, /**< Children[0] = the condition expression */
|
||||
IR_CONT_IF_TRUE,
|
||||
|
||||
IR_COPY, /**< assignment/copy */
|
||||
IR_MOVE, /**< assembly MOV instruction */
|
||||
|
||||
/* vector ops: */
|
||||
IR_ADD, /**< assembly ADD instruction */
|
||||
IR_SUB,
|
||||
IR_MUL,
|
||||
IR_DIV,
|
||||
IR_DOT4,
|
||||
IR_DOT3,
|
||||
IR_DOT2,
|
||||
IR_NRM4,
|
||||
IR_NRM3,
|
||||
IR_CROSS, /* vec3 cross product */
|
||||
IR_LRP,
|
||||
IR_CLAMP,
|
||||
IR_MIN,
|
||||
IR_MAX,
|
||||
IR_CMP, /* = (op0 < 0) ? op1 : op2 */
|
||||
IR_SEQUAL, /* Set if args are equal (vector) */
|
||||
IR_SNEQUAL, /* Set if args are not equal (vector) */
|
||||
IR_SGE, /* Set if greater or equal (vector) */
|
||||
IR_SGT, /* Set if greater than (vector) */
|
||||
IR_SLE, /* Set if less or equal (vector) */
|
||||
IR_SLT, /* Set if less than (vector) */
|
||||
IR_POW, /* x^y */
|
||||
IR_EXP, /* e^x */
|
||||
IR_EXP2, /* 2^x */
|
||||
IR_LOG2, /* log base 2 */
|
||||
IR_RSQ, /* 1/sqrt() */
|
||||
IR_RCP, /* reciprocol */
|
||||
IR_FLOOR,
|
||||
IR_FRAC,
|
||||
IR_ABS, /* absolute value */
|
||||
IR_NEG, /* negate */
|
||||
IR_DDX, /* derivative w.r.t. X */
|
||||
IR_DDY, /* derivative w.r.t. Y */
|
||||
IR_SIN, /* sine */
|
||||
IR_COS, /* cosine */
|
||||
IR_NOISE1, /* noise(x) */
|
||||
IR_NOISE2, /* noise(x, y) */
|
||||
IR_NOISE3, /* noise(x, y, z) */
|
||||
IR_NOISE4, /* noise(x, y, z, w) */
|
||||
|
||||
IR_EQUAL, /* boolean equality */
|
||||
IR_NOTEQUAL,/* boolean inequality */
|
||||
IR_NOT, /* boolean not */
|
||||
|
||||
IR_VAR, /* variable reference */
|
||||
IR_VAR_DECL,/* var declaration */
|
||||
|
||||
IR_ELEMENT, /* array element */
|
||||
IR_FIELD, /* struct field */
|
||||
IR_SWIZZLE, /* swizzled storage access */
|
||||
|
||||
IR_TEX, /* texture lookup */
|
||||
IR_TEXB, /* texture lookup with LOD bias */
|
||||
IR_TEXP, /* texture lookup with projection */
|
||||
|
||||
IR_TEX_SH, /* texture lookup, shadow compare */
|
||||
IR_TEXB_SH, /* texture lookup with LOD bias, shadow compare */
|
||||
IR_TEXP_SH, /* texture lookup with projection, shadow compare */
|
||||
|
||||
IR_FLOAT,
|
||||
IR_I_TO_F, /* int[4] to float[4] conversion */
|
||||
IR_F_TO_I, /* float[4] to int[4] conversion */
|
||||
|
||||
IR_KILL, /* fragment kill/discard */
|
||||
|
||||
IR_EMIT_VERTEX, /* geometry shader: emit vertex */
|
||||
IR_END_PRIMITIVE /* geometry shader: end primitive */
|
||||
} slang_ir_opcode;
|
||||
|
||||
|
||||
/**
|
||||
* Describes where data/variables are stored in the various register files.
|
||||
*
|
||||
* In the simple case, the File, Index and Size fields indicate where
|
||||
* a variable is stored. For example, a vec3 variable may be stored
|
||||
* as (File=PROGRAM_TEMPORARY, Index=6, Size=3). Or, File[Index].
|
||||
* Or, a program input like color may be stored as
|
||||
* (File=PROGRAM_INPUT,Index=3,Size=4);
|
||||
*
|
||||
* For single-float values, the Swizzle field indicates which component
|
||||
* of the vector contains the float.
|
||||
*
|
||||
* If IsIndirect is set, the storage is accessed through an indirect
|
||||
* register lookup. The value in question will be located at:
|
||||
* File[Index + IndirectFile[IndirectIndex]]
|
||||
*
|
||||
* This is primary used for indexing arrays. For example, consider this
|
||||
* GLSL code:
|
||||
* uniform int i;
|
||||
* float a[10];
|
||||
* float x = a[i];
|
||||
*
|
||||
* here, storage for a[i] would be described by (File=PROGRAM_TEMPORAY,
|
||||
* Index=aPos, IndirectFile=PROGRAM_UNIFORM, IndirectIndex=iPos), which
|
||||
* would mean TEMP[aPos + UNIFORM[iPos]]
|
||||
*/
|
||||
struct slang_ir_storage_
|
||||
{
|
||||
gl_register_file File; /**< PROGRAM_TEMPORARY, PROGRAM_INPUT, etc */
|
||||
GLint Index; /**< -1 means unallocated */
|
||||
GLint Size; /**< number of floats or ints */
|
||||
GLuint Swizzle; /**< Swizzle AND writemask info */
|
||||
GLint RefCount; /**< Used during IR tree delete */
|
||||
|
||||
GLboolean RelAddr; /* we'll remove this eventually */
|
||||
|
||||
GLboolean IsIndirect;
|
||||
gl_register_file IndirectFile;
|
||||
GLint IndirectIndex;
|
||||
GLuint IndirectSwizzle;
|
||||
GLuint TexTarget; /**< If File==PROGRAM_SAMPLER, one of TEXTURE_x_INDEX */
|
||||
|
||||
/* Is the register two-dimensional and
|
||||
* if so what's the second index */
|
||||
GLboolean Is2D;
|
||||
GLint Index2;
|
||||
|
||||
/** If Parent is non-null, Index is relative to parent.
|
||||
* The other fields are ignored.
|
||||
*/
|
||||
struct slang_ir_storage_ *Parent;
|
||||
};
|
||||
|
||||
typedef struct slang_ir_storage_ slang_ir_storage;
|
||||
|
||||
|
||||
/**
|
||||
* Intermediate Representation (IR) tree node
|
||||
* Basically a binary tree, but IR_LRP and IR_CLAMP have three children.
|
||||
*/
|
||||
typedef struct slang_ir_node_
|
||||
{
|
||||
slang_ir_opcode Opcode;
|
||||
struct slang_ir_node_ *Children[3];
|
||||
slang_ir_storage *Store; /**< location of result of this operation */
|
||||
GLint InstLocation; /**< Location of instruction emitted for this node */
|
||||
|
||||
/** special fields depending on Opcode: */
|
||||
const char *Field; /**< If Opcode == IR_FIELD */
|
||||
GLfloat Value[4]; /**< If Opcode == IR_FLOAT */
|
||||
slang_variable *Var; /**< If Opcode == IR_VAR or IR_VAR_DECL */
|
||||
struct slang_ir_node_ *List; /**< For various linked lists */
|
||||
struct slang_ir_node_ *Parent; /**< Pointer to logical parent (ie. loop) */
|
||||
slang_label *Label; /**< Used for branches */
|
||||
const char *Comment; /**< If Opcode == IR_COMMENT */
|
||||
} slang_ir_node;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Assembly and IR info
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
slang_ir_opcode IrOpcode;
|
||||
const char *IrName;
|
||||
gl_inst_opcode InstOpcode;
|
||||
GLuint ResultSize, NumParams;
|
||||
} slang_ir_info;
|
||||
|
||||
|
||||
|
||||
extern const slang_ir_info *
|
||||
_slang_ir_info(slang_ir_opcode opcode);
|
||||
|
||||
|
||||
extern void
|
||||
_slang_init_ir_storage(slang_ir_storage *st,
|
||||
gl_register_file file, GLint index, GLint size,
|
||||
GLuint swizzle);
|
||||
|
||||
extern slang_ir_storage *
|
||||
_slang_new_ir_storage(gl_register_file file, GLint index, GLint size);
|
||||
|
||||
|
||||
extern slang_ir_storage *
|
||||
_slang_new_ir_storage_swz(gl_register_file file, GLint index, GLint size,
|
||||
GLuint swizzle);
|
||||
|
||||
extern slang_ir_storage *
|
||||
_slang_new_ir_storage_2d(gl_register_file file, GLint index, GLint index2d,
|
||||
GLint size, GLuint swizzle);
|
||||
|
||||
extern slang_ir_storage *
|
||||
_slang_new_ir_storage_relative(GLint index, GLint size,
|
||||
slang_ir_storage *parent);
|
||||
|
||||
|
||||
extern slang_ir_storage *
|
||||
_slang_new_ir_storage_indirect(gl_register_file file,
|
||||
GLint index,
|
||||
GLint size,
|
||||
gl_register_file indirectFile,
|
||||
GLint indirectIndex,
|
||||
GLuint indirectSwizzle);
|
||||
|
||||
extern slang_ir_storage *
|
||||
_slang_new_ir_storage_sampler(GLint sampNum, GLuint texTarget, GLint size);
|
||||
|
||||
|
||||
extern void
|
||||
_slang_copy_ir_storage(slang_ir_storage *dst, const slang_ir_storage *src);
|
||||
|
||||
|
||||
extern void
|
||||
_slang_free_ir_tree(slang_ir_node *n);
|
||||
|
||||
|
||||
extern void
|
||||
_slang_print_ir_tree(const slang_ir_node *n, int indent);
|
||||
|
||||
|
||||
#endif /* SLANG_IR_H */
|
|
@ -1,107 +0,0 @@
|
|||
|
||||
|
||||
/**
|
||||
* Functions for managing instruction labels.
|
||||
* Basically, this is used to manage the problem of forward branches where
|
||||
* we have a branch instruciton but don't know the target address yet.
|
||||
*/
|
||||
|
||||
|
||||
#include "main/imports.h"
|
||||
#include "main/mtypes.h"
|
||||
#include "program/prog_instruction.h"
|
||||
#include "slang_label.h"
|
||||
#include "slang_mem.h"
|
||||
|
||||
|
||||
|
||||
slang_label *
|
||||
_slang_label_new(const char *name)
|
||||
{
|
||||
slang_label *l = (slang_label *) _slang_alloc(sizeof(slang_label));
|
||||
if (l) {
|
||||
l->Name = _slang_strdup(name);
|
||||
l->Location = -1;
|
||||
}
|
||||
return l;
|
||||
}
|
||||
|
||||
/**
|
||||
* As above, but suffix the name with a unique number.
|
||||
*/
|
||||
slang_label *
|
||||
_slang_label_new_unique(const char *name)
|
||||
{
|
||||
static int id = 1;
|
||||
slang_label *l = (slang_label *) _slang_alloc(sizeof(slang_label));
|
||||
if (l) {
|
||||
l->Name = (char *) _slang_alloc(strlen(name) + 10);
|
||||
if (!l->Name) {
|
||||
free(l);
|
||||
return NULL;
|
||||
}
|
||||
_mesa_snprintf(l->Name, strlen(name) + 10, "%s_%d", name, id);
|
||||
id++;
|
||||
l->Location = -1;
|
||||
}
|
||||
return l;
|
||||
}
|
||||
|
||||
void
|
||||
_slang_label_delete(slang_label *l)
|
||||
{
|
||||
if (l->Name) {
|
||||
_slang_free(l->Name);
|
||||
l->Name = NULL;
|
||||
}
|
||||
if (l->References) {
|
||||
_slang_free(l->References);
|
||||
l->References = NULL;
|
||||
}
|
||||
_slang_free(l);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
_slang_label_add_reference(slang_label *l, GLuint inst)
|
||||
{
|
||||
const GLuint oldSize = l->NumReferences * sizeof(GLuint);
|
||||
assert(l->Location < 0);
|
||||
l->References = _slang_realloc(l->References,
|
||||
oldSize, oldSize + sizeof(GLuint));
|
||||
if (l->References) {
|
||||
l->References[l->NumReferences] = inst;
|
||||
l->NumReferences++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
GLint
|
||||
_slang_label_get_location(const slang_label *l)
|
||||
{
|
||||
return l->Location;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
_slang_label_set_location(slang_label *l, GLint location,
|
||||
struct gl_program *prog)
|
||||
{
|
||||
GLuint i;
|
||||
|
||||
assert(l->Location < 0);
|
||||
assert(location >= 0);
|
||||
|
||||
l->Location = location;
|
||||
|
||||
/* for the instructions that were waiting to learn the label's location: */
|
||||
for (i = 0; i < l->NumReferences; i++) {
|
||||
const GLuint j = l->References[i];
|
||||
prog->Instructions[j].BranchTarget = location;
|
||||
}
|
||||
|
||||
if (l->References) {
|
||||
_slang_free(l->References);
|
||||
l->References = NULL;
|
||||
}
|
||||
}
|
|
@ -1,44 +0,0 @@
|
|||
#ifndef SLANG_LABEL_H
|
||||
#define SLANG_LABEL_H 1
|
||||
|
||||
#include "main/glheader.h"
|
||||
|
||||
struct gl_program;
|
||||
|
||||
struct slang_label_
|
||||
{
|
||||
char *Name;
|
||||
GLint Location;
|
||||
/**
|
||||
* List of instruction references (numbered starting at zero) which need
|
||||
* their BranchTarget field filled in with the location eventually
|
||||
* assigned to the label.
|
||||
*/
|
||||
GLuint NumReferences;
|
||||
GLuint *References; /** Array [NumReferences] */
|
||||
};
|
||||
|
||||
typedef struct slang_label_ slang_label;
|
||||
|
||||
|
||||
extern slang_label *
|
||||
_slang_label_new(const char *name);
|
||||
|
||||
extern slang_label *
|
||||
_slang_label_new_unique(const char *name);
|
||||
|
||||
extern void
|
||||
_slang_label_delete(slang_label *l);
|
||||
|
||||
extern void
|
||||
_slang_label_add_reference(slang_label *l, GLuint inst);
|
||||
|
||||
extern GLint
|
||||
_slang_label_get_location(const slang_label *l);
|
||||
|
||||
extern void
|
||||
_slang_label_set_location(slang_label *l, GLint location,
|
||||
struct gl_program *prog);
|
||||
|
||||
|
||||
#endif /* SLANG_LABEL_H */
|
File diff suppressed because it is too large
Load Diff
|
@ -1,37 +0,0 @@
|
|||
/*
|
||||
* Mesa 3-D graphics library
|
||||
* Version: 7.2
|
||||
*
|
||||
* Copyright (C) 2008 Brian Paul All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included
|
||||
* in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
|
||||
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef SLANG_LINK_H
|
||||
#define SLANG_LINK_H 1
|
||||
|
||||
#include "main/mtypes.h"
|
||||
|
||||
|
||||
extern void
|
||||
_slang_link(GLcontext *ctx, GLhandleARB h,
|
||||
struct gl_shader_program *shProg);
|
||||
|
||||
|
||||
#endif
|
||||
|
|
@ -1,133 +0,0 @@
|
|||
/*
|
||||
* Mesa 3-D graphics library
|
||||
* Version: 7.3
|
||||
*
|
||||
* Copyright (C) 2005-2007 Brian Paul All Rights Reserved.
|
||||
* Copyright (C) 2009 VMware, Inc. All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included
|
||||
* in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
|
||||
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "main/imports.h"
|
||||
#include "slang_log.h"
|
||||
#include "slang_utility.h"
|
||||
|
||||
|
||||
|
||||
static char *out_of_memory = "Error: Out of memory.\n";
|
||||
|
||||
void
|
||||
slang_info_log_construct(slang_info_log * log)
|
||||
{
|
||||
log->text = NULL;
|
||||
log->dont_free_text = GL_FALSE;
|
||||
log->error_flag = GL_FALSE;
|
||||
}
|
||||
|
||||
void
|
||||
slang_info_log_destruct(slang_info_log * log)
|
||||
{
|
||||
if (!log->dont_free_text)
|
||||
free(log->text);
|
||||
}
|
||||
|
||||
static int
|
||||
slang_info_log_message(slang_info_log * log, const char *prefix,
|
||||
const char *msg)
|
||||
{
|
||||
GLuint size;
|
||||
|
||||
if (log->dont_free_text)
|
||||
return 0;
|
||||
size = slang_string_length(msg) + 2;
|
||||
if (prefix != NULL)
|
||||
size += slang_string_length(prefix) + 2;
|
||||
if (log->text != NULL) {
|
||||
GLuint old_len = slang_string_length(log->text);
|
||||
log->text = (char *)
|
||||
_mesa_realloc(log->text, old_len + 1, old_len + size);
|
||||
}
|
||||
else {
|
||||
log->text = (char *) (malloc(size));
|
||||
if (log->text != NULL)
|
||||
log->text[0] = '\0';
|
||||
}
|
||||
if (log->text == NULL)
|
||||
return 0;
|
||||
if (prefix != NULL) {
|
||||
slang_string_concat(log->text, prefix);
|
||||
slang_string_concat(log->text, ": ");
|
||||
}
|
||||
slang_string_concat(log->text, msg);
|
||||
slang_string_concat(log->text, "\n");
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int
|
||||
slang_info_log_print(slang_info_log * log, const char *msg, ...)
|
||||
{
|
||||
va_list va;
|
||||
char buf[1024];
|
||||
|
||||
va_start(va, msg);
|
||||
vsprintf(buf, msg, va);
|
||||
va_end(va);
|
||||
return slang_info_log_message(log, NULL, buf);
|
||||
}
|
||||
|
||||
int
|
||||
slang_info_log_error(slang_info_log * log, const char *msg, ...)
|
||||
{
|
||||
va_list va;
|
||||
char buf[1024];
|
||||
|
||||
va_start(va, msg);
|
||||
vsprintf(buf, msg, va);
|
||||
va_end(va);
|
||||
log->error_flag = GL_TRUE;
|
||||
if (slang_info_log_message(log, "Error", buf))
|
||||
return 1;
|
||||
slang_info_log_memory(log);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
slang_info_log_warning(slang_info_log * log, const char *msg, ...)
|
||||
{
|
||||
va_list va;
|
||||
char buf[1024];
|
||||
|
||||
va_start(va, msg);
|
||||
vsprintf(buf, msg, va);
|
||||
va_end(va);
|
||||
if (slang_info_log_message(log, "Warning", buf))
|
||||
return 1;
|
||||
slang_info_log_memory(log);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
slang_info_log_memory(slang_info_log * log)
|
||||
{
|
||||
if (!slang_info_log_message(log, "Error", "Out of memory.")) {
|
||||
log->dont_free_text = GL_TRUE;
|
||||
log->error_flag = GL_TRUE;
|
||||
log->text = out_of_memory;
|
||||
}
|
||||
}
|
|
@ -1,59 +0,0 @@
|
|||
/*
|
||||
* Mesa 3-D graphics library
|
||||
* Version: 6.5.3
|
||||
*
|
||||
* Copyright (C) 2005-2007 Brian Paul All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included
|
||||
* in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
|
||||
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
|
||||
#ifndef SLANG_LOG_H
|
||||
#define SLANG_LOG_H
|
||||
|
||||
|
||||
#include "main/glheader.h"
|
||||
|
||||
typedef struct slang_info_log_
|
||||
{
|
||||
char *text;
|
||||
GLboolean dont_free_text;
|
||||
GLboolean error_flag;
|
||||
} slang_info_log;
|
||||
|
||||
|
||||
extern void
|
||||
slang_info_log_construct(slang_info_log *);
|
||||
|
||||
extern void
|
||||
slang_info_log_destruct(slang_info_log *);
|
||||
|
||||
extern int
|
||||
slang_info_log_print(slang_info_log *, const char *, ...);
|
||||
|
||||
extern int
|
||||
slang_info_log_error(slang_info_log *, const char *, ...);
|
||||
|
||||
extern int
|
||||
slang_info_log_warning(slang_info_log *, const char *, ...);
|
||||
|
||||
extern void
|
||||
slang_info_log_memory(slang_info_log *);
|
||||
|
||||
|
||||
#endif /* SLANG_LOG_H */
|
|
@ -1,243 +0,0 @@
|
|||
/*
|
||||
* Mesa 3-D graphics library
|
||||
* Version: 6.5.3
|
||||
*
|
||||
* Copyright (C) 2005-2007 Brian Paul All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included
|
||||
* in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
|
||||
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
/**
|
||||
* \file slang_mem.c
|
||||
*
|
||||
* Memory manager for GLSL compiler. The general idea is to do all
|
||||
* allocations out of a large pool then just free the pool when done
|
||||
* compiling to avoid intricate malloc/free tracking and memory leaks.
|
||||
*
|
||||
* \author Brian Paul
|
||||
*/
|
||||
|
||||
#include "main/context.h"
|
||||
#include "main/macros.h"
|
||||
#include "slang_mem.h"
|
||||
|
||||
|
||||
#define GRANULARITY 8
|
||||
#define ROUND_UP(B) ( ((B) + (GRANULARITY - 1)) & ~(GRANULARITY - 1) )
|
||||
|
||||
|
||||
/** If 1, use conventional malloc/free. Helpful for debugging */
|
||||
#define USE_MALLOC_FREE 0
|
||||
|
||||
|
||||
struct slang_mempool_
|
||||
{
|
||||
GLuint Size, Used, Count, Largest;
|
||||
char *Data;
|
||||
struct slang_mempool_ *Next;
|
||||
};
|
||||
|
||||
|
||||
slang_mempool *
|
||||
_slang_new_mempool(GLuint initialSize)
|
||||
{
|
||||
slang_mempool *pool = (slang_mempool *) calloc(1, sizeof(slang_mempool));
|
||||
if (pool) {
|
||||
pool->Data = (char *) calloc(1, initialSize);
|
||||
/*printf("ALLOC MEMPOOL %d at %p\n", initialSize, pool->Data);*/
|
||||
if (!pool->Data) {
|
||||
free(pool);
|
||||
return NULL;
|
||||
}
|
||||
pool->Size = initialSize;
|
||||
pool->Used = 0;
|
||||
}
|
||||
return pool;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
_slang_delete_mempool(slang_mempool *pool)
|
||||
{
|
||||
GLuint total = 0;
|
||||
while (pool) {
|
||||
slang_mempool *next = pool->Next;
|
||||
/*
|
||||
printf("DELETE MEMPOOL %u / %u count=%u largest=%u\n",
|
||||
pool->Used, pool->Size, pool->Count, pool->Largest);
|
||||
*/
|
||||
total += pool->Used;
|
||||
free(pool->Data);
|
||||
free(pool);
|
||||
pool = next;
|
||||
}
|
||||
/*printf("TOTAL ALLOCATED: %u\n", total);*/
|
||||
}
|
||||
|
||||
|
||||
#ifdef DEBUG
|
||||
static void
|
||||
check_zero(const char *addr, GLuint n)
|
||||
{
|
||||
GLuint i;
|
||||
for (i = 0; i < n; i++) {
|
||||
assert(addr[i]==0);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef DEBUG
|
||||
static GLboolean
|
||||
is_valid_address(const slang_mempool *pool, void *addr)
|
||||
{
|
||||
while (pool) {
|
||||
if ((char *) addr >= pool->Data &&
|
||||
(char *) addr < pool->Data + pool->Used)
|
||||
return GL_TRUE;
|
||||
|
||||
pool = pool->Next;
|
||||
}
|
||||
return GL_FALSE;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/**
|
||||
* Alloc 'bytes' from shader mempool.
|
||||
*/
|
||||
void *
|
||||
_slang_alloc(GLuint bytes)
|
||||
{
|
||||
#if USE_MALLOC_FREE
|
||||
return calloc(1, bytes);
|
||||
#else
|
||||
slang_mempool *pool;
|
||||
GET_CURRENT_CONTEXT(ctx);
|
||||
pool = (slang_mempool *) ctx->Shader.MemPool;
|
||||
|
||||
if (bytes == 0)
|
||||
bytes = 1;
|
||||
|
||||
while (pool) {
|
||||
if (pool->Used + bytes <= pool->Size) {
|
||||
/* found room */
|
||||
void *addr = (void *) (pool->Data + pool->Used);
|
||||
#ifdef DEBUG
|
||||
check_zero((char*) addr, bytes);
|
||||
#endif
|
||||
pool->Used += ROUND_UP(bytes);
|
||||
pool->Largest = MAX2(pool->Largest, bytes);
|
||||
pool->Count++;
|
||||
/*printf("alloc %u Used %u\n", bytes, pool->Used);*/
|
||||
return addr;
|
||||
}
|
||||
else if (pool->Next) {
|
||||
/* try next block */
|
||||
pool = pool->Next;
|
||||
}
|
||||
else {
|
||||
/* alloc new pool */
|
||||
const GLuint sz = MAX2(bytes, pool->Size);
|
||||
pool->Next = _slang_new_mempool(sz);
|
||||
if (!pool->Next) {
|
||||
/* we're _really_ out of memory */
|
||||
return NULL;
|
||||
}
|
||||
else {
|
||||
pool = pool->Next;
|
||||
pool->Largest = bytes;
|
||||
pool->Count++;
|
||||
pool->Used = ROUND_UP(bytes);
|
||||
#ifdef DEBUG
|
||||
check_zero((char*) pool->Data, bytes);
|
||||
#endif
|
||||
return (void *) pool->Data;
|
||||
}
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
void *
|
||||
_slang_realloc(void *oldBuffer, GLuint oldSize, GLuint newSize)
|
||||
{
|
||||
#if USE_MALLOC_FREE
|
||||
return _mesa_realloc(oldBuffer, oldSize, newSize);
|
||||
#else
|
||||
GET_CURRENT_CONTEXT(ctx);
|
||||
slang_mempool *pool = (slang_mempool *) ctx->Shader.MemPool;
|
||||
(void) pool;
|
||||
|
||||
if (newSize < oldSize) {
|
||||
return oldBuffer;
|
||||
}
|
||||
else {
|
||||
const GLuint copySize = (oldSize < newSize) ? oldSize : newSize;
|
||||
void *newBuffer = _slang_alloc(newSize);
|
||||
|
||||
if (oldBuffer)
|
||||
ASSERT(is_valid_address(pool, oldBuffer));
|
||||
|
||||
if (newBuffer && oldBuffer && copySize > 0)
|
||||
memcpy(newBuffer, oldBuffer, copySize);
|
||||
|
||||
return newBuffer;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Clone string, storing in current mempool.
|
||||
*/
|
||||
char *
|
||||
_slang_strdup(const char *s)
|
||||
{
|
||||
if (s) {
|
||||
size_t l = strlen(s);
|
||||
char *s2 = (char *) _slang_alloc(l + 1);
|
||||
if (s2)
|
||||
strcpy(s2, s);
|
||||
return s2;
|
||||
}
|
||||
else {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Don't actually free memory, but mark it (for debugging).
|
||||
*/
|
||||
void
|
||||
_slang_free(void *addr)
|
||||
{
|
||||
#if USE_MALLOC_FREE
|
||||
free(addr);
|
||||
#else
|
||||
if (addr) {
|
||||
GET_CURRENT_CONTEXT(ctx);
|
||||
slang_mempool *pool = (slang_mempool *) ctx->Shader.MemPool;
|
||||
(void) pool;
|
||||
ASSERT(is_valid_address(pool, addr));
|
||||
}
|
||||
#endif
|
||||
}
|
|
@ -1,55 +0,0 @@
|
|||
/*
|
||||
* Mesa 3-D graphics library
|
||||
* Version: 6.5.3
|
||||
*
|
||||
* Copyright (C) 2005-2007 Brian Paul All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included
|
||||
* in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
|
||||
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
|
||||
#ifndef SLANG_MEM_H
|
||||
#define SLANG_MEM_H
|
||||
|
||||
|
||||
#include "main/glheader.h"
|
||||
|
||||
|
||||
typedef struct slang_mempool_ slang_mempool;
|
||||
|
||||
|
||||
extern slang_mempool *
|
||||
_slang_new_mempool(GLuint initialSize);
|
||||
|
||||
extern void
|
||||
_slang_delete_mempool(slang_mempool *pool);
|
||||
|
||||
extern void *
|
||||
_slang_alloc(GLuint bytes);
|
||||
|
||||
extern void *
|
||||
_slang_realloc(void *oldBuffer, GLuint oldSize, GLuint newSize);
|
||||
|
||||
extern char *
|
||||
_slang_strdup(const char *s);
|
||||
|
||||
extern void
|
||||
_slang_free(void *addr);
|
||||
|
||||
|
||||
#endif
|
|
@ -1,883 +0,0 @@
|
|||
|
||||
/**
|
||||
* Dump/print a slang_operation tree
|
||||
*/
|
||||
|
||||
|
||||
#include "main/imports.h"
|
||||
#include "slang_compile.h"
|
||||
#include "slang_print.h"
|
||||
|
||||
|
||||
static void
|
||||
spaces(int n)
|
||||
{
|
||||
while (n--)
|
||||
printf(" ");
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
print_type(const slang_fully_specified_type *t)
|
||||
{
|
||||
switch (t->qualifier) {
|
||||
case SLANG_QUAL_NONE:
|
||||
/*printf("");*/
|
||||
break;
|
||||
case SLANG_QUAL_CONST:
|
||||
printf("const ");
|
||||
break;
|
||||
case SLANG_QUAL_ATTRIBUTE:
|
||||
printf("attrib ");
|
||||
break;
|
||||
case SLANG_QUAL_VARYING:
|
||||
printf("varying ");
|
||||
break;
|
||||
case SLANG_QUAL_UNIFORM:
|
||||
printf("uniform ");
|
||||
break;
|
||||
case SLANG_QUAL_OUT:
|
||||
printf("output ");
|
||||
break;
|
||||
case SLANG_QUAL_INOUT:
|
||||
printf("inout ");
|
||||
break;
|
||||
case SLANG_QUAL_FIXEDOUTPUT:
|
||||
printf("fixedoutput");
|
||||
break;
|
||||
case SLANG_QUAL_FIXEDINPUT:
|
||||
printf("fixedinput");
|
||||
break;
|
||||
default:
|
||||
printf("unknown qualifer!");
|
||||
}
|
||||
|
||||
switch (t->specifier.type) {
|
||||
case SLANG_SPEC_VOID:
|
||||
printf("void");
|
||||
break;
|
||||
case SLANG_SPEC_BOOL:
|
||||
printf("bool");
|
||||
break;
|
||||
case SLANG_SPEC_BVEC2:
|
||||
printf("bvec2");
|
||||
break;
|
||||
case SLANG_SPEC_BVEC3:
|
||||
printf("bvec3");
|
||||
break;
|
||||
case SLANG_SPEC_BVEC4:
|
||||
printf("bvec4");
|
||||
break;
|
||||
case SLANG_SPEC_INT:
|
||||
printf("int");
|
||||
break;
|
||||
case SLANG_SPEC_IVEC2:
|
||||
printf("ivec2");
|
||||
break;
|
||||
case SLANG_SPEC_IVEC3:
|
||||
printf("ivec3");
|
||||
break;
|
||||
case SLANG_SPEC_IVEC4:
|
||||
printf("ivec4");
|
||||
break;
|
||||
case SLANG_SPEC_FLOAT:
|
||||
printf("float");
|
||||
break;
|
||||
case SLANG_SPEC_VEC2:
|
||||
printf("vec2");
|
||||
break;
|
||||
case SLANG_SPEC_VEC3:
|
||||
printf("vec3");
|
||||
break;
|
||||
case SLANG_SPEC_VEC4:
|
||||
printf("vec4");
|
||||
break;
|
||||
case SLANG_SPEC_MAT2:
|
||||
printf("mat2");
|
||||
break;
|
||||
case SLANG_SPEC_MAT3:
|
||||
printf("mat3");
|
||||
break;
|
||||
case SLANG_SPEC_MAT4:
|
||||
printf("mat4");
|
||||
break;
|
||||
case SLANG_SPEC_MAT23:
|
||||
printf("mat2x3");
|
||||
break;
|
||||
case SLANG_SPEC_MAT32:
|
||||
printf("mat3x2");
|
||||
break;
|
||||
case SLANG_SPEC_MAT24:
|
||||
printf("mat2x4");
|
||||
break;
|
||||
case SLANG_SPEC_MAT42:
|
||||
printf("mat4x2");
|
||||
break;
|
||||
case SLANG_SPEC_MAT34:
|
||||
printf("mat3x4");
|
||||
break;
|
||||
case SLANG_SPEC_MAT43:
|
||||
printf("mat4x3");
|
||||
break;
|
||||
case SLANG_SPEC_SAMPLER_1D:
|
||||
printf("sampler1D");
|
||||
break;
|
||||
case SLANG_SPEC_SAMPLER_2D:
|
||||
printf("sampler2D");
|
||||
break;
|
||||
case SLANG_SPEC_SAMPLER_3D:
|
||||
printf("sampler3D");
|
||||
break;
|
||||
case SLANG_SPEC_SAMPLER_CUBE:
|
||||
printf("samplerCube");
|
||||
break;
|
||||
case SLANG_SPEC_SAMPLER_1D_SHADOW:
|
||||
printf("sampler1DShadow");
|
||||
break;
|
||||
case SLANG_SPEC_SAMPLER_2D_SHADOW:
|
||||
printf("sampler2DShadow");
|
||||
break;
|
||||
case SLANG_SPEC_STRUCT:
|
||||
printf("struct");
|
||||
break;
|
||||
case SLANG_SPEC_ARRAY:
|
||||
printf("array");
|
||||
break;
|
||||
default:
|
||||
printf("unknown type");
|
||||
}
|
||||
/*printf("\n");*/
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
print_variable(const slang_variable *v, int indent)
|
||||
{
|
||||
spaces(indent);
|
||||
printf("VAR ");
|
||||
print_type(&v->type);
|
||||
printf(" %s (at %p)", (char *) v->a_name, (void *) v);
|
||||
if (v->initializer) {
|
||||
printf(" :=\n");
|
||||
slang_print_tree(v->initializer, indent + 3);
|
||||
}
|
||||
else {
|
||||
printf(";\n");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
print_binary(const slang_operation *op, const char *oper, int indent)
|
||||
{
|
||||
assert(op->num_children == 2);
|
||||
#if 0
|
||||
printf("binary at %p locals=%p outer=%p\n",
|
||||
(void *) op,
|
||||
(void *) op->locals,
|
||||
(void *) op->locals->outer_scope);
|
||||
#endif
|
||||
slang_print_tree(&op->children[0], indent + 3);
|
||||
spaces(indent);
|
||||
printf("%s at %p locals=%p outer=%p\n",
|
||||
oper, (void *) op, (void *) op->locals,
|
||||
(void *) op->locals->outer_scope);
|
||||
slang_print_tree(&op->children[1], indent + 3);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
print_generic2(const slang_operation *op, const char *oper,
|
||||
const char *s, int indent)
|
||||
{
|
||||
GLuint i;
|
||||
if (oper) {
|
||||
spaces(indent);
|
||||
printf("%s %s at %p locals=%p outer=%p\n",
|
||||
oper, s, (void *) op, (void *) op->locals,
|
||||
(void *) op->locals->outer_scope);
|
||||
}
|
||||
for (i = 0; i < op->num_children; i++) {
|
||||
spaces(indent);
|
||||
printf("//child %u of %u:\n", i, op->num_children);
|
||||
slang_print_tree(&op->children[i], indent);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
print_generic(const slang_operation *op, const char *oper, int indent)
|
||||
{
|
||||
print_generic2(op, oper, "", indent);
|
||||
}
|
||||
|
||||
|
||||
static const slang_variable_scope *
|
||||
find_scope(const slang_variable_scope *s, slang_atom name)
|
||||
{
|
||||
GLuint i;
|
||||
for (i = 0; i < s->num_variables; i++) {
|
||||
if (s->variables[i]->a_name == name)
|
||||
return s;
|
||||
}
|
||||
if (s->outer_scope)
|
||||
return find_scope(s->outer_scope, name);
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static const slang_variable *
|
||||
find_var(const slang_variable_scope *s, slang_atom name)
|
||||
{
|
||||
GLuint i;
|
||||
for (i = 0; i < s->num_variables; i++) {
|
||||
if (s->variables[i]->a_name == name)
|
||||
return s->variables[i];
|
||||
}
|
||||
if (s->outer_scope)
|
||||
return find_var(s->outer_scope, name);
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
slang_print_tree(const slang_operation *op, int indent)
|
||||
{
|
||||
GLuint i;
|
||||
|
||||
switch (op->type) {
|
||||
|
||||
case SLANG_OPER_NONE:
|
||||
spaces(indent);
|
||||
printf("SLANG_OPER_NONE\n");
|
||||
break;
|
||||
|
||||
case SLANG_OPER_BLOCK_NO_NEW_SCOPE:
|
||||
spaces(indent);
|
||||
printf("{ locals=%p outer=%p\n", (void*)op->locals, (void*)op->locals->outer_scope);
|
||||
print_generic(op, NULL, indent+3);
|
||||
spaces(indent);
|
||||
printf("}\n");
|
||||
break;
|
||||
|
||||
case SLANG_OPER_BLOCK_NEW_SCOPE:
|
||||
case SLANG_OPER_NON_INLINED_CALL:
|
||||
spaces(indent);
|
||||
printf("{{ // new scope locals=%p outer=%p: ",
|
||||
(void *) op->locals,
|
||||
(void *) op->locals->outer_scope);
|
||||
for (i = 0; i < op->locals->num_variables; i++) {
|
||||
printf("%s ", (char *) op->locals->variables[i]->a_name);
|
||||
}
|
||||
printf("\n");
|
||||
print_generic(op, NULL, indent+3);
|
||||
spaces(indent);
|
||||
printf("}}\n");
|
||||
break;
|
||||
|
||||
case SLANG_OPER_VARIABLE_DECL:
|
||||
assert(op->num_children == 0 || op->num_children == 1);
|
||||
{
|
||||
slang_variable *v;
|
||||
v = _slang_variable_locate(op->locals, op->a_id, GL_TRUE);
|
||||
if (v) {
|
||||
const slang_variable_scope *scope;
|
||||
spaces(indent);
|
||||
printf("DECL (locals=%p outer=%p) ", (void*)op->locals, (void*) op->locals->outer_scope);
|
||||
print_type(&v->type);
|
||||
printf(" %s (%p)", (char *) op->a_id,
|
||||
(void *) find_var(op->locals, op->a_id));
|
||||
|
||||
scope = find_scope(op->locals, op->a_id);
|
||||
printf(" (in scope %p) ", (void *) scope);
|
||||
assert(scope);
|
||||
if (op->num_children == 1) {
|
||||
printf(" :=\n");
|
||||
slang_print_tree(&op->children[0], indent + 3);
|
||||
}
|
||||
else if (v->initializer) {
|
||||
printf(" := INITIALIZER\n");
|
||||
slang_print_tree(v->initializer, indent + 3);
|
||||
}
|
||||
else {
|
||||
printf(";\n");
|
||||
}
|
||||
/*
|
||||
spaces(indent);
|
||||
printf("TYPE: ");
|
||||
print_type(&v->type);
|
||||
spaces(indent);
|
||||
printf("ADDR: %d size: %d\n", v->address, v->size);
|
||||
*/
|
||||
}
|
||||
else {
|
||||
spaces(indent);
|
||||
printf("DECL %s (anonymous variable!!!!)\n", (char *) op->a_id);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case SLANG_OPER_ASM:
|
||||
spaces(indent);
|
||||
printf("ASM: %s at %p locals=%p outer=%p\n",
|
||||
(char *) op->a_id,
|
||||
(void *) op,
|
||||
(void *) op->locals,
|
||||
(void *) op->locals->outer_scope);
|
||||
print_generic(op, "ASM", indent+3);
|
||||
break;
|
||||
|
||||
case SLANG_OPER_BREAK:
|
||||
spaces(indent);
|
||||
printf("BREAK\n");
|
||||
break;
|
||||
|
||||
case SLANG_OPER_CONTINUE:
|
||||
spaces(indent);
|
||||
printf("CONTINUE\n");
|
||||
break;
|
||||
|
||||
case SLANG_OPER_DISCARD:
|
||||
spaces(indent);
|
||||
printf("DISCARD\n");
|
||||
break;
|
||||
|
||||
case SLANG_OPER_RETURN:
|
||||
spaces(indent);
|
||||
printf("RETURN\n");
|
||||
if (op->num_children > 0)
|
||||
slang_print_tree(&op->children[0], indent + 3);
|
||||
break;
|
||||
|
||||
case SLANG_OPER_RETURN_INLINED:
|
||||
spaces(indent);
|
||||
printf("RETURN_INLINED\n");
|
||||
if (op->num_children > 0)
|
||||
slang_print_tree(&op->children[0], indent + 3);
|
||||
break;
|
||||
|
||||
case SLANG_OPER_LABEL:
|
||||
spaces(indent);
|
||||
printf("LABEL %s\n", (char *) op->a_id);
|
||||
break;
|
||||
|
||||
case SLANG_OPER_EXPRESSION:
|
||||
spaces(indent);
|
||||
printf("EXPR: locals=%p outer=%p\n",
|
||||
(void *) op->locals,
|
||||
(void *) op->locals->outer_scope);
|
||||
/*print_generic(op, "SLANG_OPER_EXPRESSION", indent);*/
|
||||
slang_print_tree(&op->children[0], indent + 3);
|
||||
break;
|
||||
|
||||
case SLANG_OPER_IF:
|
||||
spaces(indent);
|
||||
printf("IF\n");
|
||||
slang_print_tree(&op->children[0], indent + 3);
|
||||
spaces(indent);
|
||||
printf("THEN\n");
|
||||
slang_print_tree(&op->children[1], indent + 3);
|
||||
spaces(indent);
|
||||
printf("ELSE\n");
|
||||
slang_print_tree(&op->children[2], indent + 3);
|
||||
spaces(indent);
|
||||
printf("ENDIF\n");
|
||||
break;
|
||||
|
||||
case SLANG_OPER_WHILE:
|
||||
assert(op->num_children == 2);
|
||||
spaces(indent);
|
||||
printf("WHILE LOOP: locals = %p\n", (void *) op->locals);
|
||||
indent += 3;
|
||||
spaces(indent);
|
||||
printf("WHILE cond:\n");
|
||||
slang_print_tree(&op->children[0], indent + 3);
|
||||
spaces(indent);
|
||||
printf("WHILE body:\n");
|
||||
slang_print_tree(&op->children[1], indent + 3);
|
||||
indent -= 3;
|
||||
spaces(indent);
|
||||
printf("END WHILE LOOP\n");
|
||||
break;
|
||||
|
||||
case SLANG_OPER_DO:
|
||||
spaces(indent);
|
||||
printf("DO LOOP: locals = %p\n", (void *) op->locals);
|
||||
indent += 3;
|
||||
spaces(indent);
|
||||
printf("DO body:\n");
|
||||
slang_print_tree(&op->children[0], indent + 3);
|
||||
spaces(indent);
|
||||
printf("DO cond:\n");
|
||||
slang_print_tree(&op->children[1], indent + 3);
|
||||
indent -= 3;
|
||||
spaces(indent);
|
||||
printf("END DO LOOP\n");
|
||||
break;
|
||||
|
||||
case SLANG_OPER_FOR:
|
||||
spaces(indent);
|
||||
printf("FOR LOOP: locals = %p\n", (void *) op->locals);
|
||||
indent += 3;
|
||||
spaces(indent);
|
||||
printf("FOR init:\n");
|
||||
slang_print_tree(&op->children[0], indent + 3);
|
||||
spaces(indent);
|
||||
printf("FOR condition:\n");
|
||||
slang_print_tree(&op->children[1], indent + 3);
|
||||
spaces(indent);
|
||||
printf("FOR step:\n");
|
||||
slang_print_tree(&op->children[2], indent + 3);
|
||||
spaces(indent);
|
||||
printf("FOR body:\n");
|
||||
slang_print_tree(&op->children[3], indent + 3);
|
||||
indent -= 3;
|
||||
spaces(indent);
|
||||
printf("ENDFOR\n");
|
||||
/*
|
||||
print_generic(op, "FOR", indent + 3);
|
||||
*/
|
||||
break;
|
||||
|
||||
case SLANG_OPER_VOID:
|
||||
spaces(indent);
|
||||
printf("(oper-void)\n");
|
||||
break;
|
||||
|
||||
case SLANG_OPER_LITERAL_BOOL:
|
||||
spaces(indent);
|
||||
printf("LITERAL (");
|
||||
for (i = 0; i < op->literal_size; i++)
|
||||
printf("%s ", op->literal[0] ? "TRUE" : "FALSE");
|
||||
printf(")\n");
|
||||
|
||||
break;
|
||||
|
||||
case SLANG_OPER_LITERAL_INT:
|
||||
spaces(indent);
|
||||
printf("LITERAL (");
|
||||
for (i = 0; i < op->literal_size; i++)
|
||||
printf("%d ", (int) op->literal[i]);
|
||||
printf(")\n");
|
||||
break;
|
||||
|
||||
case SLANG_OPER_LITERAL_FLOAT:
|
||||
spaces(indent);
|
||||
printf("LITERAL (");
|
||||
for (i = 0; i < op->literal_size; i++)
|
||||
printf("%f ", op->literal[i]);
|
||||
printf(")\n");
|
||||
break;
|
||||
|
||||
case SLANG_OPER_IDENTIFIER:
|
||||
{
|
||||
const slang_variable_scope *scope;
|
||||
spaces(indent);
|
||||
if (op->var && op->var->a_name) {
|
||||
scope = find_scope(op->locals, op->var->a_name);
|
||||
printf("VAR %s (in scope %p)\n", (char *) op->var->a_name,
|
||||
(void *) scope);
|
||||
assert(scope);
|
||||
}
|
||||
else {
|
||||
scope = find_scope(op->locals, op->a_id);
|
||||
printf("VAR' %s (in scope %p) locals=%p outer=%p\n",
|
||||
(char *) op->a_id,
|
||||
(void *) scope,
|
||||
(void *) op->locals,
|
||||
(void *) op->locals->outer_scope);
|
||||
/*assert(scope);*/
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case SLANG_OPER_SEQUENCE:
|
||||
print_generic(op, "COMMA-SEQ", indent+3);
|
||||
break;
|
||||
|
||||
case SLANG_OPER_ASSIGN:
|
||||
spaces(indent);
|
||||
printf("ASSIGNMENT locals=%p outer=%p\n",
|
||||
(void *) op->locals,
|
||||
(void *) op->locals->outer_scope);
|
||||
print_binary(op, ":=", indent);
|
||||
break;
|
||||
|
||||
case SLANG_OPER_ADDASSIGN:
|
||||
spaces(indent);
|
||||
printf("ASSIGN\n");
|
||||
print_binary(op, "+=", indent);
|
||||
break;
|
||||
|
||||
case SLANG_OPER_SUBASSIGN:
|
||||
spaces(indent);
|
||||
printf("ASSIGN\n");
|
||||
print_binary(op, "-=", indent);
|
||||
break;
|
||||
|
||||
case SLANG_OPER_MULASSIGN:
|
||||
spaces(indent);
|
||||
printf("ASSIGN\n");
|
||||
print_binary(op, "*=", indent);
|
||||
break;
|
||||
|
||||
case SLANG_OPER_DIVASSIGN:
|
||||
spaces(indent);
|
||||
printf("ASSIGN\n");
|
||||
print_binary(op, "/=", indent);
|
||||
break;
|
||||
|
||||
/*SLANG_OPER_MODASSIGN,*/
|
||||
/*SLANG_OPER_LSHASSIGN,*/
|
||||
/*SLANG_OPER_RSHASSIGN,*/
|
||||
/*SLANG_OPER_ORASSIGN,*/
|
||||
/*SLANG_OPER_XORASSIGN,*/
|
||||
/*SLANG_OPER_ANDASSIGN,*/
|
||||
case SLANG_OPER_SELECT:
|
||||
spaces(indent);
|
||||
printf("SLANG_OPER_SELECT n=%d\n", op->num_children);
|
||||
assert(op->num_children == 3);
|
||||
slang_print_tree(&op->children[0], indent+3);
|
||||
spaces(indent);
|
||||
printf("?\n");
|
||||
slang_print_tree(&op->children[1], indent+3);
|
||||
spaces(indent);
|
||||
printf(":\n");
|
||||
slang_print_tree(&op->children[2], indent+3);
|
||||
break;
|
||||
|
||||
case SLANG_OPER_LOGICALOR:
|
||||
print_binary(op, "||", indent);
|
||||
break;
|
||||
|
||||
case SLANG_OPER_LOGICALXOR:
|
||||
print_binary(op, "^^", indent);
|
||||
break;
|
||||
|
||||
case SLANG_OPER_LOGICALAND:
|
||||
print_binary(op, "&&", indent);
|
||||
break;
|
||||
|
||||
/*SLANG_OPER_BITOR*/
|
||||
/*SLANG_OPER_BITXOR*/
|
||||
/*SLANG_OPER_BITAND*/
|
||||
case SLANG_OPER_EQUAL:
|
||||
print_binary(op, "==", indent);
|
||||
break;
|
||||
|
||||
case SLANG_OPER_NOTEQUAL:
|
||||
print_binary(op, "!=", indent);
|
||||
break;
|
||||
|
||||
case SLANG_OPER_LESS:
|
||||
print_binary(op, "<", indent);
|
||||
break;
|
||||
|
||||
case SLANG_OPER_GREATER:
|
||||
print_binary(op, ">", indent);
|
||||
break;
|
||||
|
||||
case SLANG_OPER_LESSEQUAL:
|
||||
print_binary(op, "<=", indent);
|
||||
break;
|
||||
|
||||
case SLANG_OPER_GREATEREQUAL:
|
||||
print_binary(op, ">=", indent);
|
||||
break;
|
||||
|
||||
/*SLANG_OPER_LSHIFT*/
|
||||
/*SLANG_OPER_RSHIFT*/
|
||||
case SLANG_OPER_ADD:
|
||||
print_binary(op, "+", indent);
|
||||
break;
|
||||
|
||||
case SLANG_OPER_SUBTRACT:
|
||||
print_binary(op, "-", indent);
|
||||
break;
|
||||
|
||||
case SLANG_OPER_MULTIPLY:
|
||||
print_binary(op, "*", indent);
|
||||
break;
|
||||
|
||||
case SLANG_OPER_DIVIDE:
|
||||
print_binary(op, "/", indent);
|
||||
break;
|
||||
|
||||
/*SLANG_OPER_MODULUS*/
|
||||
case SLANG_OPER_PREINCREMENT:
|
||||
spaces(indent);
|
||||
printf("PRE++\n");
|
||||
slang_print_tree(&op->children[0], indent+3);
|
||||
break;
|
||||
|
||||
case SLANG_OPER_PREDECREMENT:
|
||||
spaces(indent);
|
||||
printf("PRE--\n");
|
||||
slang_print_tree(&op->children[0], indent+3);
|
||||
break;
|
||||
|
||||
case SLANG_OPER_PLUS:
|
||||
spaces(indent);
|
||||
printf("SLANG_OPER_PLUS\n");
|
||||
break;
|
||||
|
||||
case SLANG_OPER_MINUS:
|
||||
spaces(indent);
|
||||
printf("SLANG_OPER_MINUS\n");
|
||||
break;
|
||||
|
||||
/*SLANG_OPER_COMPLEMENT*/
|
||||
case SLANG_OPER_NOT:
|
||||
spaces(indent);
|
||||
printf("NOT\n");
|
||||
slang_print_tree(&op->children[0], indent+3);
|
||||
break;
|
||||
|
||||
case SLANG_OPER_SUBSCRIPT:
|
||||
spaces(indent);
|
||||
printf("SLANG_OPER_SUBSCRIPT locals=%p outer=%p\n",
|
||||
(void *) op->locals,
|
||||
(void *) op->locals->outer_scope);
|
||||
print_generic(op, NULL, indent+3);
|
||||
break;
|
||||
|
||||
case SLANG_OPER_CALL:
|
||||
#if 0
|
||||
slang_function *fun
|
||||
= _slang_function_locate(A->space.funcs, oper->a_id,
|
||||
oper->children,
|
||||
oper->num_children, &A->space, A->atoms);
|
||||
#endif
|
||||
spaces(indent);
|
||||
printf("CALL %s(\n", (char *) op->a_id);
|
||||
for (i = 0; i < op->num_children; i++) {
|
||||
slang_print_tree(&op->children[i], indent+3);
|
||||
if (i + 1 < op->num_children) {
|
||||
spaces(indent + 3);
|
||||
printf(",\n");
|
||||
}
|
||||
}
|
||||
spaces(indent);
|
||||
printf(")\n");
|
||||
break;
|
||||
|
||||
case SLANG_OPER_METHOD:
|
||||
spaces(indent);
|
||||
printf("METHOD CALL %s.%s\n", (char *) op->a_obj, (char *) op->a_id);
|
||||
break;
|
||||
|
||||
case SLANG_OPER_FIELD:
|
||||
spaces(indent);
|
||||
printf("FIELD %s of\n", (char*) op->a_id);
|
||||
slang_print_tree(&op->children[0], indent+3);
|
||||
break;
|
||||
|
||||
case SLANG_OPER_POSTINCREMENT:
|
||||
spaces(indent);
|
||||
printf("POST++\n");
|
||||
slang_print_tree(&op->children[0], indent+3);
|
||||
break;
|
||||
|
||||
case SLANG_OPER_POSTDECREMENT:
|
||||
spaces(indent);
|
||||
printf("POST--\n");
|
||||
slang_print_tree(&op->children[0], indent+3);
|
||||
break;
|
||||
|
||||
default:
|
||||
printf("unknown op->type %d\n", (int) op->type);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
slang_print_function(const slang_function *f, GLboolean body)
|
||||
{
|
||||
GLuint i;
|
||||
|
||||
#if 0
|
||||
if (strcmp((char *) f->header.a_name, "main") != 0)
|
||||
return;
|
||||
#endif
|
||||
|
||||
printf("FUNCTION %s ( scope=%p\n",
|
||||
(char *) f->header.a_name, (void *) f->parameters);
|
||||
|
||||
for (i = 0; i < f->param_count; i++) {
|
||||
print_variable(f->parameters->variables[i], 3);
|
||||
}
|
||||
|
||||
printf(") param scope = %p\n", (void *) f->parameters);
|
||||
|
||||
if (body && f->body)
|
||||
slang_print_tree(f->body, 0);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
const char *
|
||||
slang_type_qual_string(slang_type_qualifier q)
|
||||
{
|
||||
switch (q) {
|
||||
case SLANG_QUAL_NONE:
|
||||
return "none";
|
||||
case SLANG_QUAL_CONST:
|
||||
return "const";
|
||||
case SLANG_QUAL_ATTRIBUTE:
|
||||
return "attribute";
|
||||
case SLANG_QUAL_VARYING:
|
||||
return "varying";
|
||||
case SLANG_QUAL_UNIFORM:
|
||||
return "uniform";
|
||||
case SLANG_QUAL_OUT:
|
||||
return "out";
|
||||
case SLANG_QUAL_INOUT:
|
||||
return "inout";
|
||||
case SLANG_QUAL_FIXEDOUTPUT:
|
||||
return "fixedoutput";
|
||||
case SLANG_QUAL_FIXEDINPUT:
|
||||
return "fixedinputk";
|
||||
default:
|
||||
return "qual?";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static const char *
|
||||
slang_type_string(slang_type_specifier_type t)
|
||||
{
|
||||
switch (t) {
|
||||
case SLANG_SPEC_VOID:
|
||||
return "void";
|
||||
case SLANG_SPEC_BOOL:
|
||||
return "bool";
|
||||
case SLANG_SPEC_BVEC2:
|
||||
return "bvec2";
|
||||
case SLANG_SPEC_BVEC3:
|
||||
return "bvec3";
|
||||
case SLANG_SPEC_BVEC4:
|
||||
return "bvec4";
|
||||
case SLANG_SPEC_INT:
|
||||
return "int";
|
||||
case SLANG_SPEC_IVEC2:
|
||||
return "ivec2";
|
||||
case SLANG_SPEC_IVEC3:
|
||||
return "ivec3";
|
||||
case SLANG_SPEC_IVEC4:
|
||||
return "ivec4";
|
||||
case SLANG_SPEC_FLOAT:
|
||||
return "float";
|
||||
case SLANG_SPEC_VEC2:
|
||||
return "vec2";
|
||||
case SLANG_SPEC_VEC3:
|
||||
return "vec3";
|
||||
case SLANG_SPEC_VEC4:
|
||||
return "vec4";
|
||||
case SLANG_SPEC_MAT2:
|
||||
return "mat2";
|
||||
case SLANG_SPEC_MAT3:
|
||||
return "mat3";
|
||||
case SLANG_SPEC_MAT4:
|
||||
return "mat4";
|
||||
case SLANG_SPEC_SAMPLER_1D:
|
||||
return "sampler1D";
|
||||
case SLANG_SPEC_SAMPLER_2D:
|
||||
return "sampler2D";
|
||||
case SLANG_SPEC_SAMPLER_3D:
|
||||
return "sampler3D";
|
||||
case SLANG_SPEC_SAMPLER_CUBE:
|
||||
return "samplerCube";
|
||||
case SLANG_SPEC_SAMPLER_1D_SHADOW:
|
||||
return "sampler1DShadow";
|
||||
case SLANG_SPEC_SAMPLER_2D_SHADOW:
|
||||
return "sampler2DShadow";
|
||||
case SLANG_SPEC_SAMPLER_RECT:
|
||||
return "sampler2DRect";
|
||||
case SLANG_SPEC_SAMPLER_RECT_SHADOW:
|
||||
return "sampler2DRectShadow";
|
||||
case SLANG_SPEC_STRUCT:
|
||||
return "struct";
|
||||
case SLANG_SPEC_ARRAY:
|
||||
return "array";
|
||||
default:
|
||||
return "type?";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static const char *
|
||||
slang_fq_type_string(const slang_fully_specified_type *t)
|
||||
{
|
||||
static char str[1000];
|
||||
_mesa_snprintf(str, sizeof(str), "%s %s", slang_type_qual_string(t->qualifier),
|
||||
slang_type_string(t->specifier.type));
|
||||
return str;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
slang_print_type(const slang_fully_specified_type *t)
|
||||
{
|
||||
printf("%s %s", slang_type_qual_string(t->qualifier),
|
||||
slang_type_string(t->specifier.type));
|
||||
}
|
||||
|
||||
|
||||
#if 0
|
||||
static char *
|
||||
slang_var_string(const slang_variable *v)
|
||||
{
|
||||
static char str[1000];
|
||||
_mesa_snprintf(str, sizeof(str), "%s : %s",
|
||||
(char *) v->a_name,
|
||||
slang_fq_type_string(&v->type));
|
||||
return str;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
void
|
||||
slang_print_variable(const slang_variable *v)
|
||||
{
|
||||
printf("Name: %s\n", (char *) v->a_name);
|
||||
printf("Type: %s\n", slang_fq_type_string(&v->type));
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
_slang_print_var_scope(const slang_variable_scope *vars, int indent)
|
||||
{
|
||||
GLuint i;
|
||||
|
||||
spaces(indent);
|
||||
printf("Var scope %p %d vars:\n", (void *) vars, vars->num_variables);
|
||||
for (i = 0; i < vars->num_variables; i++) {
|
||||
spaces(indent + 3);
|
||||
printf("%s (at %p)\n", (char *) vars->variables[i]->a_name, (void*) (vars->variables + i));
|
||||
}
|
||||
spaces(indent + 3);
|
||||
printf("outer_scope = %p\n", (void*) vars->outer_scope);
|
||||
|
||||
if (vars->outer_scope) {
|
||||
/*spaces(indent + 3);*/
|
||||
_slang_print_var_scope(vars->outer_scope, indent + 3);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
int
|
||||
slang_checksum_tree(const slang_operation *op)
|
||||
{
|
||||
int s = op->num_children;
|
||||
GLuint i;
|
||||
|
||||
for (i = 0; i < op->num_children; i++) {
|
||||
s += slang_checksum_tree(&op->children[i]);
|
||||
}
|
||||
return s;
|
||||
}
|
|
@ -1,35 +0,0 @@
|
|||
|
||||
|
||||
#ifndef SLANG_PRINT
|
||||
#define SLANG_PRINT
|
||||
|
||||
#include "main/glheader.h"
|
||||
#include "slang_compile_function.h"
|
||||
#include "slang_compile_operation.h"
|
||||
#include "slang_compile_variable.h"
|
||||
#include "slang_typeinfo.h"
|
||||
|
||||
extern void
|
||||
slang_print_function(const slang_function *f, GLboolean body);
|
||||
|
||||
extern void
|
||||
slang_print_tree(const slang_operation *op, int indent);
|
||||
|
||||
extern const char *
|
||||
slang_type_qual_string(slang_type_qualifier q);
|
||||
|
||||
extern void
|
||||
slang_print_type(const slang_fully_specified_type *t);
|
||||
|
||||
extern void
|
||||
slang_print_variable(const slang_variable *v);
|
||||
|
||||
extern void
|
||||
_slang_print_var_scope(const slang_variable_scope *s, int indent);
|
||||
|
||||
|
||||
extern int
|
||||
slang_checksum_tree(const slang_operation *op);
|
||||
|
||||
#endif /* SLANG_PRINT */
|
||||
|
|
@ -1,527 +0,0 @@
|
|||
/*
|
||||
* Mesa 3-D graphics library
|
||||
* Version: 7.1
|
||||
*
|
||||
* Copyright (C) 2005-2008 Brian Paul All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included
|
||||
* in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
|
||||
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Functions for constant folding, built-in constant lookup, and function
|
||||
* call casting.
|
||||
*/
|
||||
|
||||
|
||||
#include "main/imports.h"
|
||||
#include "main/macros.h"
|
||||
#include "main/get.h"
|
||||
#include "slang_compile.h"
|
||||
#include "slang_codegen.h"
|
||||
#include "slang_simplify.h"
|
||||
#include "slang_print.h"
|
||||
|
||||
|
||||
#ifndef GL_MAX_FRAGMENT_UNIFORM_VECTORS
|
||||
#define GL_MAX_FRAGMENT_UNIFORM_VECTORS 0x8DFD
|
||||
#endif
|
||||
#ifndef GL_MAX_VERTEX_UNIFORM_VECTORS
|
||||
#define GL_MAX_VERTEX_UNIFORM_VECTORS 0x8DFB
|
||||
#endif
|
||||
#ifndef GL_MAX_VARYING_VECTORS
|
||||
#define GL_MAX_VARYING_VECTORS 0x8DFC
|
||||
#endif
|
||||
|
||||
|
||||
/**
|
||||
* Lookup the value of named constant, such as gl_MaxLights.
|
||||
* \return value of constant, or -1 if unknown
|
||||
*/
|
||||
GLint
|
||||
_slang_lookup_constant(const char *name)
|
||||
{
|
||||
struct constant_info {
|
||||
const char *Name;
|
||||
const GLenum Token;
|
||||
};
|
||||
static const struct constant_info info[] = {
|
||||
{ "gl_MaxClipPlanes", GL_MAX_CLIP_PLANES },
|
||||
{ "gl_MaxCombinedTextureImageUnits", GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS },
|
||||
{ "gl_MaxDrawBuffers", GL_MAX_DRAW_BUFFERS },
|
||||
{ "gl_MaxFragmentUniformComponents", GL_MAX_FRAGMENT_UNIFORM_COMPONENTS },
|
||||
{ "gl_MaxLights", GL_MAX_LIGHTS },
|
||||
{ "gl_MaxTextureUnits", GL_MAX_TEXTURE_UNITS },
|
||||
{ "gl_MaxTextureCoords", GL_MAX_TEXTURE_COORDS },
|
||||
{ "gl_MaxVertexAttribs", GL_MAX_VERTEX_ATTRIBS },
|
||||
{ "gl_MaxVertexUniformComponents", GL_MAX_VERTEX_UNIFORM_COMPONENTS },
|
||||
{ "gl_MaxVaryingFloats", GL_MAX_VARYING_FLOATS },
|
||||
{ "gl_MaxVertexTextureImageUnits", GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS },
|
||||
{ "gl_MaxTextureImageUnits", GL_MAX_TEXTURE_IMAGE_UNITS },
|
||||
#if FEATURE_es2_glsl
|
||||
{ "gl_MaxVertexUniformVectors", GL_MAX_VERTEX_UNIFORM_VECTORS },
|
||||
{ "gl_MaxVaryingVectors", GL_MAX_VARYING_VECTORS },
|
||||
{ "gl_MaxFragmentUniformVectors", GL_MAX_FRAGMENT_UNIFORM_VECTORS },
|
||||
#endif
|
||||
{ NULL, 0 }
|
||||
};
|
||||
GLuint i;
|
||||
|
||||
for (i = 0; info[i].Name; i++) {
|
||||
if (strcmp(info[i].Name, name) == 0) {
|
||||
/* found */
|
||||
GLint values[16];
|
||||
values[0] = -1;
|
||||
_mesa_GetIntegerv(info[i].Token, values);
|
||||
ASSERT(values[0] >= 0); /* sanity check that glGetFloatv worked */
|
||||
return values[0];
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
static slang_operation_type
|
||||
literal_type(slang_operation_type t1, slang_operation_type t2)
|
||||
{
|
||||
if (t1 == SLANG_OPER_LITERAL_FLOAT || t2 == SLANG_OPER_LITERAL_FLOAT)
|
||||
return SLANG_OPER_LITERAL_FLOAT;
|
||||
else
|
||||
return SLANG_OPER_LITERAL_INT;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Recursively traverse an AST tree, applying simplifications wherever
|
||||
* possible.
|
||||
* At the least, we do constant folding. We need to do that much so that
|
||||
* compile-time expressions can be evaluated for things like array
|
||||
* declarations. I.e.: float foo[3 + 5];
|
||||
*/
|
||||
void
|
||||
_slang_simplify(slang_operation *oper,
|
||||
const slang_name_space * space,
|
||||
slang_atom_pool * atoms)
|
||||
{
|
||||
GLboolean isFloat[4];
|
||||
GLboolean isBool[4];
|
||||
GLuint i, n;
|
||||
|
||||
if (oper->type == SLANG_OPER_IDENTIFIER) {
|
||||
/* see if it's a named constant */
|
||||
GLint value = _slang_lookup_constant((char *) oper->a_id);
|
||||
/*printf("value[%s] = %d\n", (char*) oper->a_id, value);*/
|
||||
if (value >= 0) {
|
||||
oper->literal[0] =
|
||||
oper->literal[1] =
|
||||
oper->literal[2] =
|
||||
oper->literal[3] = (GLfloat) value;
|
||||
oper->type = SLANG_OPER_LITERAL_INT;
|
||||
return;
|
||||
}
|
||||
/* look for user-defined constant */
|
||||
{
|
||||
slang_variable *var;
|
||||
var = _slang_variable_locate(oper->locals, oper->a_id, GL_TRUE);
|
||||
if (var) {
|
||||
if (var->type.qualifier == SLANG_QUAL_CONST &&
|
||||
var->initializer &&
|
||||
(var->initializer->type == SLANG_OPER_LITERAL_INT ||
|
||||
var->initializer->type == SLANG_OPER_LITERAL_FLOAT)) {
|
||||
oper->literal[0] = var->initializer->literal[0];
|
||||
oper->literal[1] = var->initializer->literal[1];
|
||||
oper->literal[2] = var->initializer->literal[2];
|
||||
oper->literal[3] = var->initializer->literal[3];
|
||||
oper->literal_size = var->initializer->literal_size;
|
||||
oper->type = var->initializer->type;
|
||||
/*
|
||||
printf("value[%s] = %f\n",
|
||||
(char*) oper->a_id, oper->literal[0]);
|
||||
*/
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* first, simplify children */
|
||||
for (i = 0; i < oper->num_children; i++) {
|
||||
_slang_simplify(&oper->children[i], space, atoms);
|
||||
}
|
||||
|
||||
/* examine children */
|
||||
n = MIN2(oper->num_children, 4);
|
||||
for (i = 0; i < n; i++) {
|
||||
isFloat[i] = (oper->children[i].type == SLANG_OPER_LITERAL_FLOAT ||
|
||||
oper->children[i].type == SLANG_OPER_LITERAL_INT);
|
||||
isBool[i] = (oper->children[i].type == SLANG_OPER_LITERAL_BOOL);
|
||||
}
|
||||
|
||||
if (oper->num_children == 2 && isFloat[0] && isFloat[1]) {
|
||||
/* probably simple arithmetic */
|
||||
switch (oper->type) {
|
||||
case SLANG_OPER_ADD:
|
||||
for (i = 0; i < 4; i++) {
|
||||
oper->literal[i]
|
||||
= oper->children[0].literal[i] + oper->children[1].literal[i];
|
||||
}
|
||||
oper->literal_size = oper->children[0].literal_size;
|
||||
oper->type = literal_type(oper->children[0].type,
|
||||
oper->children[1].type);
|
||||
slang_operation_destruct(oper); /* frees unused children */
|
||||
return;
|
||||
case SLANG_OPER_SUBTRACT:
|
||||
for (i = 0; i < 4; i++) {
|
||||
oper->literal[i]
|
||||
= oper->children[0].literal[i] - oper->children[1].literal[i];
|
||||
}
|
||||
oper->literal_size = oper->children[0].literal_size;
|
||||
oper->type = literal_type(oper->children[0].type,
|
||||
oper->children[1].type);
|
||||
slang_operation_destruct(oper);
|
||||
return;
|
||||
case SLANG_OPER_MULTIPLY:
|
||||
for (i = 0; i < 4; i++) {
|
||||
oper->literal[i]
|
||||
= oper->children[0].literal[i] * oper->children[1].literal[i];
|
||||
}
|
||||
oper->literal_size = oper->children[0].literal_size;
|
||||
oper->type = literal_type(oper->children[0].type,
|
||||
oper->children[1].type);
|
||||
slang_operation_destruct(oper);
|
||||
return;
|
||||
case SLANG_OPER_DIVIDE:
|
||||
for (i = 0; i < 4; i++) {
|
||||
oper->literal[i]
|
||||
= oper->children[0].literal[i] / oper->children[1].literal[i];
|
||||
}
|
||||
oper->literal_size = oper->children[0].literal_size;
|
||||
oper->type = literal_type(oper->children[0].type,
|
||||
oper->children[1].type);
|
||||
slang_operation_destruct(oper);
|
||||
return;
|
||||
default:
|
||||
; /* nothing */
|
||||
}
|
||||
}
|
||||
|
||||
if (oper->num_children == 1 && isFloat[0]) {
|
||||
switch (oper->type) {
|
||||
case SLANG_OPER_MINUS:
|
||||
for (i = 0; i < 4; i++) {
|
||||
oper->literal[i] = -oper->children[0].literal[i];
|
||||
}
|
||||
oper->literal_size = oper->children[0].literal_size;
|
||||
slang_operation_destruct(oper);
|
||||
oper->type = SLANG_OPER_LITERAL_FLOAT;
|
||||
return;
|
||||
case SLANG_OPER_PLUS:
|
||||
COPY_4V(oper->literal, oper->children[0].literal);
|
||||
oper->literal_size = oper->children[0].literal_size;
|
||||
slang_operation_destruct(oper);
|
||||
oper->type = SLANG_OPER_LITERAL_FLOAT;
|
||||
return;
|
||||
default:
|
||||
; /* nothing */
|
||||
}
|
||||
}
|
||||
|
||||
if (oper->num_children == 2 && isBool[0] && isBool[1]) {
|
||||
/* simple boolean expression */
|
||||
switch (oper->type) {
|
||||
case SLANG_OPER_LOGICALAND:
|
||||
for (i = 0; i < 4; i++) {
|
||||
const GLint a = oper->children[0].literal[i] ? 1 : 0;
|
||||
const GLint b = oper->children[1].literal[i] ? 1 : 0;
|
||||
oper->literal[i] = (GLfloat) (a && b);
|
||||
}
|
||||
oper->literal_size = oper->children[0].literal_size;
|
||||
slang_operation_destruct(oper);
|
||||
oper->type = SLANG_OPER_LITERAL_BOOL;
|
||||
return;
|
||||
case SLANG_OPER_LOGICALOR:
|
||||
for (i = 0; i < 4; i++) {
|
||||
const GLint a = oper->children[0].literal[i] ? 1 : 0;
|
||||
const GLint b = oper->children[1].literal[i] ? 1 : 0;
|
||||
oper->literal[i] = (GLfloat) (a || b);
|
||||
}
|
||||
oper->literal_size = oper->children[0].literal_size;
|
||||
slang_operation_destruct(oper);
|
||||
oper->type = SLANG_OPER_LITERAL_BOOL;
|
||||
return;
|
||||
case SLANG_OPER_LOGICALXOR:
|
||||
for (i = 0; i < 4; i++) {
|
||||
const GLint a = oper->children[0].literal[i] ? 1 : 0;
|
||||
const GLint b = oper->children[1].literal[i] ? 1 : 0;
|
||||
oper->literal[i] = (GLfloat) (a ^ b);
|
||||
}
|
||||
oper->literal_size = oper->children[0].literal_size;
|
||||
slang_operation_destruct(oper);
|
||||
oper->type = SLANG_OPER_LITERAL_BOOL;
|
||||
return;
|
||||
default:
|
||||
; /* nothing */
|
||||
}
|
||||
}
|
||||
|
||||
if (oper->num_children == 4
|
||||
&& isFloat[0] && isFloat[1] && isFloat[2] && isFloat[3]) {
|
||||
/* vec4(flt, flt, flt, flt) constructor */
|
||||
if (oper->type == SLANG_OPER_CALL) {
|
||||
if (strcmp((char *) oper->a_id, "vec4") == 0) {
|
||||
oper->literal[0] = oper->children[0].literal[0];
|
||||
oper->literal[1] = oper->children[1].literal[0];
|
||||
oper->literal[2] = oper->children[2].literal[0];
|
||||
oper->literal[3] = oper->children[3].literal[0];
|
||||
oper->literal_size = 4;
|
||||
slang_operation_destruct(oper);
|
||||
oper->type = SLANG_OPER_LITERAL_FLOAT;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (oper->num_children == 3 && isFloat[0] && isFloat[1] && isFloat[2]) {
|
||||
/* vec3(flt, flt, flt) constructor */
|
||||
if (oper->type == SLANG_OPER_CALL) {
|
||||
if (strcmp((char *) oper->a_id, "vec3") == 0) {
|
||||
oper->literal[0] = oper->children[0].literal[0];
|
||||
oper->literal[1] = oper->children[1].literal[0];
|
||||
oper->literal[2] = oper->children[2].literal[0];
|
||||
oper->literal[3] = oper->literal[2];
|
||||
oper->literal_size = 3;
|
||||
slang_operation_destruct(oper);
|
||||
oper->type = SLANG_OPER_LITERAL_FLOAT;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (oper->num_children == 2 && isFloat[0] && isFloat[1]) {
|
||||
/* vec2(flt, flt) constructor */
|
||||
if (oper->type == SLANG_OPER_CALL) {
|
||||
if (strcmp((char *) oper->a_id, "vec2") == 0) {
|
||||
oper->literal[0] = oper->children[0].literal[0];
|
||||
oper->literal[1] = oper->children[1].literal[0];
|
||||
oper->literal[2] = oper->literal[1];
|
||||
oper->literal[3] = oper->literal[1];
|
||||
oper->literal_size = 2;
|
||||
slang_operation_destruct(oper); /* XXX oper->locals goes NULL! */
|
||||
oper->type = SLANG_OPER_LITERAL_FLOAT;
|
||||
assert(oper->num_children == 0);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (oper->num_children == 1 && isFloat[0]) {
|
||||
/* vec2/3/4(flt, flt) constructor */
|
||||
if (oper->type == SLANG_OPER_CALL) {
|
||||
const char *func = (const char *) oper->a_id;
|
||||
if (strncmp(func, "vec", 3) == 0 && func[3] >= '2' && func[3] <= '4') {
|
||||
oper->literal[0] =
|
||||
oper->literal[1] =
|
||||
oper->literal[2] =
|
||||
oper->literal[3] = oper->children[0].literal[0];
|
||||
oper->literal_size = func[3] - '0';
|
||||
assert(oper->literal_size >= 2);
|
||||
assert(oper->literal_size <= 4);
|
||||
slang_operation_destruct(oper); /* XXX oper->locals goes NULL! */
|
||||
oper->type = SLANG_OPER_LITERAL_FLOAT;
|
||||
assert(oper->num_children == 0);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Insert casts to try to adapt actual parameters to formal parameters for a
|
||||
* function call when an exact match for the parameter types is not found.
|
||||
* Example:
|
||||
* void foo(int i, bool b) {}
|
||||
* x = foo(3.15, 9);
|
||||
* Gets translated into:
|
||||
* x = foo(int(3.15), bool(9))
|
||||
*/
|
||||
GLboolean
|
||||
_slang_cast_func_params(slang_operation *callOper, const slang_function *fun,
|
||||
const slang_name_space * space,
|
||||
slang_atom_pool * atoms, slang_info_log *log)
|
||||
{
|
||||
const GLboolean haveRetValue = _slang_function_has_return_value(fun);
|
||||
const int numParams = fun->param_count - haveRetValue;
|
||||
int i;
|
||||
int dbg = 0;
|
||||
|
||||
if (dbg)
|
||||
printf("Adapt call of %d args to func %s (%d params)\n",
|
||||
callOper->num_children, (char*) fun->header.a_name, numParams);
|
||||
|
||||
for (i = 0; i < numParams; i++) {
|
||||
slang_typeinfo argType;
|
||||
slang_variable *paramVar = fun->parameters->variables[i];
|
||||
|
||||
/* Get type of arg[i] */
|
||||
if (!slang_typeinfo_construct(&argType))
|
||||
return GL_FALSE;
|
||||
if (!_slang_typeof_operation(&callOper->children[i], space,
|
||||
&argType, atoms, log)) {
|
||||
slang_typeinfo_destruct(&argType);
|
||||
return GL_FALSE;
|
||||
}
|
||||
|
||||
/* see if arg type matches parameter type */
|
||||
if (!slang_type_specifier_equal(&argType.spec,
|
||||
¶mVar->type.specifier)) {
|
||||
/* need to adapt arg type to match param type */
|
||||
const char *constructorName =
|
||||
slang_type_specifier_type_to_string(paramVar->type.specifier.type);
|
||||
slang_operation *child = slang_operation_new(1);
|
||||
|
||||
if (dbg)
|
||||
printf("Need to adapt types of arg %d\n", i);
|
||||
|
||||
slang_operation_copy(child, &callOper->children[i]);
|
||||
child->locals->outer_scope = callOper->children[i].locals;
|
||||
|
||||
#if 0
|
||||
if (_slang_sizeof_type_specifier(&argType.spec) >
|
||||
_slang_sizeof_type_specifier(¶mVar->type.specifier)) {
|
||||
}
|
||||
#endif
|
||||
|
||||
callOper->children[i].type = SLANG_OPER_CALL;
|
||||
callOper->children[i].a_id = slang_atom_pool_atom(atoms, constructorName);
|
||||
callOper->children[i].num_children = 1;
|
||||
callOper->children[i].children = child;
|
||||
}
|
||||
|
||||
slang_typeinfo_destruct(&argType);
|
||||
}
|
||||
|
||||
if (dbg) {
|
||||
printf("===== New call to %s with cast arguments ===============\n",
|
||||
(char*) fun->header.a_name);
|
||||
slang_print_tree(callOper, 5);
|
||||
}
|
||||
|
||||
return GL_TRUE;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Adapt the arguments for a function call to match the parameters of
|
||||
* the given function.
|
||||
* This is for:
|
||||
* 1. converting/casting argument types to match parameters
|
||||
* 2. breaking up vector/matrix types into individual components to
|
||||
* satisfy constructors.
|
||||
*/
|
||||
GLboolean
|
||||
_slang_adapt_call(slang_operation *callOper, const slang_function *fun,
|
||||
const slang_name_space * space,
|
||||
slang_atom_pool * atoms, slang_info_log *log)
|
||||
{
|
||||
const GLboolean haveRetValue = _slang_function_has_return_value(fun);
|
||||
const int numParams = fun->param_count - haveRetValue;
|
||||
int i;
|
||||
int dbg = 0;
|
||||
|
||||
if (dbg)
|
||||
printf("Adapt %d args to %d parameters for %s\n",
|
||||
callOper->num_children, numParams, (char *) fun->header.a_name);
|
||||
|
||||
/* Only try adapting for constructors */
|
||||
if (fun->kind != SLANG_FUNC_CONSTRUCTOR)
|
||||
return GL_FALSE;
|
||||
|
||||
if (callOper->num_children != numParams) {
|
||||
/* number of arguments doesn't match number of parameters */
|
||||
|
||||
/* For constructor calls, we can try to unroll vector/matrix args
|
||||
* into individual floats/ints and try to match the function params.
|
||||
*/
|
||||
for (i = 0; i < numParams; i++) {
|
||||
slang_typeinfo argType;
|
||||
GLint argSz, j;
|
||||
|
||||
/* Get type of arg[i] */
|
||||
if (!slang_typeinfo_construct(&argType))
|
||||
return GL_FALSE;
|
||||
if (!_slang_typeof_operation(&callOper->children[i], space,
|
||||
&argType, atoms, log)) {
|
||||
slang_typeinfo_destruct(&argType);
|
||||
return GL_FALSE;
|
||||
}
|
||||
|
||||
/*
|
||||
paramSz = _slang_sizeof_type_specifier(¶mVar->type.specifier);
|
||||
assert(paramSz == 1);
|
||||
*/
|
||||
argSz = _slang_sizeof_type_specifier(&argType.spec);
|
||||
if (argSz > 1) {
|
||||
slang_operation origArg;
|
||||
/* break up arg[i] into components */
|
||||
if (dbg)
|
||||
printf("Break up arg %d from 1 to %d elements\n", i, argSz);
|
||||
|
||||
slang_operation_construct(&origArg);
|
||||
slang_operation_copy(&origArg, &callOper->children[i]);
|
||||
|
||||
/* insert argSz-1 new children/args */
|
||||
for (j = 0; j < argSz - 1; j++) {
|
||||
(void) slang_operation_insert(&callOper->num_children,
|
||||
&callOper->children, i);
|
||||
}
|
||||
|
||||
/* replace arg[i+j] with subscript/index oper */
|
||||
for (j = 0; j < argSz; j++) {
|
||||
callOper->children[i + j].type = SLANG_OPER_SUBSCRIPT;
|
||||
callOper->children[i + j].locals = _slang_variable_scope_new(callOper->locals);
|
||||
callOper->children[i + j].num_children = 2;
|
||||
callOper->children[i + j].children = slang_operation_new(2);
|
||||
slang_operation_copy(&callOper->children[i + j].children[0],
|
||||
&origArg);
|
||||
callOper->children[i + j].children[1].type
|
||||
= SLANG_OPER_LITERAL_INT;
|
||||
callOper->children[i + j].children[1].literal[0] = (GLfloat) j;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (callOper->num_children < (GLuint) numParams) {
|
||||
/* still not enough args for all params */
|
||||
return GL_FALSE;
|
||||
}
|
||||
else if (callOper->num_children > (GLuint) numParams) {
|
||||
/* now too many arguments */
|
||||
/* just truncate */
|
||||
callOper->num_children = (GLuint) numParams;
|
||||
}
|
||||
|
||||
if (dbg) {
|
||||
printf("===== New call to %s with adapted arguments ===============\n",
|
||||
(char*) fun->header.a_name);
|
||||
slang_print_tree(callOper, 5);
|
||||
}
|
||||
|
||||
return GL_TRUE;
|
||||
}
|
|
@ -1,57 +0,0 @@
|
|||
/*
|
||||
* Mesa 3-D graphics library
|
||||
* Version: 7.1
|
||||
*
|
||||
* Copyright (C) 2005-2008 Brian Paul All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included
|
||||
* in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
|
||||
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef SLANG_SIMPLIFY_H
|
||||
#define SLANG_SIMPLIFY_H
|
||||
|
||||
|
||||
#include "main/glheader.h"
|
||||
#include "slang_compile.h"
|
||||
#include "slang_compile_function.h"
|
||||
#include "slang_compile_operation.h"
|
||||
#include "slang_log.h"
|
||||
#include "slang_utility.h"
|
||||
|
||||
extern GLint
|
||||
_slang_lookup_constant(const char *name);
|
||||
|
||||
|
||||
extern void
|
||||
_slang_simplify(slang_operation *oper,
|
||||
const slang_name_space * space,
|
||||
slang_atom_pool * atoms);
|
||||
|
||||
|
||||
extern GLboolean
|
||||
_slang_cast_func_params(slang_operation *callOper, const slang_function *fun,
|
||||
const slang_name_space * space,
|
||||
slang_atom_pool * atoms, slang_info_log *log);
|
||||
|
||||
extern GLboolean
|
||||
_slang_adapt_call(slang_operation *callOper, const slang_function *fun,
|
||||
const slang_name_space * space,
|
||||
slang_atom_pool * atoms, slang_info_log *log);
|
||||
|
||||
|
||||
#endif /* SLANG_SIMPLIFY_H */
|
|
@ -1,321 +0,0 @@
|
|||
/*
|
||||
* Mesa 3-D graphics library
|
||||
* Version: 6.5
|
||||
*
|
||||
* Copyright (C) 2005-2006 Brian Paul All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included
|
||||
* in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
|
||||
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
/**
|
||||
* \file slang_storage.c
|
||||
* slang variable storage
|
||||
* \author Michal Krol
|
||||
*/
|
||||
|
||||
#include "main/imports.h"
|
||||
#include "slang_storage.h"
|
||||
#include "slang_mem.h"
|
||||
|
||||
/* slang_storage_array */
|
||||
|
||||
GLboolean
|
||||
slang_storage_array_construct(slang_storage_array * arr)
|
||||
{
|
||||
arr->type = SLANG_STORE_AGGREGATE;
|
||||
arr->aggregate = NULL;
|
||||
arr->length = 0;
|
||||
return GL_TRUE;
|
||||
}
|
||||
|
||||
GLvoid
|
||||
slang_storage_array_destruct(slang_storage_array * arr)
|
||||
{
|
||||
if (arr->aggregate != NULL) {
|
||||
slang_storage_aggregate_destruct(arr->aggregate);
|
||||
_slang_free(arr->aggregate);
|
||||
}
|
||||
}
|
||||
|
||||
/* slang_storage_aggregate */
|
||||
|
||||
GLboolean
|
||||
slang_storage_aggregate_construct(slang_storage_aggregate * agg)
|
||||
{
|
||||
agg->arrays = NULL;
|
||||
agg->count = 0;
|
||||
return GL_TRUE;
|
||||
}
|
||||
|
||||
GLvoid
|
||||
slang_storage_aggregate_destruct(slang_storage_aggregate * agg)
|
||||
{
|
||||
GLuint i;
|
||||
|
||||
for (i = 0; i < agg->count; i++)
|
||||
slang_storage_array_destruct(agg->arrays + i);
|
||||
_slang_free(agg->arrays);
|
||||
}
|
||||
|
||||
static slang_storage_array *
|
||||
slang_storage_aggregate_push_new(slang_storage_aggregate * agg)
|
||||
{
|
||||
slang_storage_array *arr = NULL;
|
||||
|
||||
agg->arrays = (slang_storage_array *)
|
||||
_slang_realloc(agg->arrays,
|
||||
agg->count * sizeof(slang_storage_array),
|
||||
(agg->count + 1) * sizeof(slang_storage_array));
|
||||
if (agg->arrays != NULL) {
|
||||
arr = agg->arrays + agg->count;
|
||||
if (!slang_storage_array_construct(arr))
|
||||
return NULL;
|
||||
agg->count++;
|
||||
}
|
||||
return arr;
|
||||
}
|
||||
|
||||
/* _slang_aggregate_variable() */
|
||||
|
||||
static GLboolean
|
||||
aggregate_vector(slang_storage_aggregate * agg, slang_storage_type basic_type,
|
||||
GLuint row_count)
|
||||
{
|
||||
slang_storage_array *arr = slang_storage_aggregate_push_new(agg);
|
||||
if (arr == NULL)
|
||||
return GL_FALSE;
|
||||
arr->type = basic_type;
|
||||
arr->length = row_count;
|
||||
return GL_TRUE;
|
||||
}
|
||||
|
||||
static GLboolean
|
||||
aggregate_matrix(slang_storage_aggregate * agg, slang_storage_type basic_type,
|
||||
GLuint columns, GLuint rows)
|
||||
{
|
||||
slang_storage_array *arr = slang_storage_aggregate_push_new(agg);
|
||||
if (arr == NULL)
|
||||
return GL_FALSE;
|
||||
arr->type = SLANG_STORE_AGGREGATE;
|
||||
arr->length = columns;
|
||||
arr->aggregate = (slang_storage_aggregate *)
|
||||
_slang_alloc(sizeof(slang_storage_aggregate));
|
||||
if (arr->aggregate == NULL)
|
||||
return GL_FALSE;
|
||||
if (!slang_storage_aggregate_construct(arr->aggregate)) {
|
||||
_slang_free(arr->aggregate);
|
||||
arr->aggregate = NULL;
|
||||
return GL_FALSE;
|
||||
}
|
||||
if (!aggregate_vector(arr->aggregate, basic_type, rows))
|
||||
return GL_FALSE;
|
||||
return GL_TRUE;
|
||||
}
|
||||
|
||||
|
||||
static GLboolean
|
||||
aggregate_variables(slang_storage_aggregate * agg,
|
||||
slang_variable_scope * vars, slang_function_scope * funcs,
|
||||
slang_struct_scope * structs,
|
||||
slang_variable_scope * globals,
|
||||
slang_atom_pool * atoms)
|
||||
{
|
||||
GLuint i;
|
||||
|
||||
for (i = 0; i < vars->num_variables; i++)
|
||||
if (!_slang_aggregate_variable(agg, &vars->variables[i]->type.specifier,
|
||||
vars->variables[i]->array_len, funcs,
|
||||
structs, globals, atoms))
|
||||
return GL_FALSE;
|
||||
return GL_TRUE;
|
||||
}
|
||||
|
||||
|
||||
GLboolean
|
||||
_slang_aggregate_variable(slang_storage_aggregate * agg,
|
||||
slang_type_specifier * spec, GLuint array_len,
|
||||
slang_function_scope * funcs,
|
||||
slang_struct_scope * structs,
|
||||
slang_variable_scope * vars,
|
||||
slang_atom_pool * atoms)
|
||||
{
|
||||
switch (spec->type) {
|
||||
case SLANG_SPEC_BOOL:
|
||||
return aggregate_vector(agg, SLANG_STORE_BOOL, 1);
|
||||
case SLANG_SPEC_BVEC2:
|
||||
return aggregate_vector(agg, SLANG_STORE_BOOL, 2);
|
||||
case SLANG_SPEC_BVEC3:
|
||||
return aggregate_vector(agg, SLANG_STORE_BOOL, 3);
|
||||
case SLANG_SPEC_BVEC4:
|
||||
return aggregate_vector(agg, SLANG_STORE_BOOL, 4);
|
||||
case SLANG_SPEC_INT:
|
||||
return aggregate_vector(agg, SLANG_STORE_INT, 1);
|
||||
case SLANG_SPEC_IVEC2:
|
||||
return aggregate_vector(agg, SLANG_STORE_INT, 2);
|
||||
case SLANG_SPEC_IVEC3:
|
||||
return aggregate_vector(agg, SLANG_STORE_INT, 3);
|
||||
case SLANG_SPEC_IVEC4:
|
||||
return aggregate_vector(agg, SLANG_STORE_INT, 4);
|
||||
case SLANG_SPEC_FLOAT:
|
||||
return aggregate_vector(agg, SLANG_STORE_FLOAT, 1);
|
||||
case SLANG_SPEC_VEC2:
|
||||
return aggregate_vector(agg, SLANG_STORE_FLOAT, 2);
|
||||
case SLANG_SPEC_VEC3:
|
||||
return aggregate_vector(agg, SLANG_STORE_FLOAT, 3);
|
||||
case SLANG_SPEC_VEC4:
|
||||
return aggregate_vector(agg, SLANG_STORE_FLOAT, 4);
|
||||
case SLANG_SPEC_MAT2:
|
||||
return aggregate_matrix(agg, SLANG_STORE_FLOAT, 2, 2);
|
||||
case SLANG_SPEC_MAT3:
|
||||
return aggregate_matrix(agg, SLANG_STORE_FLOAT, 3, 3);
|
||||
case SLANG_SPEC_MAT4:
|
||||
return aggregate_matrix(agg, SLANG_STORE_FLOAT, 4, 4);
|
||||
|
||||
case SLANG_SPEC_MAT23:
|
||||
return aggregate_matrix(agg, SLANG_STORE_FLOAT, 2, 3);
|
||||
case SLANG_SPEC_MAT32:
|
||||
return aggregate_matrix(agg, SLANG_STORE_FLOAT, 3, 2);
|
||||
case SLANG_SPEC_MAT24:
|
||||
return aggregate_matrix(agg, SLANG_STORE_FLOAT, 2, 4);
|
||||
case SLANG_SPEC_MAT42:
|
||||
return aggregate_matrix(agg, SLANG_STORE_FLOAT, 4, 2);
|
||||
case SLANG_SPEC_MAT34:
|
||||
return aggregate_matrix(agg, SLANG_STORE_FLOAT, 3, 4);
|
||||
case SLANG_SPEC_MAT43:
|
||||
return aggregate_matrix(agg, SLANG_STORE_FLOAT, 4, 3);
|
||||
|
||||
case SLANG_SPEC_SAMPLER_1D:
|
||||
case SLANG_SPEC_SAMPLER_2D:
|
||||
case SLANG_SPEC_SAMPLER_3D:
|
||||
case SLANG_SPEC_SAMPLER_CUBE:
|
||||
case SLANG_SPEC_SAMPLER_1D_SHADOW:
|
||||
case SLANG_SPEC_SAMPLER_2D_SHADOW:
|
||||
case SLANG_SPEC_SAMPLER_RECT:
|
||||
case SLANG_SPEC_SAMPLER_RECT_SHADOW:
|
||||
case SLANG_SPEC_SAMPLER_1D_ARRAY:
|
||||
case SLANG_SPEC_SAMPLER_2D_ARRAY:
|
||||
case SLANG_SPEC_SAMPLER_1D_ARRAY_SHADOW:
|
||||
case SLANG_SPEC_SAMPLER_2D_ARRAY_SHADOW:
|
||||
|
||||
return aggregate_vector(agg, SLANG_STORE_INT, 1);
|
||||
case SLANG_SPEC_STRUCT:
|
||||
return aggregate_variables(agg, spec->_struct->fields, funcs, structs,
|
||||
vars, atoms);
|
||||
case SLANG_SPEC_ARRAY:
|
||||
{
|
||||
slang_storage_array *arr;
|
||||
|
||||
arr = slang_storage_aggregate_push_new(agg);
|
||||
if (arr == NULL)
|
||||
return GL_FALSE;
|
||||
arr->type = SLANG_STORE_AGGREGATE;
|
||||
arr->aggregate = (slang_storage_aggregate *)
|
||||
_slang_alloc(sizeof(slang_storage_aggregate));
|
||||
if (arr->aggregate == NULL)
|
||||
return GL_FALSE;
|
||||
if (!slang_storage_aggregate_construct(arr->aggregate)) {
|
||||
_slang_free(arr->aggregate);
|
||||
arr->aggregate = NULL;
|
||||
return GL_FALSE;
|
||||
}
|
||||
if (!_slang_aggregate_variable(arr->aggregate, spec->_array, 0,
|
||||
funcs, structs, vars, atoms))
|
||||
return GL_FALSE;
|
||||
arr->length = array_len;
|
||||
/* TODO: check if 0 < arr->length <= 65535 */
|
||||
}
|
||||
return GL_TRUE;
|
||||
default:
|
||||
return GL_FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
GLuint
|
||||
_slang_sizeof_type(slang_storage_type type)
|
||||
{
|
||||
if (type == SLANG_STORE_AGGREGATE)
|
||||
return 0;
|
||||
if (type == SLANG_STORE_VEC4)
|
||||
return 4 * sizeof(GLfloat);
|
||||
return sizeof(GLfloat);
|
||||
}
|
||||
|
||||
|
||||
GLuint
|
||||
_slang_sizeof_aggregate(const slang_storage_aggregate * agg)
|
||||
{
|
||||
GLuint i, size = 0;
|
||||
|
||||
for (i = 0; i < agg->count; i++) {
|
||||
slang_storage_array *arr = &agg->arrays[i];
|
||||
GLuint element_size;
|
||||
|
||||
if (arr->type == SLANG_STORE_AGGREGATE)
|
||||
element_size = _slang_sizeof_aggregate(arr->aggregate);
|
||||
else
|
||||
element_size = _slang_sizeof_type(arr->type);
|
||||
size += element_size * arr->length;
|
||||
}
|
||||
return size;
|
||||
}
|
||||
|
||||
|
||||
#if 0
|
||||
GLboolean
|
||||
_slang_flatten_aggregate(slang_storage_aggregate * flat,
|
||||
const slang_storage_aggregate * agg)
|
||||
{
|
||||
GLuint i;
|
||||
|
||||
for (i = 0; i < agg->count; i++) {
|
||||
GLuint j;
|
||||
|
||||
for (j = 0; j < agg->arrays[i].length; j++) {
|
||||
if (agg->arrays[i].type == SLANG_STORE_AGGREGATE) {
|
||||
if (!_slang_flatten_aggregate(flat, agg->arrays[i].aggregate))
|
||||
return GL_FALSE;
|
||||
}
|
||||
else {
|
||||
GLuint k, count;
|
||||
slang_storage_type type;
|
||||
|
||||
if (agg->arrays[i].type == SLANG_STORE_VEC4) {
|
||||
count = 4;
|
||||
type = SLANG_STORE_FLOAT;
|
||||
}
|
||||
else {
|
||||
count = 1;
|
||||
type = agg->arrays[i].type;
|
||||
}
|
||||
|
||||
for (k = 0; k < count; k++) {
|
||||
slang_storage_array *arr;
|
||||
|
||||
arr = slang_storage_aggregate_push_new(flat);
|
||||
if (arr == NULL)
|
||||
return GL_FALSE;
|
||||
arr->type = type;
|
||||
arr->length = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return GL_TRUE;
|
||||
}
|
||||
#endif
|
|
@ -1,144 +0,0 @@
|
|||
/*
|
||||
* Mesa 3-D graphics library
|
||||
* Version: 6.5
|
||||
*
|
||||
* Copyright (C) 2005-2006 Brian Paul All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included
|
||||
* in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
|
||||
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef SLANG_STORAGE_H
|
||||
#define SLANG_STORAGE_H
|
||||
|
||||
#include "main/glheader.h"
|
||||
#include "slang_compile_function.h"
|
||||
#include "slang_compile_struct.h"
|
||||
#include "slang_compile_variable.h"
|
||||
#include "slang_typeinfo.h"
|
||||
#include "slang_utility.h"
|
||||
|
||||
|
||||
/*
|
||||
* Program variable data storage is kept completely transparent to the
|
||||
* front-end compiler. It is up to the back-end how the data is
|
||||
* actually allocated. The slang_storage_type enum provides the basic
|
||||
* information about how the memory is interpreted. This abstract
|
||||
* piece of memory is called a data slot. A data slot of a particular
|
||||
* type has a fixed size.
|
||||
*
|
||||
* For now, only the three basic types are supported, that is bool,
|
||||
* int and float. Other built-in types like vector or matrix can
|
||||
* easily be decomposed into a series of basic types.
|
||||
*
|
||||
* If the vec4 module is enabled, 4-component vectors of floats are
|
||||
* used when possible. 4x4 matrices are constructed of 4 vec4 slots.
|
||||
*/
|
||||
typedef enum slang_storage_type_
|
||||
{
|
||||
/* core */
|
||||
SLANG_STORE_AGGREGATE,
|
||||
SLANG_STORE_BOOL,
|
||||
SLANG_STORE_INT,
|
||||
SLANG_STORE_FLOAT,
|
||||
/* vec4 */
|
||||
SLANG_STORE_VEC4
|
||||
} slang_storage_type;
|
||||
|
||||
|
||||
/**
|
||||
* The slang_storage_array structure groups data slots of the same
|
||||
* type into an array. This array has a fixed length. Arrays are
|
||||
* required to have a size equal to the sum of sizes of its
|
||||
* elements. They are also required to support indirect
|
||||
* addressing. That is, if B references first data slot in the array,
|
||||
* S is the size of the data slot and I is the integral index that is
|
||||
* not known at compile time, B+I*S references I-th data slot.
|
||||
*
|
||||
* This structure is also used to break down built-in data types that
|
||||
* are not supported directly. Vectors, like vec3, are constructed
|
||||
* from arrays of their basic types. Matrices are formed of an array
|
||||
* of column vectors, which are in turn processed as other vectors.
|
||||
*/
|
||||
typedef struct slang_storage_array_
|
||||
{
|
||||
slang_storage_type type;
|
||||
struct slang_storage_aggregate_ *aggregate;
|
||||
GLuint length;
|
||||
} slang_storage_array;
|
||||
|
||||
GLboolean slang_storage_array_construct (slang_storage_array *);
|
||||
GLvoid slang_storage_array_destruct (slang_storage_array *);
|
||||
|
||||
|
||||
/**
|
||||
* The slang_storage_aggregate structure relaxes the indirect
|
||||
* addressing requirement for slang_storage_array
|
||||
* structure. Aggregates are always accessed statically - its member
|
||||
* addresses are well-known at compile time. For example, user-defined
|
||||
* types are implemented as aggregates. Aggregates can collect data of
|
||||
* a different type.
|
||||
*/
|
||||
typedef struct slang_storage_aggregate_
|
||||
{
|
||||
slang_storage_array *arrays;
|
||||
GLuint count;
|
||||
} slang_storage_aggregate;
|
||||
|
||||
GLboolean slang_storage_aggregate_construct (slang_storage_aggregate *);
|
||||
GLvoid slang_storage_aggregate_destruct (slang_storage_aggregate *);
|
||||
|
||||
|
||||
extern GLboolean
|
||||
_slang_aggregate_variable(slang_storage_aggregate *agg,
|
||||
slang_type_specifier *spec,
|
||||
GLuint array_len,
|
||||
slang_function_scope *funcs,
|
||||
slang_struct_scope *structs,
|
||||
slang_variable_scope *vars,
|
||||
slang_atom_pool *atoms);
|
||||
|
||||
/*
|
||||
* Returns the size (in machine units) of the given storage type.
|
||||
* It is an error to pass-in SLANG_STORE_AGGREGATE.
|
||||
* Returns 0 on error.
|
||||
*/
|
||||
extern GLuint
|
||||
_slang_sizeof_type (slang_storage_type);
|
||||
|
||||
|
||||
/**
|
||||
* Returns total size (in machine units) of the given aggregate.
|
||||
* Returns 0 on error.
|
||||
*/
|
||||
extern GLuint
|
||||
_slang_sizeof_aggregate (const slang_storage_aggregate *);
|
||||
|
||||
|
||||
#if 0
|
||||
/**
|
||||
* Converts structured aggregate to a flat one, with arrays of generic
|
||||
* type being one-element long. Returns GL_TRUE on success. Returns
|
||||
* GL_FALSE otherwise.
|
||||
*/
|
||||
extern GLboolean
|
||||
_slang_flatten_aggregate (slang_storage_aggregate *,
|
||||
const slang_storage_aggregate *);
|
||||
|
||||
#endif
|
||||
|
||||
#endif /* SLANG_STORAGE_H */
|
File diff suppressed because it is too large
Load Diff
|
@ -1,263 +0,0 @@
|
|||
/*
|
||||
* Mesa 3-D graphics library
|
||||
* Version: 6.5
|
||||
*
|
||||
* Copyright (C) 2005-2006 Brian Paul All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included
|
||||
* in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
|
||||
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef SLANG_TYPEINFO_H
|
||||
#define SLANG_TYPEINFO_H 1
|
||||
|
||||
#include "main/glheader.h"
|
||||
#include "slang_log.h"
|
||||
#include "slang_utility.h"
|
||||
|
||||
|
||||
struct slang_operation_;
|
||||
|
||||
struct slang_name_space_;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Holds complete information about vector swizzle - the <swizzle>
|
||||
* array contains vector component source indices, where 0 is "x", 1
|
||||
* is "y", 2 is "z" and 3 is "w".
|
||||
* Example: "xwz" --> { 3, { 0, 3, 2, not used } }.
|
||||
*/
|
||||
typedef struct slang_swizzle_
|
||||
{
|
||||
GLuint num_components;
|
||||
GLuint swizzle[4];
|
||||
} slang_swizzle;
|
||||
|
||||
extern GLboolean
|
||||
_slang_is_swizzle(const char *field, GLuint rows, slang_swizzle *swz);
|
||||
|
||||
|
||||
typedef enum slang_type_variant_
|
||||
{
|
||||
SLANG_VARIANT, /* the default */
|
||||
SLANG_INVARIANT /* indicates the "invariant" keyword */
|
||||
} slang_type_variant;
|
||||
|
||||
|
||||
typedef enum slang_type_centroid_
|
||||
{
|
||||
SLANG_CENTER, /* the default */
|
||||
SLANG_CENTROID /* indicates the "centroid" keyword */
|
||||
} slang_type_centroid;
|
||||
|
||||
|
||||
/**
|
||||
* These only apply to gl_FragCoord, but other layout qualifiers may
|
||||
* appear in the future.
|
||||
*/
|
||||
typedef enum slang_layout_qualifier_
|
||||
{
|
||||
SLANG_LAYOUT_NONE = 0x0,
|
||||
SLANG_LAYOUT_UPPER_LEFT_BIT = 0x1,
|
||||
SLANG_LAYOUT_PIXEL_CENTER_INTEGER_BIT = 0x2
|
||||
} slang_layout_qualifier;
|
||||
|
||||
|
||||
typedef enum slang_type_qualifier_
|
||||
{
|
||||
SLANG_QUAL_NONE,
|
||||
SLANG_QUAL_CONST,
|
||||
SLANG_QUAL_ATTRIBUTE,
|
||||
SLANG_QUAL_VARYING,
|
||||
SLANG_QUAL_UNIFORM,
|
||||
SLANG_QUAL_OUT,
|
||||
SLANG_QUAL_INOUT,
|
||||
SLANG_QUAL_FIXEDOUTPUT, /* internal */
|
||||
SLANG_QUAL_FIXEDINPUT /* internal */
|
||||
} slang_type_qualifier;
|
||||
|
||||
typedef enum slang_varying_kind_
|
||||
{
|
||||
SLANG_VARYING_IN,
|
||||
SLANG_VARYING_OUT,
|
||||
} slang_varying_kind;
|
||||
|
||||
typedef enum slang_type_precision_
|
||||
{
|
||||
SLANG_PREC_DEFAULT,
|
||||
SLANG_PREC_LOW,
|
||||
SLANG_PREC_MEDIUM,
|
||||
SLANG_PREC_HIGH
|
||||
} slang_type_precision;
|
||||
|
||||
|
||||
/**
|
||||
* The basic shading language types (float, vec4, mat3, etc)
|
||||
*/
|
||||
typedef enum slang_type_specifier_type_
|
||||
{
|
||||
SLANG_SPEC_VOID,
|
||||
SLANG_SPEC_BOOL,
|
||||
SLANG_SPEC_BVEC2,
|
||||
SLANG_SPEC_BVEC3,
|
||||
SLANG_SPEC_BVEC4,
|
||||
SLANG_SPEC_INT,
|
||||
SLANG_SPEC_IVEC2,
|
||||
SLANG_SPEC_IVEC3,
|
||||
SLANG_SPEC_IVEC4,
|
||||
SLANG_SPEC_FLOAT,
|
||||
SLANG_SPEC_VEC2,
|
||||
SLANG_SPEC_VEC3,
|
||||
SLANG_SPEC_VEC4,
|
||||
SLANG_SPEC_MAT2,
|
||||
SLANG_SPEC_MAT3,
|
||||
SLANG_SPEC_MAT4,
|
||||
SLANG_SPEC_MAT23,
|
||||
SLANG_SPEC_MAT32,
|
||||
SLANG_SPEC_MAT24,
|
||||
SLANG_SPEC_MAT42,
|
||||
SLANG_SPEC_MAT34,
|
||||
SLANG_SPEC_MAT43,
|
||||
SLANG_SPEC_SAMPLER_1D,
|
||||
SLANG_SPEC_SAMPLER_2D,
|
||||
SLANG_SPEC_SAMPLER_3D,
|
||||
SLANG_SPEC_SAMPLER_CUBE,
|
||||
SLANG_SPEC_SAMPLER_RECT,
|
||||
SLANG_SPEC_SAMPLER_1D_SHADOW,
|
||||
SLANG_SPEC_SAMPLER_2D_SHADOW,
|
||||
SLANG_SPEC_SAMPLER_RECT_SHADOW,
|
||||
SLANG_SPEC_SAMPLER_1D_ARRAY,
|
||||
SLANG_SPEC_SAMPLER_2D_ARRAY,
|
||||
SLANG_SPEC_SAMPLER_1D_ARRAY_SHADOW,
|
||||
SLANG_SPEC_SAMPLER_2D_ARRAY_SHADOW,
|
||||
SLANG_SPEC_STRUCT,
|
||||
SLANG_SPEC_ARRAY
|
||||
} slang_type_specifier_type;
|
||||
|
||||
|
||||
extern slang_type_specifier_type
|
||||
slang_type_specifier_type_from_string(const char *);
|
||||
|
||||
extern const char *
|
||||
slang_type_specifier_type_to_string(slang_type_specifier_type);
|
||||
|
||||
|
||||
/**
|
||||
* Describes more sophisticated types, like structs and arrays.
|
||||
*/
|
||||
typedef struct slang_type_specifier_
|
||||
{
|
||||
slang_type_specifier_type type;
|
||||
struct slang_struct_ *_struct; /**< if type == SLANG_SPEC_STRUCT */
|
||||
struct slang_type_specifier_ *_array; /**< if type == SLANG_SPEC_ARRAY */
|
||||
} slang_type_specifier;
|
||||
|
||||
|
||||
extern GLvoid
|
||||
slang_type_specifier_ctr(slang_type_specifier *);
|
||||
|
||||
extern GLvoid
|
||||
slang_type_specifier_dtr(slang_type_specifier *);
|
||||
|
||||
extern slang_type_specifier *
|
||||
slang_type_specifier_new(slang_type_specifier_type type,
|
||||
struct slang_struct_ *_struct,
|
||||
struct slang_type_specifier_ *_array);
|
||||
|
||||
|
||||
extern GLboolean
|
||||
slang_type_specifier_copy(slang_type_specifier *, const slang_type_specifier *);
|
||||
|
||||
extern GLboolean
|
||||
slang_type_specifier_equal(const slang_type_specifier *,
|
||||
const slang_type_specifier *);
|
||||
|
||||
|
||||
extern GLboolean
|
||||
slang_type_specifier_compatible(const slang_type_specifier *x,
|
||||
const slang_type_specifier *y);
|
||||
|
||||
|
||||
typedef struct slang_fully_specified_type_
|
||||
{
|
||||
slang_type_qualifier qualifier;
|
||||
slang_type_specifier specifier;
|
||||
slang_type_precision precision;
|
||||
slang_type_variant variant;
|
||||
slang_type_centroid centroid;
|
||||
slang_layout_qualifier layout;
|
||||
GLint array_len; /**< -1 if not an array type */
|
||||
slang_varying_kind varying_kind;
|
||||
} slang_fully_specified_type;
|
||||
|
||||
extern int
|
||||
slang_fully_specified_type_construct(slang_fully_specified_type *);
|
||||
|
||||
extern void
|
||||
slang_fully_specified_type_destruct(slang_fully_specified_type *);
|
||||
|
||||
extern int
|
||||
slang_fully_specified_type_copy(slang_fully_specified_type *,
|
||||
const slang_fully_specified_type *);
|
||||
|
||||
GLboolean
|
||||
slang_fully_specified_types_compatible(const slang_fully_specified_type * x,
|
||||
const slang_fully_specified_type * y);
|
||||
|
||||
|
||||
typedef struct slang_typeinfo_
|
||||
{
|
||||
GLboolean can_be_referenced;
|
||||
GLboolean is_swizzled;
|
||||
slang_swizzle swz;
|
||||
slang_type_specifier spec;
|
||||
GLuint array_len;
|
||||
} slang_typeinfo;
|
||||
|
||||
extern GLboolean
|
||||
slang_typeinfo_construct(slang_typeinfo *);
|
||||
|
||||
extern GLvoid
|
||||
slang_typeinfo_destruct(slang_typeinfo *);
|
||||
|
||||
|
||||
extern GLboolean
|
||||
_slang_typeof_operation(struct slang_operation_ *,
|
||||
const struct slang_name_space_ *,
|
||||
slang_typeinfo *, slang_atom_pool *,
|
||||
slang_info_log *log);
|
||||
|
||||
extern GLboolean
|
||||
_slang_type_is_matrix(slang_type_specifier_type);
|
||||
|
||||
extern GLboolean
|
||||
_slang_type_is_vector(slang_type_specifier_type);
|
||||
|
||||
extern GLboolean
|
||||
_slang_type_is_float_vec_mat(slang_type_specifier_type);
|
||||
|
||||
extern slang_type_specifier_type
|
||||
_slang_type_base(slang_type_specifier_type);
|
||||
|
||||
extern GLuint
|
||||
_slang_type_dim(slang_type_specifier_type);
|
||||
|
||||
extern GLenum
|
||||
_slang_gltype_from_specifier(const slang_type_specifier *type);
|
||||
|
||||
#endif
|
|
@ -1,228 +0,0 @@
|
|||
/*
|
||||
* Mesa 3-D graphics library
|
||||
* Version: 6.5.3
|
||||
*
|
||||
* Copyright (C) 2005-2007 Brian Paul All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included
|
||||
* in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
|
||||
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
/**
|
||||
* \file slang_utility.c
|
||||
* slang utilities
|
||||
* \author Michal Krol
|
||||
*/
|
||||
|
||||
#include "main/imports.h"
|
||||
#include "slang_utility.h"
|
||||
#include "slang_mem.h"
|
||||
|
||||
char *
|
||||
slang_string_concat (char *dst, const char *src)
|
||||
{
|
||||
return strcpy (dst + strlen (dst), src);
|
||||
}
|
||||
|
||||
|
||||
/* slang_string */
|
||||
|
||||
GLvoid
|
||||
slang_string_init (slang_string *self)
|
||||
{
|
||||
self->data = NULL;
|
||||
self->capacity = 0;
|
||||
self->length = 0;
|
||||
self->fail = GL_FALSE;
|
||||
}
|
||||
|
||||
GLvoid
|
||||
slang_string_free (slang_string *self)
|
||||
{
|
||||
if (self->data != NULL)
|
||||
free(self->data);
|
||||
}
|
||||
|
||||
GLvoid
|
||||
slang_string_reset (slang_string *self)
|
||||
{
|
||||
self->length = 0;
|
||||
self->fail = GL_FALSE;
|
||||
}
|
||||
|
||||
static GLboolean
|
||||
grow (slang_string *self, GLuint size)
|
||||
{
|
||||
if (self->fail)
|
||||
return GL_FALSE;
|
||||
if (size > self->capacity) {
|
||||
/* do not overflow 32-bit range */
|
||||
assert (size < 0x80000000);
|
||||
|
||||
self->data = (char *) (_mesa_realloc (self->data, self->capacity, size * 2));
|
||||
self->capacity = size * 2;
|
||||
if (self->data == NULL) {
|
||||
self->capacity = 0;
|
||||
self->fail = GL_TRUE;
|
||||
return GL_FALSE;
|
||||
}
|
||||
}
|
||||
return GL_TRUE;
|
||||
}
|
||||
|
||||
GLvoid
|
||||
slang_string_push (slang_string *self, const slang_string *str)
|
||||
{
|
||||
if (str->fail) {
|
||||
self->fail = GL_TRUE;
|
||||
return;
|
||||
}
|
||||
if (grow (self, self->length + str->length)) {
|
||||
memcpy (&self->data[self->length], str->data, str->length);
|
||||
self->length += str->length;
|
||||
}
|
||||
}
|
||||
|
||||
GLvoid
|
||||
slang_string_pushc (slang_string *self, const char c)
|
||||
{
|
||||
if (grow (self, self->length + 1)) {
|
||||
self->data[self->length] = c;
|
||||
self->length++;
|
||||
}
|
||||
}
|
||||
|
||||
GLvoid
|
||||
slang_string_pushs (slang_string *self, const char *cstr, GLuint len)
|
||||
{
|
||||
if (grow (self, self->length + len)) {
|
||||
memcpy (&self->data[self->length], cstr, len);
|
||||
self->length += len;
|
||||
}
|
||||
}
|
||||
|
||||
GLvoid
|
||||
slang_string_pushi (slang_string *self, GLint i)
|
||||
{
|
||||
char buffer[12];
|
||||
|
||||
_mesa_snprintf (buffer, sizeof(buffer), "%d", i);
|
||||
slang_string_pushs (self, buffer, strlen (buffer));
|
||||
}
|
||||
|
||||
const char *
|
||||
slang_string_cstr (slang_string *self)
|
||||
{
|
||||
if (grow (self, self->length + 1))
|
||||
self->data[self->length] = '\0';
|
||||
return self->data;
|
||||
}
|
||||
|
||||
/* slang_atom_pool */
|
||||
|
||||
void
|
||||
slang_atom_pool_construct(slang_atom_pool * pool)
|
||||
{
|
||||
GLuint i;
|
||||
|
||||
for (i = 0; i < SLANG_ATOM_POOL_SIZE; i++)
|
||||
pool->entries[i] = NULL;
|
||||
}
|
||||
|
||||
void
|
||||
slang_atom_pool_destruct (slang_atom_pool * pool)
|
||||
{
|
||||
GLuint i;
|
||||
|
||||
for (i = 0; i < SLANG_ATOM_POOL_SIZE; i++) {
|
||||
slang_atom_entry * entry;
|
||||
|
||||
entry = pool->entries[i];
|
||||
while (entry != NULL) {
|
||||
slang_atom_entry *next = entry->next;
|
||||
_slang_free(entry->id);
|
||||
_slang_free(entry);
|
||||
entry = next;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Search the atom pool for an atom with a given name.
|
||||
* If atom is not found, create and add it to the pool.
|
||||
* Returns ATOM_NULL if the atom was not found and the function failed
|
||||
* to create a new atom.
|
||||
*/
|
||||
slang_atom
|
||||
slang_atom_pool_atom(slang_atom_pool * pool, const char * id)
|
||||
{
|
||||
GLuint hash;
|
||||
const char * p = id;
|
||||
slang_atom_entry ** entry;
|
||||
|
||||
/* Hash a given string to a number in the range [0, ATOM_POOL_SIZE). */
|
||||
hash = 0;
|
||||
while (*p != '\0') {
|
||||
GLuint g;
|
||||
|
||||
hash = (hash << 4) + (GLuint) (*p++);
|
||||
g = hash & 0xf0000000;
|
||||
if (g != 0)
|
||||
hash ^= g >> 24;
|
||||
hash &= ~g;
|
||||
}
|
||||
hash %= SLANG_ATOM_POOL_SIZE;
|
||||
|
||||
/* Now the hash points to a linked list of atoms with names that
|
||||
* have the same hash value. Search the linked list for a given
|
||||
* name.
|
||||
*/
|
||||
entry = &pool->entries[hash];
|
||||
while (*entry != NULL) {
|
||||
/* If the same, return the associated atom. */
|
||||
if (slang_string_compare((**entry).id, id) == 0)
|
||||
return (slang_atom) (**entry).id;
|
||||
/* Grab the next atom in the linked list. */
|
||||
entry = &(**entry).next;
|
||||
}
|
||||
|
||||
/* Okay, we have not found an atom. Create a new entry for it.
|
||||
* Note that the <entry> points to the last entry's <next> field.
|
||||
*/
|
||||
*entry = (slang_atom_entry *) _slang_alloc(sizeof(slang_atom_entry));
|
||||
if (*entry == NULL)
|
||||
return SLANG_ATOM_NULL;
|
||||
|
||||
/* Initialize a new entry. Because we'll need the actual name of
|
||||
* the atom, we use the pointer to this string as an actual atom's
|
||||
* value.
|
||||
*/
|
||||
(**entry).next = NULL;
|
||||
(**entry).id = _slang_strdup(id);
|
||||
if ((**entry).id == NULL)
|
||||
return SLANG_ATOM_NULL;
|
||||
return (slang_atom) (**entry).id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the name of a given atom.
|
||||
*/
|
||||
const char *
|
||||
slang_atom_pool_id(slang_atom_pool * pool, slang_atom atom)
|
||||
{
|
||||
return (const char *) (atom);
|
||||
}
|
|
@ -1,102 +0,0 @@
|
|||
/*
|
||||
* Mesa 3-D graphics library
|
||||
* Version: 6.5.3
|
||||
*
|
||||
* Copyright (C) 2005-2007 Brian Paul All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included
|
||||
* in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
|
||||
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef SLANG_UTILITY_H
|
||||
#define SLANG_UTILITY_H
|
||||
|
||||
|
||||
#include "main/glheader.h"
|
||||
|
||||
/* Compile-time assertions. If the expression is zero, try to declare an
|
||||
* array of size [-1] to cause compilation error.
|
||||
*/
|
||||
#define static_assert(expr) do { int _array[(expr) ? 1 : -1]; (void) _array[0]; } while (0)
|
||||
|
||||
|
||||
#define slang_string_compare(str1, str2) strcmp (str1, str2)
|
||||
#define slang_string_copy(dst, src) strcpy (dst, src)
|
||||
#define slang_string_length(str) strlen (str)
|
||||
|
||||
char *slang_string_concat (char *, const char *);
|
||||
|
||||
/* slang_string */
|
||||
|
||||
typedef struct
|
||||
{
|
||||
char *data;
|
||||
GLuint length;
|
||||
GLuint capacity;
|
||||
GLboolean fail;
|
||||
} slang_string;
|
||||
|
||||
GLvoid
|
||||
slang_string_init (slang_string *);
|
||||
|
||||
GLvoid
|
||||
slang_string_free (slang_string *);
|
||||
|
||||
GLvoid
|
||||
slang_string_reset (slang_string *);
|
||||
|
||||
GLvoid
|
||||
slang_string_push (slang_string *, const slang_string *);
|
||||
|
||||
GLvoid
|
||||
slang_string_pushc (slang_string *, const char);
|
||||
|
||||
GLvoid
|
||||
slang_string_pushs (slang_string *, const char *, GLuint);
|
||||
|
||||
GLvoid
|
||||
slang_string_pushi (slang_string *, GLint);
|
||||
|
||||
const char *
|
||||
slang_string_cstr (slang_string *);
|
||||
|
||||
/* slang_atom */
|
||||
|
||||
typedef GLvoid *slang_atom;
|
||||
|
||||
#define SLANG_ATOM_NULL ((slang_atom) 0)
|
||||
|
||||
typedef struct slang_atom_entry_
|
||||
{
|
||||
char *id;
|
||||
struct slang_atom_entry_ *next;
|
||||
} slang_atom_entry;
|
||||
|
||||
#define SLANG_ATOM_POOL_SIZE 1023
|
||||
|
||||
typedef struct slang_atom_pool_
|
||||
{
|
||||
slang_atom_entry *entries[SLANG_ATOM_POOL_SIZE];
|
||||
} slang_atom_pool;
|
||||
|
||||
GLvoid slang_atom_pool_construct (slang_atom_pool *);
|
||||
GLvoid slang_atom_pool_destruct (slang_atom_pool *);
|
||||
slang_atom slang_atom_pool_atom (slang_atom_pool *, const char *);
|
||||
const char *slang_atom_pool_id (slang_atom_pool *, slang_atom);
|
||||
|
||||
|
||||
#endif
|
|
@ -1,362 +0,0 @@
|
|||
|
||||
#include "main/imports.h"
|
||||
#include "program/program.h"
|
||||
#include "program/prog_print.h"
|
||||
#include "slang_compile.h"
|
||||
#include "slang_compile_variable.h"
|
||||
#include "slang_emit.h"
|
||||
#include "slang_mem.h"
|
||||
#include "slang_vartable.h"
|
||||
#include "slang_ir.h"
|
||||
|
||||
|
||||
static int dbg = 0;
|
||||
|
||||
|
||||
typedef enum {
|
||||
FREE,
|
||||
VAR,
|
||||
TEMP
|
||||
} TempState;
|
||||
|
||||
|
||||
/**
|
||||
* Variable/register info for one variable scope.
|
||||
*/
|
||||
struct table
|
||||
{
|
||||
int Level;
|
||||
int NumVars;
|
||||
slang_variable **Vars; /* array [NumVars] */
|
||||
|
||||
TempState Temps[MAX_PROGRAM_TEMPS * 4]; /* per-component state */
|
||||
int ValSize[MAX_PROGRAM_TEMPS * 4]; /**< For debug only */
|
||||
|
||||
struct table *Parent; /** Parent scope table */
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* A variable table is a stack of tables, one per scope.
|
||||
*/
|
||||
struct slang_var_table_
|
||||
{
|
||||
GLint CurLevel;
|
||||
GLuint MaxRegisters;
|
||||
struct table *Top; /**< Table at top of stack */
|
||||
};
|
||||
|
||||
|
||||
|
||||
slang_var_table *
|
||||
_slang_new_var_table(GLuint maxRegisters)
|
||||
{
|
||||
slang_var_table *vt
|
||||
= (slang_var_table *) _slang_alloc(sizeof(slang_var_table));
|
||||
if (vt) {
|
||||
vt->MaxRegisters = maxRegisters;
|
||||
}
|
||||
return vt;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
_slang_delete_var_table(slang_var_table *vt)
|
||||
{
|
||||
if (vt->Top) {
|
||||
_mesa_problem(NULL, "non-empty var table in _slang_delete_var_table()");
|
||||
return;
|
||||
}
|
||||
_slang_free(vt);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Create new table on top of vartable stack.
|
||||
* Used when we enter a {} block.
|
||||
*/
|
||||
void
|
||||
_slang_push_var_table(slang_var_table *vt)
|
||||
{
|
||||
struct table *t = (struct table *) _slang_alloc(sizeof(struct table));
|
||||
if (t) {
|
||||
t->Level = vt->CurLevel++;
|
||||
t->Parent = vt->Top;
|
||||
if (t->Parent) {
|
||||
/* copy the info indicating which temp regs are in use */
|
||||
memcpy(t->Temps, t->Parent->Temps, sizeof(t->Temps));
|
||||
memcpy(t->ValSize, t->Parent->ValSize, sizeof(t->ValSize));
|
||||
}
|
||||
vt->Top = t;
|
||||
if (dbg) printf("Pushing level %d\n", t->Level);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Pop top entry from variable table.
|
||||
* Used when we leave a {} block.
|
||||
*/
|
||||
void
|
||||
_slang_pop_var_table(slang_var_table *vt)
|
||||
{
|
||||
struct table *t = vt->Top;
|
||||
int i;
|
||||
|
||||
if (dbg) printf("Popping level %d\n", t->Level);
|
||||
|
||||
/* free the storage allocated for each variable */
|
||||
for (i = 0; i < t->NumVars; i++) {
|
||||
slang_ir_storage *store = t->Vars[i]->store;
|
||||
GLint j;
|
||||
GLuint comp;
|
||||
if (dbg) printf(" Free var %s, size %d at %d.%s\n",
|
||||
(char*) t->Vars[i]->a_name, store->Size,
|
||||
store->Index,
|
||||
_mesa_swizzle_string(store->Swizzle, 0, 0));
|
||||
|
||||
if (store->File == PROGRAM_SAMPLER) {
|
||||
/* samplers have no storage */
|
||||
continue;
|
||||
}
|
||||
|
||||
if (store->Size == 1)
|
||||
comp = GET_SWZ(store->Swizzle, 0);
|
||||
else
|
||||
comp = 0;
|
||||
|
||||
/* store->Index may be -1 if we run out of registers */
|
||||
if (store->Index >= 0) {
|
||||
for (j = 0; j < store->Size; j++) {
|
||||
assert(t->Temps[store->Index * 4 + j + comp] == VAR);
|
||||
t->Temps[store->Index * 4 + j + comp] = FREE;
|
||||
}
|
||||
}
|
||||
store->Index = -1;
|
||||
}
|
||||
if (t->Parent) {
|
||||
/* just verify that any remaining allocations in this scope
|
||||
* were for temps
|
||||
*/
|
||||
for (i = 0; i < (int) vt->MaxRegisters * 4; i++) {
|
||||
if (t->Temps[i] != FREE && t->Parent->Temps[i] == FREE) {
|
||||
if (dbg) printf(" Free reg %d\n", i/4);
|
||||
assert(t->Temps[i] == TEMP);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (t->Vars) {
|
||||
_slang_free(t->Vars);
|
||||
t->Vars = NULL;
|
||||
}
|
||||
|
||||
vt->Top = t->Parent;
|
||||
_slang_free(t);
|
||||
vt->CurLevel--;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Add a new variable to the given var/symbol table.
|
||||
*/
|
||||
void
|
||||
_slang_add_variable(slang_var_table *vt, slang_variable *v)
|
||||
{
|
||||
struct table *t;
|
||||
assert(vt);
|
||||
t = vt->Top;
|
||||
assert(t);
|
||||
if (dbg) printf("Adding var %s, store %p\n", (char *) v->a_name, (void *) v->store);
|
||||
t->Vars = (slang_variable **)
|
||||
_slang_realloc(t->Vars,
|
||||
t->NumVars * sizeof(slang_variable *),
|
||||
(t->NumVars + 1) * sizeof(slang_variable *));
|
||||
t->Vars[t->NumVars] = v;
|
||||
t->NumVars++;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Look for variable by name in given table.
|
||||
* If not found, Parent table will be searched.
|
||||
*/
|
||||
slang_variable *
|
||||
_slang_find_variable(const slang_var_table *vt, slang_atom name)
|
||||
{
|
||||
struct table *t = vt->Top;
|
||||
while (1) {
|
||||
int i;
|
||||
for (i = 0; i < t->NumVars; i++) {
|
||||
if (t->Vars[i]->a_name == name)
|
||||
return t->Vars[i];
|
||||
}
|
||||
if (t->Parent)
|
||||
t = t->Parent;
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Allocation helper.
|
||||
* \param size var size in floats
|
||||
* \return position for var, measured in floats
|
||||
*/
|
||||
static GLint
|
||||
alloc_reg(slang_var_table *vt, GLint size, GLboolean isTemp)
|
||||
{
|
||||
struct table *t = vt->Top;
|
||||
/* if size == 1, allocate anywhere, else, pos must be multiple of 4 */
|
||||
const GLuint step = (size == 1) ? 1 : 4;
|
||||
GLuint i, j;
|
||||
assert(size > 0); /* number of floats */
|
||||
|
||||
for (i = 0; i <= vt->MaxRegisters * 4 - size; i += step) {
|
||||
GLuint found = 0;
|
||||
for (j = 0; j < (GLuint) size; j++) {
|
||||
assert(i + j < 4 * MAX_PROGRAM_TEMPS);
|
||||
if (i + j < vt->MaxRegisters * 4 && t->Temps[i + j] == FREE) {
|
||||
found++;
|
||||
}
|
||||
else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (found == size) {
|
||||
/* found block of size free regs */
|
||||
if (size > 1)
|
||||
assert(i % 4 == 0);
|
||||
for (j = 0; j < (GLuint) size; j++) {
|
||||
assert(i + j < 4 * MAX_PROGRAM_TEMPS);
|
||||
t->Temps[i + j] = isTemp ? TEMP : VAR;
|
||||
}
|
||||
assert(i < MAX_PROGRAM_TEMPS * 4);
|
||||
t->ValSize[i] = size;
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
/* if we get here, we ran out of registers */
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Allocate temp register(s) for storing a variable.
|
||||
* \param size size needed, in floats
|
||||
* \param swizzle returns swizzle mask for accessing var in register
|
||||
* \return register allocated, or -1
|
||||
*/
|
||||
GLboolean
|
||||
_slang_alloc_var(slang_var_table *vt, slang_ir_storage *store)
|
||||
{
|
||||
struct table *t = vt->Top;
|
||||
int i;
|
||||
|
||||
if (store->File == PROGRAM_SAMPLER) {
|
||||
/* don't really allocate storage */
|
||||
store->Index = 0;
|
||||
return GL_TRUE;
|
||||
}
|
||||
|
||||
i = alloc_reg(vt, store->Size, GL_FALSE);
|
||||
if (i < 0)
|
||||
return GL_FALSE;
|
||||
|
||||
store->Index = i / 4;
|
||||
store->Swizzle = _slang_var_swizzle(store->Size, i % 4);
|
||||
|
||||
if (dbg)
|
||||
printf("Alloc var storage sz %d at %d.%s (level %d) store %p\n",
|
||||
store->Size, store->Index,
|
||||
_mesa_swizzle_string(store->Swizzle, 0, 0),
|
||||
t->Level,
|
||||
(void*) store);
|
||||
|
||||
return GL_TRUE;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Allocate temp register(s) for storing an unnamed intermediate value.
|
||||
*/
|
||||
GLboolean
|
||||
_slang_alloc_temp(slang_var_table *vt, slang_ir_storage *store)
|
||||
{
|
||||
struct table *t = vt->Top;
|
||||
const int i = alloc_reg(vt, store->Size, GL_TRUE);
|
||||
if (i < 0)
|
||||
return GL_FALSE;
|
||||
|
||||
assert(store->Index < 0);
|
||||
|
||||
store->Index = i / 4;
|
||||
store->Swizzle = _slang_var_swizzle(store->Size, i % 4);
|
||||
|
||||
if (dbg) printf("Alloc temp sz %d at %d.%s (level %d) store %p\n",
|
||||
store->Size, store->Index,
|
||||
_mesa_swizzle_string(store->Swizzle, 0, 0), t->Level,
|
||||
(void *) store);
|
||||
|
||||
return GL_TRUE;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
_slang_free_temp(slang_var_table *vt, slang_ir_storage *store)
|
||||
{
|
||||
struct table *t = vt->Top;
|
||||
GLuint i;
|
||||
GLint r = store->Index;
|
||||
assert(store->Size > 0);
|
||||
assert(r >= 0);
|
||||
assert((GLuint)r + store->Size <= vt->MaxRegisters * 4);
|
||||
if (dbg) printf("Free temp sz %d at %d.%s (level %d) store %p\n",
|
||||
store->Size, r,
|
||||
_mesa_swizzle_string(store->Swizzle, 0, 0),
|
||||
t->Level, (void *) store);
|
||||
if (store->Size == 1) {
|
||||
const GLuint comp = GET_SWZ(store->Swizzle, 0);
|
||||
/* we can actually fail some of these assertions because of the
|
||||
* troublesome IR_SWIZZLE handling.
|
||||
*/
|
||||
#if 0
|
||||
assert(store->Swizzle == MAKE_SWIZZLE4(comp, comp, comp, comp));
|
||||
assert(comp < 4);
|
||||
assert(t->ValSize[r * 4 + comp] == 1);
|
||||
#endif
|
||||
assert(t->Temps[r * 4 + comp] == TEMP);
|
||||
t->Temps[r * 4 + comp] = FREE;
|
||||
}
|
||||
else {
|
||||
/*assert(store->Swizzle == SWIZZLE_NOOP);*/
|
||||
assert(t->ValSize[r*4] == store->Size);
|
||||
for (i = 0; i < (GLuint) store->Size; i++) {
|
||||
assert(t->Temps[r * 4 + i] == TEMP);
|
||||
t->Temps[r * 4 + i] = FREE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
GLboolean
|
||||
_slang_is_temp(const slang_var_table *vt, const slang_ir_storage *store)
|
||||
{
|
||||
struct table *t = vt->Top;
|
||||
GLuint comp;
|
||||
assert(store->Index >= 0);
|
||||
assert(store->Index < (int) vt->MaxRegisters);
|
||||
if (store->Swizzle == SWIZZLE_NOOP)
|
||||
comp = 0;
|
||||
else
|
||||
comp = GET_SWZ(store->Swizzle, 0);
|
||||
|
||||
if (t->Temps[store->Index * 4 + comp] == TEMP)
|
||||
return GL_TRUE;
|
||||
else
|
||||
return GL_FALSE;
|
||||
}
|
|
@ -1,45 +0,0 @@
|
|||
|
||||
#ifndef SLANG_VARTABLE_H
|
||||
#define SLANG_VARTABLE_H
|
||||
|
||||
#include "main/glheader.h"
|
||||
#include "slang_utility.h"
|
||||
|
||||
struct slang_ir_storage_;
|
||||
|
||||
typedef struct slang_var_table_ slang_var_table;
|
||||
|
||||
struct slang_variable_;
|
||||
|
||||
extern slang_var_table *
|
||||
_slang_new_var_table(GLuint maxRegisters);
|
||||
|
||||
extern void
|
||||
_slang_delete_var_table(slang_var_table *vt);
|
||||
|
||||
extern void
|
||||
_slang_push_var_table(slang_var_table *parent);
|
||||
|
||||
extern void
|
||||
_slang_pop_var_table(slang_var_table *t);
|
||||
|
||||
extern void
|
||||
_slang_add_variable(slang_var_table *t, struct slang_variable_ *v);
|
||||
|
||||
extern struct slang_variable_ *
|
||||
_slang_find_variable(const slang_var_table *t, slang_atom name);
|
||||
|
||||
extern GLboolean
|
||||
_slang_alloc_var(slang_var_table *t, struct slang_ir_storage_ *store);
|
||||
|
||||
extern GLboolean
|
||||
_slang_alloc_temp(slang_var_table *t, struct slang_ir_storage_ *store);
|
||||
|
||||
extern void
|
||||
_slang_free_temp(slang_var_table *t, struct slang_ir_storage_ *store);
|
||||
|
||||
extern GLboolean
|
||||
_slang_is_temp(const slang_var_table *t, const struct slang_ir_storage_ *store);
|
||||
|
||||
|
||||
#endif /* SLANG_VARTABLE_H */
|
Loading…
Reference in New Issue