remove stray tab
[mesa.git] / src / mesa / shader / slang / slang_compile.c
index c49ab4a68dc1c7bc6f563a1fd96d22958be0e758..c459eb29e744a72baea680004c666cc59bf3a7f0 100644 (file)
  */
 
 #include "imports.h"
+#include "context.h"
+#include "program.h"
+#include "prog_parameter.h"
 #include "grammar_mesa.h"
+#include "slang_codegen.h"
 #include "slang_compile.h"
 #include "slang_preprocess.h"
 #include "slang_storage.h"
+#include "slang_error.h"
+#include "slang_emit.h"
+#include "slang_vartable.h"
+
+#include "slang_print.h"
 
 /*
  * This is a straightforward implementation of the slang front-end
@@ -90,7 +99,9 @@ _slang_code_object_ctr(slang_code_object * self)
    for (i = 0; i < SLANG_BUILTIN_TOTAL; i++)
       _slang_code_unit_ctr(&self->builtin[i], self);
    _slang_code_unit_ctr(&self->unit, self);
+#if 01
    _slang_assembly_file_ctr(&self->assembly);
+#endif
    slang_machine_ctr(&self->machine);
    self->varpool.next_addr = 0;
    slang_atom_pool_construct(&self->atompool);
@@ -108,7 +119,9 @@ _slang_code_object_dtr(slang_code_object * self)
    for (i = 0; i < SLANG_BUILTIN_TOTAL; i++)
       _slang_code_unit_dtr(&self->builtin[i]);
    _slang_code_unit_dtr(&self->unit);
+#if 01
    slang_assembly_file_destruct(&self->assembly);
+#endif
    slang_machine_dtr(&self->machine);
    slang_atom_pool_destruct(&self->atompool);
    slang_export_data_table_dtr(&self->expdata);
@@ -214,6 +227,7 @@ slang_info_log_memory(slang_info_log * log)
       log->dont_free_text = 1;
       log->text = out_of_memory;
    }
+   abort();
 }
 
 /* slang_parse_ctx */
@@ -225,6 +239,7 @@ typedef struct slang_parse_ctx_
    int parsing_builtin;
    GLboolean global_scope;   /**< Is object being declared a global? */
    slang_atom_pool *atoms;
+   slang_unit_type type;     /**< Vertex vs. Fragment */
 } slang_parse_ctx;
 
 /* slang_output_ctx */
@@ -237,6 +252,8 @@ typedef struct slang_output_ctx_
    slang_assembly_file *assembly;
    slang_var_pool *global_pool;
    slang_machine *machine;
+   struct gl_program *program;
+   slang_var_table *vartable;
 } slang_output_ctx;
 
 /* _slang_compile() */
@@ -673,7 +690,7 @@ parse_type_specifier(slang_parse_ctx * C, slang_output_ctx * O,
 
          stru = slang_struct_scope_find(O->structs, a_name, 1);
          if (stru == NULL) {
-            slang_info_log_error(C->L, "%s: undeclared type name.",
+            slang_info_log_error(C->L, "undeclared type name '%s'",
                                  slang_atom_pool_id(C->atoms, a_name));
             return 0;
          }
@@ -705,7 +722,9 @@ parse_fully_specified_type(slang_parse_ctx * C, slang_output_ctx * O,
 {
    if (!parse_type_qualifier(C, &type->qualifier))
       return 0;
-   return parse_type_specifier(C, O, &type->specifier);
+   if (!parse_type_specifier(C, O, &type->specifier))
+      return 0;
+   return 1;
 }
 
 /* operation */
@@ -782,32 +801,17 @@ parse_fully_specified_type(slang_parse_ctx * C, slang_output_ctx * O,
  * \param C  the parsing context
  * \param O  the output context
  * \param oper  the operation we're parsing
- * \param statment  which child of the operation is being parsed
+ * \param statement  indicates whether parsing a statement, or expression
  * \return 1 if success, 0 if error
  */
 static int
 parse_child_operation(slang_parse_ctx * C, slang_output_ctx * O,
-                      slang_operation * oper, unsigned int statement)
+                      slang_operation * oper, GLboolean statement)
 {
    slang_operation *ch;
 
    /* grow child array */
-   oper->children = (slang_operation *)
-      slang_alloc_realloc(oper->children,
-                          oper->num_children * sizeof(slang_operation),
-                          (oper->num_children + 1) * sizeof(slang_operation));
-   if (oper->children == NULL) {
-      slang_info_log_memory(C->L);
-      return 0;
-   }
-
-   ch = &oper->children[oper->num_children];
-   if (!slang_operation_construct(ch)) {
-      slang_info_log_memory(C->L);
-      return 0;
-   }
-   oper->num_children++;
-   /* XXX I guess the 0th "statement" is not really a statement? */
+   ch = slang_operation_grow(&oper->num_children, &oper->children);
    if (statement)
       return parse_statement(C, O, ch);
    return parse_expression(C, O, ch);
@@ -846,7 +850,7 @@ parse_statement(slang_parse_ctx * C, slang_output_ctx * O,
       /* local variable declaration, individual declarators are stored as
        * children identifiers
        */
-      oper->type = slang_oper_variable_decl;
+      oper->type = slang_oper_block_no_new_scope;
       {
          const unsigned int first_var = O->vars->num_variables;
 
@@ -859,25 +863,17 @@ parse_statement(slang_parse_ctx * C, slang_output_ctx * O,
             const unsigned int num_vars = O->vars->num_variables - first_var;
             unsigned int i;
 
-            oper->children = (slang_operation *)
-               slang_alloc_malloc(num_vars * sizeof(slang_operation));
+            oper->num_children = num_vars;
+            oper->children = slang_operation_new(num_vars);
             if (oper->children == NULL) {
                slang_info_log_memory(C->L);
                return 0;
             }
-            for (oper->num_children = 0; oper->num_children < num_vars;
-                 oper->num_children++) {
-               if (!slang_operation_construct
-                   (&oper->children[oper->num_children])) {
-                  slang_info_log_memory(C->L);
-                  return 0;
-               }
-            }
             for (i = first_var; i < O->vars->num_variables; i++) {
                slang_operation *o = &oper->children[i - first_var];
-               o->type = slang_oper_identifier;
+               o->type = slang_oper_variable_decl;
                o->locals->outer_scope = O->vars;
-               o->a_id = O->vars->variables[i].a_name;
+               o->a_id = O->vars->variables[i]->a_name;
             }
          }
       }
@@ -1042,18 +1038,27 @@ parse_expression(slang_parse_ctx * C, slang_output_ctx * O,
          op->type = slang_oper_literal_bool;
          if (!parse_number(C, &number))
             return 0;
-         op->literal = (GLfloat) number;
+         op->literal[0] =
+         op->literal[1] =
+         op->literal[2] =
+         op->literal[3] = (GLfloat) number;
          break;
       case OP_PUSH_INT:
          op->type = slang_oper_literal_int;
          if (!parse_number(C, &number))
             return 0;
-         op->literal = (GLfloat) number;
+         op->literal[0] =
+         op->literal[1] =
+         op->literal[2] =
+         op->literal[3] = (GLfloat) number;
          break;
       case OP_PUSH_FLOAT:
          op->type = slang_oper_literal_float;
-         if (!parse_float(C, &op->literal))
+         if (!parse_float(C, &op->literal[0]))
             return 0;
+         op->literal[1] =
+         op->literal[2] =
+         op->literal[3] = op->literal[0];
          break;
       case OP_PUSH_IDENTIFIER:
          op->type = slang_oper_identifier;
@@ -1480,6 +1485,20 @@ parse_function_prototype(slang_parse_ctx * C, slang_output_ctx * O,
          return 0;
    }
 
+#if 111
+   /* if the function returns a value, append a hidden __retVal 'out'
+    * parameter that corresponds to the return value.
+    */
+   if (_slang_function_has_return_value(func)) {
+      slang_variable *p = slang_variable_scope_grow(func->parameters);
+      slang_atom a_retVal = slang_atom_pool_atom(C->atoms, "__retVal");
+      assert(a_retVal);
+      p->a_name = a_retVal;
+      p->type = func->header.type;
+      p->type.qualifier = slang_qual_out;
+   }
+#endif
+
    /* function formal parameters and local variables share the same
     * scope, so save the information about param count in a seperate
     * place also link the scope to the global variable scope so when a
@@ -1488,6 +1507,7 @@ parse_function_prototype(slang_parse_ctx * C, slang_output_ctx * O,
     */
    func->param_count = func->parameters->num_variables;
    func->parameters->outer_scope = O->vars;
+
    return 1;
 }
 
@@ -1529,15 +1549,19 @@ parse_function_definition(slang_parse_ctx * C, slang_output_ctx * O,
 static GLboolean
 initialize_global(slang_assemble_ctx * A, slang_variable * var)
 {
+#if 01
    slang_assembly_file_restore_point point;
+#endif
    slang_machine mach;
    slang_assembly_local_info save_local = A->local;
    slang_operation op_id, op_assign;
    GLboolean result;
 
+#if 01
    /* save the current assembly */
    if (!slang_assembly_file_restore_point_save(A->file, &point))
       return GL_FALSE;
+#endif
 
    /* setup the machine */
    mach = *A->mach;
@@ -1560,13 +1584,13 @@ initialize_global(slang_assemble_ctx * A, slang_variable * var)
 
    /* put the variable into operation's scope */
    op_id.locals->variables =
-      (slang_variable *) slang_alloc_malloc(sizeof(slang_variable));
+      (slang_variable **) slang_alloc_malloc(sizeof(slang_variable *));
    if (op_id.locals->variables == NULL) {
       slang_operation_destruct(&op_id);
       return GL_FALSE;
    }
    op_id.locals->num_variables = 1;
-   op_id.locals->variables[0] = *var;
+   op_id.locals->variables[0] = var;
 
    /* construct the assignment expression */
    if (!slang_operation_construct(&op_assign)) {
@@ -1587,8 +1611,12 @@ initialize_global(slang_assemble_ctx * A, slang_variable * var)
    op_assign.children[0] = op_id;
    op_assign.children[1] = *var->initializer;
 
+#if 0 /* this should go away */
    /* insert the actual expression */
    result = _slang_assemble_operation(A, &op_assign, slang_ref_forbid);
+#else
+   result = 1;
+#endif
 
    /* carefully destroy the operations */
    op_assign.num_children = 0;
@@ -1604,12 +1632,16 @@ initialize_global(slang_assemble_ctx * A, slang_variable * var)
       return GL_FALSE;
 
    /* execute the expression */
+#if 0
    if (!_slang_execute2(A->file, &mach))
       return GL_FALSE;
+#endif
 
+#if 01
    /* restore the old assembly */
    if (!slang_assembly_file_restore_point_load(A->file, &point))
       return GL_FALSE;
+#endif
    A->local = save_local;
 
    /* now we copy the contents of the initialized variable back to the original machine */
@@ -1702,6 +1734,26 @@ parse_init_declarator(slang_parse_ctx * C, slang_output_ctx * O,
       return 0;
    }
 
+#if 1
+   if (C->global_scope) {
+      slang_assemble_ctx A;
+
+      A.file = O->assembly;
+      A.mach = O->machine;
+      A.atoms = C->atoms;
+      A.space.funcs = O->funs;
+      A.space.structs = O->structs;
+      A.space.vars = O->vars;
+      A.program = O->program;
+#if 0
+      A.codegen = O->codegen;
+#endif
+      A.vartable = O->vartable;
+
+      _slang_codegen_global_variable(&A, var, C->type);
+   }
+#endif
+
    /* allocate global address space for a variable with a known size */
    if (C->global_scope
        && !(var->type.specifier.type == slang_spec_array
@@ -1770,9 +1822,9 @@ parse_init_declarator_list(slang_parse_ctx * C, slang_output_ctx * O)
  * \param O  output context
  * \param definition if non-zero expect a definition, else a declaration
  * \param parsed_func_ret  returns the parsed function
- * \return 1 if success, 0 if failure
+ * \return GL_TRUE if success, GL_FALSE if failure
  */
-static int
+static GLboolean
 parse_function(slang_parse_ctx * C, slang_output_ctx * O, int definition,
                slang_function ** parsed_func_ret)
 {
@@ -1780,17 +1832,17 @@ parse_function(slang_parse_ctx * C, slang_output_ctx * O, int definition,
 
    /* parse function definition/declaration */
    if (!slang_function_construct(&parsed_func))
-      return 0;
+      return GL_FALSE;
    if (definition) {
       if (!parse_function_definition(C, O, &parsed_func)) {
          slang_function_destruct(&parsed_func);
-         return 0;
+         return GL_FALSE;
       }
    }
    else {
       if (!parse_function_prototype(C, O, &parsed_func)) {
          slang_function_destruct(&parsed_func);
-         return 0;
+         return GL_FALSE;
       }
    }
 
@@ -1800,7 +1852,7 @@ parse_function(slang_parse_ctx * C, slang_output_ctx * O, int definition,
     */
    found_func = slang_function_scope_find(O->funs, &parsed_func, 0);
    if (found_func == NULL) {
-      /* add the parsed function to the function list */
+      /* New function, add it to the function list */
       O->funs->functions =
          (slang_function *) slang_alloc_realloc(O->funs->functions,
                                                 O->funs->num_functions *
@@ -1810,7 +1862,7 @@ parse_function(slang_parse_ctx * C, slang_output_ctx * O, int definition,
       if (O->funs->functions == NULL) {
          slang_info_log_memory(C->L);
          slang_function_destruct(&parsed_func);
-         return 0;
+         return GL_FALSE;
       }
       O->funs->functions[O->funs->num_functions] = parsed_func;
       O->funs->num_functions++;
@@ -1819,6 +1871,7 @@ parse_function(slang_parse_ctx * C, slang_output_ctx * O, int definition,
       *parsed_func_ret = &O->funs->functions[O->funs->num_functions - 1];
    }
    else {
+      /* previously defined or declared */
       /* TODO: check function return type qualifiers and specifiers */
       if (definition) {
          if (found_func->body != NULL) {
@@ -1827,7 +1880,7 @@ parse_function(slang_parse_ctx * C, slang_output_ctx * O, int definition,
                                                     parsed_func.header.
                                                     a_name));
             slang_function_destruct(&parsed_func);
-            return 0;
+            return GL_FALSE;
          }
 
          /* destroy the existing function declaration and replace it
@@ -1857,10 +1910,37 @@ parse_function(slang_parse_ctx * C, slang_output_ctx * O, int definition,
       A.space.funcs = O->funs;
       A.space.structs = O->structs;
       A.space.vars = O->vars;
-      if (!_slang_assemble_function(&A, *parsed_func_ret))
-         return 0;
+      A.program = O->program;
+#if 0
+      A.codegen = O->codegen;
+#endif
+      A.vartable = O->vartable;
+
+      _slang_reset_error();
+
+#if 0
+      printf("*************** Assemble function %s ****\n", (char *) (*parsed_func_ret)->header.a_name);
+      slang_print_var_scope((*parsed_func_ret)->parameters,
+                            (*parsed_func_ret)->param_count);
+#endif
+
+#if 0
+      if (!_slang_assemble_function(&A, *parsed_func_ret)) {
+         /* propogate the error message back through the info log */
+         C->L->text = _mesa_strdup(_slang_error_text());
+         C->L->dont_free_text = GL_FALSE;
+         return GL_FALSE;
+      }
+#endif
+
+#if 0
+      printf("**************************************\n");
+#endif
+#if 1
+      _slang_codegen_function(&A, *parsed_func_ret);
+#endif
    }
-   return 1;
+   return GL_TRUE;
 }
 
 /* declaration */
@@ -1895,9 +1975,11 @@ parse_declaration(slang_parse_ctx * C, slang_output_ctx * O)
 #define EXTERNAL_DECLARATION 2
 
 static GLboolean
-parse_code_unit(slang_parse_ctx * C, slang_code_unit * unit)
+parse_code_unit(slang_parse_ctx * C, slang_code_unit * unit,
+                struct gl_program *program)
 {
    slang_output_ctx o;
+   GLboolean success;
 
    /* setup output context */
    o.funs = &unit->funs;
@@ -1906,6 +1988,8 @@ parse_code_unit(slang_parse_ctx * C, slang_code_unit * unit)
    o.assembly = &unit->object->assembly;
    o.global_pool = &unit->object->varpool;
    o.machine = &unit->object->machine;
+   o.program = program;
+   o.vartable = _slang_push_var_table(NULL);
 
    /* parse individual functions and declarations */
    while (*C->I != EXTERNAL_NULL) {
@@ -1913,27 +1997,33 @@ parse_code_unit(slang_parse_ctx * C, slang_code_unit * unit)
       case EXTERNAL_FUNCTION_DEFINITION:
          {
             slang_function *func;
-
-            if (!parse_function(C, &o, 1, &func))
-               return 0;
+            success = parse_function(C, &o, 1, &func);
          }
          break;
       case EXTERNAL_DECLARATION:
-         if (!parse_declaration(C, &o))
-            return 0;
+         success = parse_declaration(C, &o);
          break;
       default:
-         return 0;
+         success = GL_FALSE;
+      }
+
+      if (!success) {
+         /* xxx free codegen */
+         _slang_pop_var_table(o.vartable);
+         return GL_FALSE;
       }
    }
    C->I++;
-   return 1;
+
+   _slang_pop_var_table(o.vartable);
+   return GL_TRUE;
 }
 
 static GLboolean
 compile_binary(const byte * prod, slang_code_unit * unit,
                slang_unit_type type, slang_info_log * infolog,
-               slang_code_unit * builtin, slang_code_unit * downlink)
+               slang_code_unit * builtin, slang_code_unit * downlink,
+               struct gl_program *program)
 {
    slang_parse_ctx C;
 
@@ -1945,6 +2035,7 @@ compile_binary(const byte * prod, slang_code_unit * unit,
    C.parsing_builtin = (builtin == NULL);
    C.global_scope = GL_TRUE;
    C.atoms = &unit->object->atompool;
+   C.type = type;
 
    if (!check_revision(&C))
       return GL_FALSE;
@@ -1956,13 +2047,14 @@ compile_binary(const byte * prod, slang_code_unit * unit,
    }
 
    /* parse translation unit */
-   return parse_code_unit(&C, unit);
+   return parse_code_unit(&C, unit, program);
 }
 
 static GLboolean
 compile_with_grammar(grammar id, const char *source, slang_code_unit * unit,
                      slang_unit_type type, slang_info_log * infolog,
-                     slang_code_unit * builtin)
+                     slang_code_unit * builtin,
+                     struct gl_program *program)
 {
    byte *prod;
    GLuint size, start, version;
@@ -1987,8 +2079,9 @@ compile_with_grammar(grammar id, const char *source, slang_code_unit * unit,
    }
 
    /* Finally check the syntax and generate its binary representation. */
-   if (!grammar_fast_check
-       (id, (const byte *) (slang_string_cstr(&preprocessed)), &prod, &size,
+   if (!grammar_fast_check(id,
+                           (const byte *) (slang_string_cstr(&preprocessed)),
+                           &prod, &size,
         65536)) {
       char buf[1024];
       GLint pos;
@@ -1996,14 +2089,14 @@ compile_with_grammar(grammar id, const char *source, slang_code_unit * unit,
       slang_string_free(&preprocessed);
       grammar_get_last_error((byte *) (buf), sizeof(buf), &pos);
       slang_info_log_error(infolog, buf);
-      return GL_FALSE;
+      RETURN_ERROR("syntax error (possibly in library code)", 0);
    }
    slang_string_free(&preprocessed);
 
    /* Syntax is okay - translate it to internal representation. */
-   if (!compile_binary
-       (prod, unit, type, infolog, builtin,
-        &builtin[SLANG_BUILTIN_TOTAL - 1])) {
+   if (!compile_binary(prod, unit, type, infolog, builtin,
+                       &builtin[SLANG_BUILTIN_TOTAL - 1],
+                       program)) {
       grammar_alloc_free(prod);
       return GL_FALSE;
    }
@@ -2032,6 +2125,7 @@ static const byte slang_vertex_builtin_gc[] = {
 };
 
 #if defined(USE_X86_ASM) || defined(SLANG_X86)
+foo
 static const byte slang_builtin_vec4_gc[] = {
 #include "library/slang_builtin_vec4_gc.h"
 };
@@ -2039,7 +2133,8 @@ static const byte slang_builtin_vec4_gc[] = {
 
 static GLboolean
 compile_object(grammar * id, const char *source, slang_code_object * object,
-               slang_unit_type type, slang_info_log * infolog)
+               slang_unit_type type, slang_info_log * infolog,
+               struct gl_program *program)
 {
    slang_code_unit *builtins = NULL;
 
@@ -2067,64 +2162,92 @@ compile_object(grammar * id, const char *source, slang_code_object * object,
    /* if parsing user-specified shader, load built-in library */
    if (type == slang_unit_fragment_shader || type == slang_unit_vertex_shader) {
       /* compile core functionality first */
-      if (!compile_binary(slang_core_gc, &object->builtin[SLANG_BUILTIN_CORE],
-                          slang_unit_fragment_builtin, infolog, NULL, NULL))
+      if (!compile_binary(slang_core_gc,
+                          &object->builtin[SLANG_BUILTIN_CORE],
+                          slang_unit_fragment_builtin, infolog,
+                          NULL, NULL, NULL))
          return GL_FALSE;
 
       /* compile common functions and variables, link to core */
-      if (!compile_binary
-          (slang_common_builtin_gc, &object->builtin[SLANG_BUILTIN_COMMON],
-           slang_unit_fragment_builtin, infolog, NULL,
-           &object->builtin[SLANG_BUILTIN_CORE]))
+      if (!compile_binary(slang_common_builtin_gc,
+                          &object->builtin[SLANG_BUILTIN_COMMON],
+                          slang_unit_fragment_builtin, infolog, NULL,
+                          &object->builtin[SLANG_BUILTIN_CORE], NULL))
          return GL_FALSE;
 
       /* compile target-specific functions and variables, link to common */
       if (type == slang_unit_fragment_shader) {
-         if (!compile_binary
-             (slang_fragment_builtin_gc,
-              &object->builtin[SLANG_BUILTIN_TARGET],
-              slang_unit_fragment_builtin, infolog, NULL,
-              &object->builtin[SLANG_BUILTIN_COMMON]))
+         if (!compile_binary(slang_fragment_builtin_gc,
+                             &object->builtin[SLANG_BUILTIN_TARGET],
+                             slang_unit_fragment_builtin, infolog, NULL,
+                             &object->builtin[SLANG_BUILTIN_COMMON], NULL))
             return GL_FALSE;
       }
       else if (type == slang_unit_vertex_shader) {
-         if (!compile_binary
-             (slang_vertex_builtin_gc, &object->builtin[SLANG_BUILTIN_TARGET],
-              slang_unit_vertex_builtin, infolog, NULL,
-              &object->builtin[SLANG_BUILTIN_COMMON]))
+         if (!compile_binary(slang_vertex_builtin_gc,
+                             &object->builtin[SLANG_BUILTIN_TARGET],
+                             slang_unit_vertex_builtin, infolog, NULL,
+                             &object->builtin[SLANG_BUILTIN_COMMON], NULL))
             return GL_FALSE;
       }
 
 #if defined(USE_X86_ASM) || defined(SLANG_X86)
       /* compile x86 4-component vector overrides, link to target */
-      if (!compile_binary
-          (slang_builtin_vec4_gc, &object->builtin[SLANG_BUILTIN_VEC4],
-           slang_unit_fragment_builtin, infolog, NULL,
-           &object->builtin[SLANG_BUILTIN_TARGET]))
+      if (!compile_binary(slang_builtin_vec4_gc,
+                          &object->builtin[SLANG_BUILTIN_VEC4],
+                          slang_unit_fragment_builtin, infolog, NULL,
+                          &object->builtin[SLANG_BUILTIN_TARGET]))
          return GL_FALSE;
 #endif
 
       /* disable language extensions */
+#if NEW_SLANG /* allow-built-ins */
+      grammar_set_reg8(*id, (const byte *) "parsing_builtin", 1);
+#else
       grammar_set_reg8(*id, (const byte *) "parsing_builtin", 0);
+#endif
       builtins = object->builtin;
    }
 
    /* compile the actual shader - pass-in built-in library for external shader */
    return compile_with_grammar(*id, source, &object->unit, type, infolog,
-                               builtins);
+                               builtins, program);
 }
 
-GLboolean
-_slang_compile(const char *source, slang_code_object * object,
-               slang_unit_type type, slang_info_log * infolog)
+
+#if 0
+static void
+slang_create_uniforms(const slang_export_data_table *exports,
+                      struct gl_program *program)
+{
+   /* XXX only add uniforms that are actually going to get used */
+   GLuint i;
+   for (i = 0; i < exports->count; i++) {
+      if (exports->entries[i].access == slang_exp_uniform) {
+         const char *name = (char *) exports->entries[i].quant.name;
+         GLint j = _mesa_add_uniform(program->Parameters, name, 4);
+         assert(j >= 0);
+      }
+   }
+}
+#endif
+
+
+static GLboolean
+compile_shader(GLcontext *ctx, slang_code_object * object,
+               slang_unit_type type, slang_info_log * infolog,
+               struct gl_shader *shader)
 {
+   struct gl_program *program = shader->Programs[0];
    GLboolean success;
    grammar id = 0;
 
+   assert(program);
+
    _slang_code_object_dtr(object);
    _slang_code_object_ctr(object);
 
-   success = compile_object(&id, source, object, type, infolog);
+   success = compile_object(&id, shader->Source, object, type, infolog, program);
    if (id != 0)
       grammar_destroy(id);
    if (!success)
@@ -2132,17 +2255,82 @@ _slang_compile(const char *source, slang_code_object * object,
 
    if (!_slang_build_export_data_table(&object->expdata, &object->unit.vars))
       return GL_FALSE;
-   if (!_slang_build_export_code_table
-       (&object->expcode, &object->unit.funs, &object->unit))
+   if (!_slang_build_export_code_table(&object->expcode, &object->unit.funs,
+                                       &object->unit))
       return GL_FALSE;
 
-#if defined(USE_X86_ASM) || defined(SLANG_X86)
-   /* XXX: lookup the @main label */
-   if (!_slang_x86_codegen
-       (&object->machine, &object->assembly,
-        object->expcode.entries[0].address))
-      return GL_FALSE;
+#if NEW_SLANG
+   {
+      slang_create_uniforms(&object->expdata, shader);
+      _mesa_print_program(program);
+      _mesa_print_program_parameters(ctx, program);
+   }
 #endif
 
    return GL_TRUE;
 }
+
+
+
+GLboolean
+_slang_compile(GLcontext *ctx, struct gl_shader *shader)
+{
+   GLboolean success;
+   slang_info_log info_log;
+   slang_code_object obj;
+   slang_unit_type type;
+
+   if (shader->Type == GL_VERTEX_SHADER) {
+      type = slang_unit_vertex_shader;
+   }
+   else {
+      assert(shader->Type == GL_FRAGMENT_SHADER);
+      type = slang_unit_fragment_shader;
+   }
+
+   /* XXX temporary hack */
+   if (!shader->Programs) {
+      GLenum progTarget;
+      if (shader->Type == GL_VERTEX_SHADER)
+         progTarget = GL_VERTEX_PROGRAM_ARB;
+      else
+         progTarget = GL_FRAGMENT_PROGRAM_ARB;
+      shader->Programs
+         = (struct gl_program **) malloc(sizeof(struct gl_program*));
+      shader->Programs[0] = _mesa_new_program(ctx, progTarget, 1);
+      shader->NumPrograms = 1;
+
+      shader->Programs[0]->Parameters = _mesa_new_parameter_list();
+      shader->Programs[0]->Varying = _mesa_new_parameter_list();
+      shader->Programs[0]->Attributes = _mesa_new_parameter_list();
+   }
+
+   slang_info_log_construct(&info_log);
+   _slang_code_object_ctr(&obj);
+
+   success = compile_shader(ctx, &obj, type, &info_log, shader);
+
+   if (success) {
+#if 0
+      slang_create_uniforms(&object->expdata, shader);
+      _mesa_print_program(program);
+      _mesa_print_program_parameters(ctx, program);
+#endif
+   }
+   else {
+      /* XXX more work on info log needed here */
+      if (info_log.text) {
+         if (shader->InfoLog) {
+            free(shader->InfoLog);
+            shader->InfoLog = NULL;
+         }
+         shader->InfoLog = strdup(info_log.text);
+      }
+   }
+
+   slang_info_log_destruct(&info_log);
+   _slang_code_object_dtr(&obj);
+
+   return success;
+}
+