Get it running for ARB_vertex_shader.
authorMichal Krol <mjkrol@gmail.org>
Mon, 13 Feb 2006 11:38:37 +0000 (11:38 +0000)
committerMichal Krol <mjkrol@gmail.org>
Mon, 13 Feb 2006 11:38:37 +0000 (11:38 +0000)
Add experimental print functions to builtin library.
Some functionality missing:
- automatic arrays;
- general constructors;
- local variable initialization;
- texture sampling and noise;
- semantic error checking;
- function prototypes.

27 files changed:
src/mesa/shader/slang/slang_assemble.c
src/mesa/shader/slang/slang_assemble.h
src/mesa/shader/slang/slang_assemble_assignment.c
src/mesa/shader/slang/slang_assemble_assignment.h
src/mesa/shader/slang/slang_assemble_conditional.c
src/mesa/shader/slang/slang_assemble_conditional.h
src/mesa/shader/slang/slang_assemble_constructor.c
src/mesa/shader/slang/slang_assemble_constructor.h
src/mesa/shader/slang/slang_assemble_typeinfo.c
src/mesa/shader/slang/slang_assemble_typeinfo.h
src/mesa/shader/slang/slang_compile.c
src/mesa/shader/slang/slang_compile.h
src/mesa/shader/slang/slang_compile_function.c
src/mesa/shader/slang/slang_compile_function.h
src/mesa/shader/slang/slang_compile_operation.c
src/mesa/shader/slang/slang_compile_operation.h
src/mesa/shader/slang/slang_compile_struct.c
src/mesa/shader/slang/slang_compile_struct.h
src/mesa/shader/slang/slang_compile_variable.c
src/mesa/shader/slang/slang_compile_variable.h
src/mesa/shader/slang/slang_execute.c
src/mesa/shader/slang/slang_execute.h
src/mesa/shader/slang/slang_preprocess.c
src/mesa/shader/slang/slang_storage.c
src/mesa/shader/slang/slang_storage.h
src/mesa/shader/slang/slang_utility.c
src/mesa/shader/slang/slang_utility.h

index a97da6b..45b6b19 100644 (file)
 #include "imports.h"\r
 #include "slang_utility.h"\r
 #include "slang_assemble.h"\r
-#include "slang_compile.h"\r
+/*#include "slang_compile.h"*/\r
 #include "slang_storage.h"\r
-#include "slang_assemble_constructor.h"\r
+/*#include "slang_assemble_constructor.h"*/\r
 #include "slang_assemble_typeinfo.h"\r
 #include "slang_assemble_conditional.h"\r
 #include "slang_assemble_assignment.h"\r
+#include "slang_execute.h"\r
 \r
 /* slang_assembly */\r
 \r
-static void slang_assembly_construct (slang_assembly *assem)\r
+static int slang_assembly_construct (slang_assembly *assem)\r
 {\r
        assem->type = slang_asm_none;\r
+       return 1;\r
 }\r
 \r
 static void slang_assembly_destruct (slang_assembly *assem)\r
@@ -51,10 +53,12 @@ static void slang_assembly_destruct (slang_assembly *assem)
 \r
 /* slang_assembly_file */\r
 \r
-void slang_assembly_file_construct (slang_assembly_file *file)\r
+int slang_assembly_file_construct (slang_assembly_file *file)\r
 {\r
        file->code = NULL;\r
        file->count = 0;\r
+       file->capacity = 0;\r
+       return 1;\r
 }\r
 \r
 void slang_assembly_file_destruct (slang_assembly_file *file)\r
@@ -62,30 +66,40 @@ void slang_assembly_file_destruct (slang_assembly_file *file)
        unsigned int i;\r
 \r
        for (i = 0; i < file->count; i++)\r
-               slang_assembly_destruct (file->code + i);\r
+               slang_assembly_destruct (&file->code[i]);\r
        slang_alloc_free (file->code);\r
 }\r
 \r
-static int slang_assembly_file_push_new (slang_assembly_file *file)\r
+static int push_new (slang_assembly_file *file)\r
 {\r
-       file->code = (slang_assembly *) slang_alloc_realloc (file->code, file->count * sizeof (\r
-               slang_assembly), (file->count + 1) * sizeof (slang_assembly));\r
-       if (file->code != NULL)\r
+       if (file->count == file->capacity)\r
        {\r
-               slang_assembly_construct (file->code + file->count);\r
-               file->count++;\r
-               return 1;\r
+               unsigned int n;\r
+\r
+               if (file->capacity == 0)\r
+                       n = 256;\r
+               else\r
+                       n = file->capacity * 2;\r
+               file->code = (slang_assembly *) slang_alloc_realloc (file->code,\r
+                       file->capacity * sizeof (slang_assembly), n * sizeof (slang_assembly));\r
+               if (file->code == NULL)\r
+                       return 0;\r
+               file->capacity = n;\r
        }\r
-       return 0;\r
+       if (!slang_assembly_construct (&file->code[file->count]))\r
+               return 0;\r
+       file->count++;\r
+       return 1;\r
 }\r
 \r
-static int slang_assembly_file_push_general (slang_assembly_file *file, slang_assembly_type type,\r
-       GLfloat literal, GLuint label, GLuint size)\r
+static int push_gen (slang_assembly_file *file, slang_assembly_type type, GLfloat literal,\r
+       GLuint label, GLuint size)\r
 {\r
        slang_assembly *assem;\r
-       if (!slang_assembly_file_push_new (file))\r
+\r
+       if (!push_new (file))\r
                return 0;\r
-       assem = file->code + file->count - 1;\r
+       assem = &file->code[file->count - 1];\r
        assem->type = type;\r
        assem->literal = literal;\r
        assem->param[0] = label;\r
@@ -95,102 +109,138 @@ static int slang_assembly_file_push_general (slang_assembly_file *file, slang_as
 \r
 int slang_assembly_file_push (slang_assembly_file *file, slang_assembly_type type)\r
 {\r
-       return slang_assembly_file_push_general (file, type, (GLfloat) 0, 0, 0);\r
+       return push_gen (file, type, (GLfloat) 0, 0, 0);\r
 }\r
 \r
 int slang_assembly_file_push_label (slang_assembly_file *file, slang_assembly_type type,\r
        GLuint label)\r
 {\r
-       return slang_assembly_file_push_general (file, type, (GLfloat) 0, label, 0);\r
+       return push_gen (file, type, (GLfloat) 0, label, 0);\r
 }\r
 \r
 int slang_assembly_file_push_label2 (slang_assembly_file *file, slang_assembly_type type,\r
        GLuint label1, GLuint label2)\r
 {\r
-       return slang_assembly_file_push_general (file, type, (GLfloat) 0, label1, label2);\r
+       return push_gen (file, type, (GLfloat) 0, label1, label2);\r
 }\r
 \r
 int slang_assembly_file_push_literal (slang_assembly_file *file, slang_assembly_type type,\r
        GLfloat literal)\r
 {\r
-       return slang_assembly_file_push_general (file, type, literal, 0, 0);\r
+       return push_gen (file, type, literal, 0, 0);\r
+}\r
+\r
+#define PUSH slang_assembly_file_push\r
+#define PLAB slang_assembly_file_push_label\r
+#define PLAB2 slang_assembly_file_push_label2\r
+#define PLIT slang_assembly_file_push_literal\r
+\r
+/* slang_assembly_file_restore_point */\r
+\r
+int slang_assembly_file_restore_point_save (slang_assembly_file *file,\r
+       slang_assembly_file_restore_point *point)\r
+{\r
+       point->count = file->count;\r
+       return 1;\r
+}\r
+\r
+int slang_assembly_file_restore_point_load (slang_assembly_file *file,\r
+       slang_assembly_file_restore_point *point)\r
+{\r
+       unsigned int i;\r
+\r
+       for (i = point->count; i < file->count; i++)\r
+               slang_assembly_destruct (&file->code[i]);\r
+       file->count = point->count;\r
+       return 1;\r
 }\r
 \r
 /* utility functions */\r
 \r
 static int sizeof_variable (slang_type_specifier *spec, slang_type_qualifier qual,\r
-       slang_operation *array_size, slang_assembly_name_space *space, unsigned int *size)\r
+       slang_operation *array_size, slang_assembly_name_space *space, unsigned int *size,\r
+       slang_machine *mach, slang_assembly_file *pfile, slang_atom_pool *atoms)\r
 {\r
        slang_storage_aggregate agg;\r
 \r
-       slang_storage_aggregate_construct (&agg);\r
-       if (!_slang_aggregate_variable (&agg, spec, array_size, space->funcs, space->structs, space->vars))\r
+       /* calculate the size of the variable's aggregate */\r
+       if (!slang_storage_aggregate_construct (&agg))\r
+               return 0;\r
+       if (!_slang_aggregate_variable (&agg, spec, array_size, space->funcs, space->structs,\r
+                       space->vars, mach, pfile, atoms))\r
        {\r
                slang_storage_aggregate_destruct (&agg);\r
                return 0;\r
        }\r
        *size += _slang_sizeof_aggregate (&agg);\r
+       slang_storage_aggregate_destruct (&agg);\r
+\r
+       /* for reference variables consider the additional address overhead */\r
        if (qual == slang_qual_out || qual == slang_qual_inout)\r
                *size += 4;\r
-       slang_storage_aggregate_destruct (&agg);\r
        return 1;\r
 }\r
 \r
 static int sizeof_variable2 (slang_variable *var, slang_assembly_name_space *space,\r
-       unsigned int *size)\r
+       unsigned int *size, slang_machine *mach, slang_assembly_file *pfile, slang_atom_pool *atoms)\r
 {\r
        var->address = *size;\r
        if (var->type.qualifier == slang_qual_out || var->type.qualifier == slang_qual_inout)\r
                var->address += 4;\r
        return sizeof_variable (&var->type.specifier, var->type.qualifier, var->array_size, space,\r
-               size);\r
+               size, mach, pfile, atoms);\r
 }\r
 \r
 static int sizeof_variables (slang_variable_scope *vars, unsigned int start, unsigned int stop,\r
-       slang_assembly_name_space *space, unsigned int *size)\r
+       slang_assembly_name_space *space, unsigned int *size, slang_machine *mach,\r
+       slang_assembly_file *pfile, slang_atom_pool *atoms)\r
 {\r
        unsigned int i;\r
 \r
        for (i = start; i < stop; i++)\r
-               if (!sizeof_variable2 (vars->variables + i, space, size))\r
+               if (!sizeof_variable2 (&vars->variables[i], space, size, mach, pfile, atoms))\r
                        return 0;\r
        return 1;\r
 }\r
 \r
 static int collect_locals (slang_operation *op, slang_assembly_name_space *space,\r
-       unsigned int *size)\r
+       unsigned int *size, slang_machine *mach, slang_assembly_file *pfile, slang_atom_pool *atoms)\r
 {\r
        unsigned int i;\r
 \r
-       if (!sizeof_variables (op->locals, 0, op->locals->num_variables, space, size))\r
+       if (!sizeof_variables (op->locals, 0, op->locals->num_variables, space, size, mach, pfile,\r
+                       atoms))\r
                return 0;\r
        for (i = 0; i < op->num_children; i++)\r
-               if (!collect_locals (op->children + i, space, size))\r
+               if (!collect_locals (&op->children[i], space, size, mach, pfile, atoms))\r
                        return 0;\r
        return 1;\r
 }\r
 \r
 /* _slang_locate_function() */\r
 \r
-slang_function *_slang_locate_function (const char *name, slang_operation *params,\r
-       unsigned int num_params, slang_assembly_name_space *space)\r
+slang_function *_slang_locate_function (slang_function_scope *funcs, slang_atom a_name,\r
+       slang_operation *params, unsigned int num_params, slang_assembly_name_space *space,\r
+       slang_atom_pool *atoms)\r
 {\r
        unsigned int i;\r
 \r
-       for (i = 0; i < space->funcs->num_functions; i++)\r
+       for (i = 0; i < funcs->num_functions; i++)\r
        {\r
                unsigned int j;\r
-               slang_function *f = space->funcs->functions + i;\r
+               slang_function *f = &funcs->functions[i];\r
 \r
-               if (slang_string_compare (name, f->header.name) != 0)\r
+               if (a_name != f->header.a_name)\r
                        continue;\r
                if (f->param_count != num_params)\r
                        continue;\r
                for (j = 0; j < num_params; j++)\r
                {\r
                        slang_assembly_typeinfo ti;\r
-                       slang_assembly_typeinfo_construct (&ti);\r
-                       if (!_slang_typeof_operation (params + j, space, &ti))\r
+\r
+                       if (!slang_assembly_typeinfo_construct (&ti))\r
+                               return 0;\r
+                       if (!_slang_typeof_operation (&params[j], space, &ti, atoms))\r
                        {\r
                                slang_assembly_typeinfo_destruct (&ti);\r
                                return 0;\r
@@ -201,28 +251,25 @@ slang_function *_slang_locate_function (const char *name, slang_operation *param
                                break;\r
                        }\r
                        slang_assembly_typeinfo_destruct (&ti);\r
+\r
                        /* "out" and "inout" formal parameter requires the actual parameter to be l-value */\r
                        if (!ti.can_be_referenced &&\r
-                               (f->parameters->variables[j].type.qualifier == slang_qual_out ||\r
-                               f->parameters->variables[j].type.qualifier == slang_qual_inout))\r
+                                       (f->parameters->variables[j].type.qualifier == slang_qual_out ||\r
+                                       f->parameters->variables[j].type.qualifier == slang_qual_inout))\r
                                break;\r
                }\r
                if (j == num_params)\r
                        return f;\r
        }\r
-       if (space->funcs->outer_scope != NULL)\r
-       {\r
-               slang_assembly_name_space my_space = *space;\r
-               my_space.funcs = space->funcs->outer_scope;\r
-               return _slang_locate_function (name, params, num_params, &my_space);\r
-       }\r
+       if (funcs->outer_scope != NULL)\r
+               return _slang_locate_function (funcs->outer_scope, a_name, params, num_params, space, atoms);\r
        return NULL;\r
 }\r
 \r
 /* _slang_assemble_function() */\r
 \r
 int _slang_assemble_function (slang_assembly_file *file, slang_function *fun,\r
-       slang_assembly_name_space *space)\r
+       slang_assembly_name_space *space, slang_machine *mach, slang_atom_pool *atoms)\r
 {\r
        unsigned int param_size, local_size;\r
        unsigned int skip, cleanup;\r
@@ -238,97 +285,106 @@ int _slang_assemble_function (slang_assembly_file *file, slang_function *fun,
                return 1;\r
        }\r
 \r
-       /* calculate return value and parameters size */\r
+       /* At this point traverse function formal parameters and code to calculate\r
+        * total memory size to be allocated on the stack.\r
+        * During this process the variables will be assigned local addresses to\r
+        * reference them in the code.\r
+        * No storage optimizations are performed so exclusive scopes are not detected and shared. */\r
+\r
+       /* calculate return value size */\r
        param_size = 0;\r
        if (fun->header.type.specifier.type != slang_spec_void)\r
                if (!sizeof_variable (&fun->header.type.specifier, slang_qual_none, NULL, space,\r
-                       &param_size))\r
+                               &param_size, mach, file, atoms))\r
                        return 0;\r
        info.ret_size = param_size;\r
-       if (!sizeof_variables (fun->parameters, 0, fun->param_count, space, &param_size))\r
+\r
+       /* calculate formal parameter list size */\r
+       if (!sizeof_variables (fun->parameters, 0, fun->param_count, space, &param_size, mach, file,\r
+                       atoms))\r
                return 0;\r
 \r
-       /* calculate local variables size, take into account the four-byte return address and\r
-       temporaries for various tasks */\r
+       /* calculate local variables size - take into account the four-byte return address and\r
+        * temporaries for various tasks (4 for addr and 16 for swizzle temporaries).\r
+        * these include variables from the formal parameter scope and from the code */\r
        info.addr_tmp = param_size + 4;\r
        info.swizzle_tmp = param_size + 4 + 4;\r
        local_size = param_size + 4 + 4 + 16;\r
        if (!sizeof_variables (fun->parameters, fun->param_count, fun->parameters->num_variables, space,\r
-               &local_size))\r
+                       &local_size, mach, file, atoms))\r
                return 0;\r
-       if (!collect_locals (fun->body, space, &local_size))\r
+       if (!collect_locals (fun->body, space, &local_size, mach, file, atoms))\r
                return 0;\r
 \r
        /* allocate local variable storage */\r
-       if (!slang_assembly_file_push_label (file, slang_asm_local_alloc, local_size - param_size - 4))\r
+       if (!PLAB (file, slang_asm_local_alloc, local_size - param_size - 4))\r
                return 0;\r
 \r
        /* mark a new frame for function variable storage */\r
-       if (!slang_assembly_file_push_label (file, slang_asm_enter, local_size))\r
+       if (!PLAB (file, slang_asm_enter, local_size))\r
                return 0;\r
 \r
-       /* skip the cleanup jump */\r
+       /* jump directly to the actual code */\r
        skip = file->count;\r
-       if (!slang_assembly_file_push_new (file))\r
+       if (!push_new (file))\r
                return 0;\r
        file->code[skip].type = slang_asm_jump;\r
 \r
        /* all "return" statements will be directed here */\r
        flow.function_end = file->count;\r
        cleanup = file->count;\r
-       if (!slang_assembly_file_push_new (file))\r
+       if (!push_new (file))\r
                return 0;\r
        file->code[cleanup].type = slang_asm_jump;\r
 \r
        /* execute the function body */\r
        file->code[skip].param[0] = file->count;\r
-       if (!_slang_assemble_operation (file, fun->body, 0, &flow, space, &info, &stk))\r
+       if (!_slang_assemble_operation (file, fun->body, 0, &flow, space, &info, &stk, mach, atoms))\r
                return 0;\r
 \r
        /* this is the end of the function - restore the old function frame */\r
        file->code[cleanup].param[0] = file->count;\r
-       if (!slang_assembly_file_push (file, slang_asm_leave))\r
+       if (!PUSH (file, slang_asm_leave))\r
                return 0;\r
 \r
        /* free local variable storage */\r
-       if (!slang_assembly_file_push_label (file, slang_asm_local_free, local_size - param_size - 4))\r
+       if (!PLAB (file, slang_asm_local_free, local_size - param_size - 4))\r
                return 0;\r
 \r
-       /* jump out of the function */\r
-       if (!slang_assembly_file_push (file, slang_asm_return))\r
+       /* return from the function */\r
+       if (!PUSH (file, slang_asm_return))\r
                return 0;\r
        return 1;\r
 }\r
 \r
 int _slang_cleanup_stack (slang_assembly_file *file, slang_operation *op, int ref,\r
-       slang_assembly_name_space *space)\r
+       slang_assembly_name_space *space, slang_machine *mach, slang_atom_pool *atoms)\r
 {\r
        slang_assembly_typeinfo ti;\r
-       unsigned int size;\r
+       unsigned int size = 0;\r
 \r
-       slang_assembly_typeinfo_construct (&ti);\r
-       if (!_slang_typeof_operation (op, space, &ti))\r
+       /* get type info of the operation and calculate its size */\r
+       if (!slang_assembly_typeinfo_construct (&ti))\r
+               return 0;\r
+       if (!_slang_typeof_operation (op, space, &ti, atoms))\r
        {\r
                slang_assembly_typeinfo_destruct (&ti);\r
                return 0;\r
        }\r
-       if (ti.spec.type == slang_spec_void)\r
-               size = 0;\r
-       else if (ref)\r
+       if (ref)\r
                size = 4;\r
-       else\r
-       {\r
-               size = 0;\r
-               if (!sizeof_variable (&ti.spec, slang_qual_none, NULL, space, &size))\r
+       else if (ti.spec.type != slang_spec_void)\r
+               if (!sizeof_variable (&ti.spec, slang_qual_none, NULL, space, &size, mach, file, atoms))\r
                {\r
                        slang_assembly_typeinfo_destruct (&ti);\r
                        return 0;\r
                }\r
-       }\r
        slang_assembly_typeinfo_destruct (&ti);\r
+\r
+       /* if nonzero, free it from the stack */\r
        if (size != 0)\r
        {\r
-               if (!slang_assembly_file_push_label (file, slang_asm_local_free, size))\r
+               if (!PLAB (file, slang_asm_local_free, size))\r
                        return 0;\r
        }\r
        return 1;\r
@@ -336,103 +392,133 @@ int _slang_cleanup_stack (slang_assembly_file *file, slang_operation *op, int re
 \r
 /* _slang_assemble_operation() */\r
 \r
-/* XXX: general swizzle! */\r
 static int dereference_aggregate (slang_assembly_file *file, const slang_storage_aggregate *agg,\r
-       unsigned int index, unsigned int *size, slang_assembly_local_info *info)\r
+       unsigned int *size, slang_assembly_local_info *info, slang_swizzle *swz, int is_swizzled)\r
 {\r
        unsigned int i;\r
 \r
        for (i = agg->count; i > 0; i--)\r
        {\r
-               const slang_storage_array *arr = agg->arrays + i - 1;\r
+               const slang_storage_array *arr = &agg->arrays[i - 1];\r
                unsigned int j;\r
 \r
                for (j = arr->length; j > 0; j--)\r
                {\r
                        if (arr->type == slang_stor_aggregate)\r
                        {\r
-                               if (!dereference_aggregate (file, arr->aggregate, index, size, info))\r
+                               if (!dereference_aggregate (file, arr->aggregate, size, info, swz, is_swizzled))\r
                                        return 0;\r
                        }\r
                        else\r
                        {\r
+                               unsigned int src_offset;\r
+                               slang_assembly_type ty;\r
+\r
                                *size -= 4;\r
-                               if (!slang_assembly_file_push_label2 (file, slang_asm_local_addr, info->addr_tmp,\r
-                                       4))\r
+\r
+                               /* calculate the offset within source variable to read */\r
+                               if (is_swizzled)\r
+                               {\r
+                                       /* swizzle the index to get the actual offset */\r
+                                       src_offset = swz->swizzle[*size / 4] * 4;\r
+                               }\r
+                               else\r
+                               {\r
+                                       /* no swizzling - read sequentially */\r
+                                       src_offset = *size;\r
+                               }\r
+\r
+                               /* dereference data slot of a basic type */\r
+                               if (!PLAB2 (file, slang_asm_local_addr, info->addr_tmp, 4))\r
                                        return 0;\r
-                               if (!slang_assembly_file_push (file, slang_asm_addr_deref))\r
+                               if (!PUSH (file, slang_asm_addr_deref))\r
                                        return 0;\r
-                               if (!slang_assembly_file_push_label (file, slang_asm_addr_push, *size))\r
+                               if (!PLAB (file, slang_asm_addr_push, src_offset))\r
                                        return 0;\r
-                               if (!slang_assembly_file_push (file, slang_asm_addr_add))\r
+                               if (!PUSH (file, slang_asm_addr_add))\r
                                        return 0;\r
+\r
                                switch (arr->type)\r
                                {\r
                                case slang_stor_bool:\r
-                                       if (!slang_assembly_file_push (file, slang_asm_bool_deref))\r
-                                               return 0;\r
+                                       ty = slang_asm_bool_deref;\r
                                        break;\r
                                case slang_stor_int:\r
-                                       if (!slang_assembly_file_push (file, slang_asm_int_deref))\r
-                                               return 0;\r
+                                       ty = slang_asm_int_deref;\r
                                        break;\r
                                case slang_stor_float:\r
-                                       if (!slang_assembly_file_push (file, slang_asm_float_deref))\r
-                                               return 0;\r
+                                       ty = slang_asm_float_deref;\r
                                        break;\r
                                }\r
-                               index += 4;\r
+                               if (!PUSH (file, ty))\r
+                                       return 0;\r
                        }\r
                }\r
        }\r
        return 1;\r
 }\r
-/* XXX: general swizzle! */\r
-int dereference (slang_assembly_file *file, slang_operation *op,\r
-       slang_assembly_name_space *space, slang_assembly_local_info *info)\r
+\r
+int _slang_dereference (slang_assembly_file *file, slang_operation *op,\r
+       slang_assembly_name_space *space, slang_assembly_local_info *info, slang_machine *mach,\r
+       slang_atom_pool *atoms)\r
 {\r
        slang_assembly_typeinfo ti;\r
        int result;\r
        slang_storage_aggregate agg;\r
        unsigned int size;\r
 \r
-       slang_assembly_typeinfo_construct (&ti);\r
-       if (!_slang_typeof_operation (op, space, &ti))\r
+       /* get type information of the given operation */\r
+       if (!slang_assembly_typeinfo_construct (&ti))\r
+               return 0;\r
+       if (!_slang_typeof_operation (op, space, &ti, atoms))\r
        {\r
                slang_assembly_typeinfo_destruct (&ti);\r
                return 0;\r
        }\r
 \r
-       slang_storage_aggregate_construct (&agg);\r
-       if (!_slang_aggregate_variable (&agg, &ti.spec, NULL, space->funcs, space->structs, space->vars))\r
+       /* construct aggregate from the type info */\r
+       if (!slang_storage_aggregate_construct (&agg))\r
+       {\r
+               slang_assembly_typeinfo_destruct (&ti);\r
+               return 0;\r
+       }\r
+       if (!_slang_aggregate_variable (&agg, &ti.spec, ti.array_size, space->funcs, space->structs,\r
+                       space->vars, mach, file, atoms))\r
        {\r
                slang_storage_aggregate_destruct (&agg);\r
                slang_assembly_typeinfo_destruct (&ti);\r
                return 0;\r
        }\r
 \r
+       /* dereference the resulting aggregate */\r
        size = _slang_sizeof_aggregate (&agg);\r
-       result = dereference_aggregate (file, &agg, 0, &size, info);\r
+       result = dereference_aggregate (file, &agg, &size, info, &ti.swz, ti.is_swizzled);\r
 \r
        slang_storage_aggregate_destruct (&agg);\r
        slang_assembly_typeinfo_destruct (&ti);\r
        return result;\r
 }\r
 \r
-static int call_function (slang_assembly_file *file, slang_function *fun, slang_operation *params,\r
+int _slang_call_function (slang_assembly_file *file, slang_function *fun, slang_operation *params,\r
        unsigned int param_count, int assignment, slang_assembly_name_space *space,\r
-       slang_assembly_local_info *info)\r
+       slang_assembly_local_info *info, slang_machine *mach, slang_atom_pool *atoms)\r
 {\r
        unsigned int i;\r
-       slang_assembly_stack_info stk;\r
+       slang_assembly_stack_info p_stk[64];\r
+\r
+       /* TODO: fix this, allocate dynamically */\r
+       if (param_count > 64)\r
+               return 0;\r
 \r
        /* make room for the return value, if any */\r
        if (fun->header.type.specifier.type != slang_spec_void)\r
        {\r
                unsigned int ret_size = 0;\r
-               if (!sizeof_variable (&fun->header.type.specifier, slang_qual_none, NULL, space, &ret_size))\r
+\r
+               if (!sizeof_variable (&fun->header.type.specifier, slang_qual_none, NULL, space,\r
+                               &ret_size, mach, file, atoms))\r
                        return 0;\r
-               if (!slang_assembly_file_push_label (file, slang_asm_local_alloc, ret_size))\r
+               if (!PLAB (file, slang_asm_local_alloc, ret_size))\r
                        return 0;\r
        }\r
 \r
@@ -444,56 +530,59 @@ static int call_function (slang_assembly_file *file, slang_function *fun, slang_
                if (fun->parameters->variables[i].type.qualifier == slang_qual_inout ||\r
                        fun->parameters->variables[i].type.qualifier == slang_qual_out)\r
                {\r
-                       if (!slang_assembly_file_push_label2 (file, slang_asm_local_addr, info->addr_tmp, 4))\r
+                       if (!PLAB2 (file, slang_asm_local_addr, info->addr_tmp, 4))\r
                                return 0;\r
                        /* TODO: optimize the "out" parameter case */\r
-                       /* TODO: inspect stk */\r
-                       if (!_slang_assemble_operation (file, params + i, 1, &flow, space, info, &stk))\r
+                       if (!_slang_assemble_operation (file, &params[i], 1, &flow, space, info, &p_stk[i],\r
+                                       mach, atoms))\r
                                return 0;\r
-                       if (!slang_assembly_file_push (file, slang_asm_addr_copy))\r
+                       if (!PUSH (file, slang_asm_addr_copy))\r
                                return 0;\r
-                       if (!slang_assembly_file_push (file, slang_asm_addr_deref))\r
+                       if (!PUSH (file, slang_asm_addr_deref))\r
                                return 0;\r
                        if (i == 0 && assignment)\r
                        {\r
-                               if (!slang_assembly_file_push_label2 (file, slang_asm_local_addr, info->addr_tmp,\r
-                                       4))\r
+                               /* duplicate the resulting address */\r
+                               if (!PLAB2 (file, slang_asm_local_addr, info->addr_tmp, 4))\r
                                        return 0;\r
-                               if (!slang_assembly_file_push (file, slang_asm_addr_deref))\r
+                               if (!PUSH (file, slang_asm_addr_deref))\r
                                        return 0;\r
                        }\r
-                       if (!dereference (file, params, space, info))\r
+                       if (!_slang_dereference (file, &params[i], space, info, mach, atoms))\r
                                return 0;\r
                }\r
                else\r
                {\r
-                       /* TODO: for "out" and "inout" parameters also push the address (first) */\r
-                       /* TODO: optimize the "out" parameter case */\r
-                       /* TODO: inspect stk */\r
-                       if (!_slang_assemble_operation (file, params + i, 0, &flow, space, info, &stk))\r
+                       if (!_slang_assemble_operation (file, &params[i], 0, &flow, space, info, &p_stk[i],\r
+                                       mach, atoms))\r
                                return 0;\r
                }\r
        }\r
 \r
        /* call the function */\r
-       if (!slang_assembly_file_push_label (file, slang_asm_call, fun->address))\r
+       if (!PLAB (file, slang_asm_call, fun->address))\r
                return 0;\r
 \r
        /* pop the parameters from the stack */\r
        for (i = param_count; i > 0; i--)\r
        {\r
                unsigned int j = i - 1;\r
+\r
                if (fun->parameters->variables[j].type.qualifier == slang_qual_inout ||\r
                        fun->parameters->variables[j].type.qualifier == slang_qual_out)\r
                {\r
-                       if (!_slang_assemble_assignment (file, params + j, space, info))\r
+                       /* for output parameter copy the contents of the formal parameter\r
+                        * back to the original actual parameter */\r
+                       if (!_slang_assemble_assignment (file, &params[j], space, info, &p_stk[j], mach, atoms))\r
                                return 0;\r
-                       if (!slang_assembly_file_push_label (file, slang_asm_local_free, 4))\r
+                       /* pop the actual parameter's address */\r
+                       if (!PLAB (file, slang_asm_local_free, 4))\r
                                return 0;\r
                }\r
                else\r
                {\r
-                       if (!_slang_cleanup_stack (file, params + j, 0, space))\r
+                       /* pop the value of the parameter */\r
+                       if (!_slang_cleanup_stack (file, &params[j], 0, space, mach, atoms))\r
                                return 0;\r
                }\r
        }\r
@@ -501,73 +590,94 @@ static int call_function (slang_assembly_file *file, slang_function *fun, slang_
        return 1;\r
 }\r
 \r
+/* TODO: migrate to full-atom version */\r
 int call_function_name (slang_assembly_file *file, const char *name, slang_operation *params,\r
        unsigned int param_count, int assignment, slang_assembly_name_space *space,\r
-       slang_assembly_local_info *info)\r
+       slang_assembly_local_info *info, slang_machine *mach, slang_atom_pool *atoms)\r
 {\r
-       slang_function *fun = _slang_locate_function (name, params, param_count, space);\r
+       slang_atom atom;\r
+       slang_function *fun;\r
+\r
+       atom = slang_atom_pool_atom (atoms, name);\r
+       if (atom == SLANG_ATOM_NULL)\r
+               return 0;\r
+       fun = _slang_locate_function (space->funcs, atom, params, param_count, space, atoms);\r
        if (fun == NULL)\r
                return 0;\r
-       return call_function (file, fun, params, param_count, assignment, space, info);\r
+       return _slang_call_function (file, fun, params, param_count, assignment, space, info, mach,\r
+               atoms);\r
 }\r
 \r
 static int call_function_name_dummyint (slang_assembly_file *file, const char *name,\r
-       slang_operation *params, slang_assembly_name_space *space, slang_assembly_local_info *info)\r
+       slang_operation *params, slang_assembly_name_space *space, slang_assembly_local_info *info,\r
+       slang_machine *mach, slang_atom_pool *atoms)\r
 {\r
-       slang_operation p2[2];\r
+       slang_operation p[2];\r
        int result;\r
 \r
-       p2[0] = *params;\r
-       if (!slang_operation_construct (p2 + 1))\r
+       p[0] = params[0];\r
+       if (!slang_operation_construct (&p[1]))\r
                return 0;\r
-       p2[1].type = slang_oper_literal_int;\r
-       result = call_function_name (file, name, p2, 2, 0, space, info);\r
-       slang_operation_destruct (p2 + 1);\r
+       p[1].type = slang_oper_literal_int;\r
+       result = call_function_name (file, name, p, 2, 0, space, info, mach, atoms);\r
+       slang_operation_destruct (&p[1]);\r
        return result;\r
 }\r
 \r
-static int call_asm_instruction (slang_assembly_file *file, const char *name)\r
+static const struct\r
 {\r
-       const struct\r
-       {\r
-               const char *name;\r
-               slang_assembly_type code1, code2;\r
-       } inst[] = {\r
-               { "float_to_int",   slang_asm_float_to_int,   slang_asm_int_copy },\r
-               { "int_to_float",   slang_asm_int_to_float,   slang_asm_float_copy },\r
-               { "float_copy",     slang_asm_float_copy,     slang_asm_none },\r
-               { "int_copy",       slang_asm_int_copy,       slang_asm_none },\r
-               { "bool_copy",      slang_asm_bool_copy,      slang_asm_none },\r
-               { "float_add",      slang_asm_float_add,      slang_asm_float_copy },\r
-               { "float_multiply", slang_asm_float_multiply, slang_asm_float_copy },\r
-               { "float_divide",   slang_asm_float_divide,   slang_asm_float_copy },\r
-               { "float_negate",   slang_asm_float_negate,   slang_asm_float_copy },\r
-               { "float_less",     slang_asm_float_less,     slang_asm_bool_copy },\r
-               { "float_equal",    slang_asm_float_equal,    slang_asm_bool_copy },\r
-               { NULL,             slang_asm_none,           slang_asm_none }\r
-       };\r
+       const char *name;\r
+       slang_assembly_type code1, code2;\r
+} inst[] = {\r
+       /* core */\r
+       { "float_add",      slang_asm_float_add,      slang_asm_float_copy },\r
+       { "float_multiply", slang_asm_float_multiply, slang_asm_float_copy },\r
+       { "float_divide",   slang_asm_float_divide,   slang_asm_float_copy },\r
+       { "float_negate",   slang_asm_float_negate,   slang_asm_float_copy },\r
+       { "float_less",     slang_asm_float_less,     slang_asm_bool_copy },\r
+       { "float_equal",    slang_asm_float_equal_exp,slang_asm_bool_copy },\r
+       { "float_to_int",   slang_asm_float_to_int,   slang_asm_int_copy },\r
+       { "float_sine",     slang_asm_float_sine,     slang_asm_float_copy },\r
+       { "float_arcsine",  slang_asm_float_arcsine,  slang_asm_float_copy },\r
+       { "float_arctan",   slang_asm_float_arctan,   slang_asm_float_copy },\r
+       { "float_power",    slang_asm_float_power,    slang_asm_float_copy },\r
+       { "float_log2",     slang_asm_float_log2,     slang_asm_float_copy },\r
+       { "float_floor",    slang_asm_float_floor,    slang_asm_float_copy },\r
+       { "float_ceil",     slang_asm_float_ceil,     slang_asm_float_copy },\r
+       { "int_to_float",   slang_asm_int_to_float,   slang_asm_float_copy },\r
+       /* mesa-specific extensions */\r
+       { "float_print",    slang_asm_float_deref,    slang_asm_float_print },\r
+       { "int_print",      slang_asm_int_deref,      slang_asm_int_print },\r
+       { "bool_print",     slang_asm_bool_deref,     slang_asm_bool_print },\r
+       { NULL,             slang_asm_none,           slang_asm_none }\r
+};\r
+\r
+static int call_asm_instruction (slang_assembly_file *file, slang_atom a_name, slang_atom_pool *atoms)\r
+{\r
+       const char *id;\r
        unsigned int i;\r
 \r
+       id = slang_atom_pool_id (atoms, a_name);\r
+\r
        for (i = 0; inst[i].name != NULL; i++)\r
-               if (slang_string_compare (name, inst[i].name) == 0)\r
+               if (slang_string_compare (id, inst[i].name) == 0)\r
                        break;\r
        if (inst[i].name == NULL)\r
                return 0;\r
 \r
-       if (!slang_assembly_file_push_label2 (file, inst[i].code1, 4, 0))\r
+       if (!PLAB2 (file, inst[i].code1, 4, 0))\r
                return 0;\r
        if (inst[i].code2 != slang_asm_none)\r
-               if (!slang_assembly_file_push_label2 (file, inst[i].code2, 4, 0))\r
+               if (!PLAB2 (file, inst[i].code2, 4, 0))\r
                        return 0;\r
 \r
        /* clean-up the stack from the remaining dst address */\r
-       if (!slang_assembly_file_push_label (file, slang_asm_local_free, 4))\r
+       if (!PLAB (file, slang_asm_local_free, 4))\r
                return 0;\r
 \r
        return 1;\r
 }\r
 \r
-/* XXX: general swizzle! */\r
 static int equality_aggregate (slang_assembly_file *file, const slang_storage_aggregate *agg,\r
        unsigned int *index, unsigned int size, slang_assembly_local_info *info, unsigned int z_label)\r
 {\r
@@ -575,7 +685,7 @@ static int equality_aggregate (slang_assembly_file *file, const slang_storage_ag
 \r
        for (i = 0; i < agg->count; i++)\r
        {\r
-               const slang_storage_array *arr = agg->arrays + i;\r
+               const slang_storage_array *arr = &agg->arrays[i];\r
                unsigned int j;\r
 \r
                for (j = 0; j < arr->length; j++)\r
@@ -587,39 +697,38 @@ static int equality_aggregate (slang_assembly_file *file, const slang_storage_ag
                        }\r
                        else\r
                        {\r
-                               if (!slang_assembly_file_push_label2 (file, slang_asm_float_equal, size + *index,\r
-                                       *index))\r
+                               if (!PLAB2 (file, slang_asm_float_equal_int, size + *index, *index))\r
                                        return 0;\r
                                *index += 4;\r
-                               if (!slang_assembly_file_push_label (file, slang_asm_jump_if_zero, z_label))\r
+                               if (!PLAB (file, slang_asm_jump_if_zero, z_label))\r
                                        return 0;\r
                        }\r
                }\r
        }\r
        return 1;\r
 }\r
-/* XXX: general swizzle! */\r
+\r
 static int equality (slang_assembly_file *file, slang_operation *op,\r
-       slang_assembly_name_space *space, slang_assembly_local_info *info, int equal)\r
+       slang_assembly_name_space *space, slang_assembly_local_info *info, int equal,\r
+       slang_machine *mach, slang_atom_pool *atoms)\r
 {\r
        slang_assembly_typeinfo ti;\r
-       int result;\r
+       int result = 0;\r
        slang_storage_aggregate agg;\r
        unsigned int index, size;\r
        unsigned int skip_jump, true_label, true_jump, false_label, false_jump;\r
 \r
        /* get type of operation */\r
-       slang_assembly_typeinfo_construct (&ti);\r
-       if (!_slang_typeof_operation (op, space, &ti))\r
-       {\r
-               slang_assembly_typeinfo_destruct (&ti);\r
+       if (!slang_assembly_typeinfo_construct (&ti))\r
                return 0;\r
-       }\r
+       if (!_slang_typeof_operation (op, space, &ti, atoms))\r
+               goto end1;\r
 \r
        /* convert it to an aggregate */\r
-       slang_storage_aggregate_construct (&agg);\r
-       if (!(result = _slang_aggregate_variable (&agg, &ti.spec, NULL, space->funcs, space->structs,\r
-                       space->vars)))\r
+       if (!slang_storage_aggregate_construct (&agg))\r
+               goto end1;\r
+       if (!_slang_aggregate_variable (&agg, &ti.spec, NULL, space->funcs, space->structs,\r
+                       space->vars, mach, file, atoms))\r
                goto end;\r
 \r
        /* compute the size of the agregate - there are two such aggregates on the stack */\r
@@ -627,37 +736,35 @@ static int equality (slang_assembly_file *file, slang_operation *op,
 \r
        /* jump to the actual data-comparison code */\r
        skip_jump = file->count;\r
-       if (!(result = slang_assembly_file_push (file, slang_asm_jump)))\r
+       if (!PUSH (file, slang_asm_jump))\r
                goto end;\r
 \r
        /* pop off the stack the compared data and push 1 */\r
        true_label = file->count;\r
-       if (!(result = slang_assembly_file_push_label (file, slang_asm_local_free, size * 2)))\r
+       if (!PLAB (file, slang_asm_local_free, size * 2))\r
                goto end;\r
-       if (!(result = slang_assembly_file_push_literal (file, slang_asm_bool_push, 1.0f)))\r
+       if (!PLIT (file, slang_asm_bool_push, (GLfloat) 1))\r
                goto end;\r
        true_jump = file->count;\r
-       if (!(result = slang_assembly_file_push (file, slang_asm_jump)))\r
+       if (!PUSH (file, slang_asm_jump))\r
                goto end;\r
 \r
        false_label = file->count;\r
-       if (!(result = slang_assembly_file_push_label (file, slang_asm_local_free, size * 2)))\r
+       if (!PLAB (file, slang_asm_local_free, size * 2))\r
                goto end;\r
-       if (!(result = slang_assembly_file_push_literal (file, slang_asm_bool_push, 0.0f)))\r
+       if (!PLIT (file, slang_asm_bool_push, (GLfloat) 0))\r
                goto end;\r
        false_jump = file->count;\r
-       if (!(result = slang_assembly_file_push (file, slang_asm_jump)))\r
+       if (!PUSH (file, slang_asm_jump))\r
                goto end;\r
 \r
        file->code[skip_jump].param[0] = file->count;\r
 \r
        /* compare the data on stack, it will eventually jump either to true or false label */\r
        index = 0;\r
-       if (!(result = equality_aggregate (file, &agg, &index, size, info,\r
-               equal ? false_label : true_label)))\r
+       if (!equality_aggregate (file, &agg, &index, size, info, equal ? false_label : true_label))\r
                goto end;\r
-       if (!(result = slang_assembly_file_push_label (file, slang_asm_jump,\r
-               equal ? true_label : false_label)))\r
+       if (!PLAB (file, slang_asm_jump, equal ? true_label : false_label))\r
                goto end;\r
 \r
        file->code[true_jump].param[0] = file->count;\r
@@ -666,20 +773,245 @@ static int equality (slang_assembly_file *file, slang_operation *op,
        result = 1;\r
 end:\r
        slang_storage_aggregate_destruct (&agg);\r
+end1:\r
        slang_assembly_typeinfo_destruct (&ti);\r
        return result;\r
 }\r
 \r
+static int handle_subscript (slang_assembly_typeinfo *tie, slang_assembly_typeinfo *tia,\r
+       slang_assembly_file *file, slang_operation *op, int reference, slang_assembly_flow_control *flow,\r
+       slang_assembly_name_space *space, slang_assembly_local_info *info, slang_machine *mach,\r
+       slang_atom_pool *atoms)\r
+{\r
+       unsigned int asize = 0, esize = 0;\r
+       slang_assembly_stack_info _stk;\r
+\r
+       /* get type info of the master expression (matrix, vector or an array */\r
+       if (!_slang_typeof_operation (&op->children[0], space, tia, atoms))\r
+               return 0;\r
+       if (!sizeof_variable (&tia->spec, slang_qual_none, tia->array_size, space, &asize, mach, file,\r
+                       atoms))\r
+               return 0;\r
+\r
+       /* get type info of the result (matrix column, vector row or array element) */\r
+       if (!_slang_typeof_operation (op, space, tie, atoms))\r
+               return 0;\r
+       if (!sizeof_variable (&tie->spec, slang_qual_none, NULL, space, &esize, mach, file, atoms))\r
+               return 0;\r
+\r
+       /* assemble the master expression */\r
+       if (!_slang_assemble_operation (file, &op->children[0], reference, flow, space, info, &_stk,\r
+                       mach, atoms))\r
+               return 0;\r
+       /* ignre the _stk */\r
+\r
+       /* when indexing an l-value swizzle, push the swizzle_tmp */\r
+       if (reference && tia->is_swizzled)\r
+       {\r
+               if (!PLAB2 (file, slang_asm_local_addr, info->swizzle_tmp, 16))\r
+                       return 0;\r
+       }\r
+\r
+       /* assemble the subscript expression */\r
+       if (!_slang_assemble_operation (file, &op->children[1], 0, flow, space, info, &_stk, mach, atoms))\r
+               return 0;\r
+       /* ignore the _stk */\r
+\r
+       if (reference && tia->is_swizzled)\r
+       {\r
+               unsigned int i;\r
+\r
+               /* copy the swizzle indexes to the swizzle_tmp */\r
+               for (i = 0; i < tia->swz.num_components; i++)\r
+               {\r
+                       if (!PLAB2 (file, slang_asm_local_addr, info->swizzle_tmp, 16))\r
+                               return 0;\r
+                       if (!PLAB (file, slang_asm_addr_push, i * 4))\r
+                               return 0;\r
+                       if (!PUSH (file, slang_asm_addr_add))\r
+                               return 0;\r
+                       if (!PLAB (file, slang_asm_addr_push, tia->swz.swizzle[i]))\r
+                               return 0;\r
+                       if (!PUSH (file, slang_asm_addr_copy))\r
+                               return 0;\r
+                       if (!PLAB (file, slang_asm_local_free, 4))\r
+                               return 0;\r
+               }\r
+\r
+               /* offset the pushed swizzle_tmp address and dereference it */\r
+               if (!PUSH (file, slang_asm_int_to_addr))\r
+                       return 0;\r
+               if (!PLAB (file, slang_asm_addr_push, 4))\r
+                       return 0;\r
+               if (!PUSH (file, slang_asm_addr_multiply))\r
+                       return 0;\r
+               if (!PUSH (file, slang_asm_addr_add))\r
+                       return 0;\r
+               if (!PUSH (file, slang_asm_addr_deref))\r
+                       return 0;\r
+       }\r
+       else\r
+       {\r
+               /* convert the integer subscript to a relative address */\r
+               if (!PUSH (file, slang_asm_int_to_addr))\r
+                       return 0;\r
+       }\r
+\r
+       if (!PLAB (file, slang_asm_addr_push, esize))\r
+               return 0;\r
+       if (!PUSH (file, slang_asm_addr_multiply))\r
+               return 0;\r
+\r
+       if (reference)\r
+       {\r
+               /* offset the base address with the relative address */\r
+               if (!PUSH (file, slang_asm_addr_add))\r
+                       return 0;\r
+       }\r
+       else\r
+       {\r
+               unsigned int i;\r
+\r
+               /* move the selected element to the beginning of the master expression */\r
+               for (i = 0; i < esize; i += 4)\r
+                       if (!PLAB2 (file, slang_asm_float_move, asize - esize + i + 4, i + 4))\r
+                               return 0;\r
+               if (!PLAB (file, slang_asm_local_free, 4))\r
+                       return 0;\r
+\r
+               /* free the rest of the master expression */\r
+               if (!PLAB (file, slang_asm_local_free, asize - esize))\r
+                       return 0;\r
+       }\r
+       return 1;\r
+}\r
+\r
+static int handle_field (slang_assembly_typeinfo *tia, slang_assembly_typeinfo *tib,\r
+       slang_assembly_file *file, slang_operation *op, int reference, slang_assembly_flow_control *flow,\r
+       slang_assembly_name_space *space, slang_assembly_local_info *info, slang_assembly_stack_info *stk,\r
+       slang_machine *mach, slang_atom_pool *atoms)\r
+{\r
+       slang_assembly_stack_info _stk;\r
+\r
+       /* get type info of the result (field or swizzle) */\r
+       if (!_slang_typeof_operation (op, space, tia, atoms))\r
+               return 0;\r
+\r
+       /* get type info of the master expression being accessed (struct or vector) */\r
+       if (!_slang_typeof_operation (&op->children[0], space, tib, atoms))\r
+               return 0;\r
+\r
+       /* if swizzling a vector in-place, the swizzle temporary is needed */\r
+       if (!reference && tia->is_swizzled)\r
+               if (!PLAB2 (file, slang_asm_local_addr, info->swizzle_tmp, 16))\r
+                       return 0;\r
+\r
+       /* assemble the master expression */\r
+       if (!_slang_assemble_operation (file, &op->children[0], reference, flow, space, info, &_stk,\r
+                       mach, atoms))\r
+               return 0;\r
+       /* ignore _stk.swizzle - we'll have it in tia->swz */\r
+\r
+       /* assemble the field expression */\r
+       if (tia->is_swizzled)\r
+       {\r
+               if (reference)\r
+               {\r
+                       /*if (tia->swz.num_components == 1)\r
+                       {\r
+                               /* simple case - adjust the vector's address to point to the selected component */\r
+                       /*      if (!PLAB (file, slang_asm_addr_push, tia->swz.swizzle[0] * 4))\r
+                                       return 0;\r
+                               if (!PUSH (file, slang_asm_addr_add))\r
+                                       return 0;\r
+                       }\r
+                       else*/\r
+                       {\r
+                               /* two or more vector components are being referenced - the so-called write mask\r
+                                * must be passed to the upper operations and applied when assigning value\r
+                                * to this swizzle */\r
+                               stk->swizzle = tia->swz;\r
+                       }\r
+               }\r
+               else\r
+               {\r
+                       /* swizzle the vector in-place using the swizzle temporary */\r
+                       if (!_slang_assemble_constructor_from_swizzle (file, &tia->swz, &tia->spec, &tib->spec,\r
+                                       info))\r
+                               return 0;\r
+               }\r
+       }\r
+       else\r
+       {\r
+               GLuint i, struct_size = 0, field_offset = 0, field_size = 0;\r
+\r
+               for (i = 0; i < tib->spec._struct->fields->num_variables; i++)\r
+               {\r
+                       slang_variable *field;\r
+                       slang_storage_aggregate agg;\r
+                       GLuint size;\r
+\r
+                       field = &tib->spec._struct->fields->variables[i];\r
+                       if (!slang_storage_aggregate_construct (&agg))\r
+                               return 0;\r
+                       if (!_slang_aggregate_variable (&agg, &field->type.specifier, field->array_size,\r
+                               space->funcs, space->structs, space->vars, mach, file, atoms))\r
+                       {\r
+                               slang_storage_aggregate_destruct (&agg);\r
+                               return 0;\r
+                       }\r
+                       size = _slang_sizeof_aggregate (&agg);\r
+                       slang_storage_aggregate_destruct (&agg);\r
+\r
+                       if (op->a_id == field->a_name)\r
+                       {\r
+                               field_size = size;\r
+                               struct_size = field_offset + size;\r
+                       }\r
+                       else if (struct_size != 0)\r
+                               struct_size += size;\r
+                       else\r
+                               field_offset += size;\r
+               }\r
+\r
+               if (!PLAB (file, slang_asm_addr_push, field_offset))\r
+                       return 0;\r
+\r
+               if (reference)\r
+               {\r
+                       if (!PUSH (file, slang_asm_addr_add))\r
+                               return 0;\r
+               }\r
+               else\r
+               {\r
+                       unsigned int i;\r
+\r
+                       /* move the selected element to the beginning of the master expression */\r
+                       for (i = 0; i < field_size; i += 4)\r
+                               if (!PLAB2 (file, slang_asm_float_move, struct_size - field_size + i + 4, i + 4))\r
+                                       return 0;\r
+                       if (!PLAB (file, slang_asm_local_free, 4))\r
+                               return 0;\r
+\r
+                       /* free the rest of the master expression */\r
+                       if (!PLAB (file, slang_asm_local_free, struct_size - field_size))\r
+                               return 0;\r
+               }\r
+       }\r
+       return 1;\r
+}\r
+\r
 int _slang_assemble_operation (slang_assembly_file *file, slang_operation *op, int reference,\r
        slang_assembly_flow_control *flow, slang_assembly_name_space *space,\r
-       slang_assembly_local_info *info, slang_assembly_stack_info *stk)\r
+       slang_assembly_local_info *info, slang_assembly_stack_info *stk, slang_machine *mach,\r
+       slang_atom_pool *atoms)\r
 {\r
        unsigned int assem;\r
 \r
-       stk->swizzle_mask = 0;\r
+       stk->swizzle.num_components = 0;\r
 \r
        assem = file->count;\r
-       if (!slang_assembly_file_push_new (file))\r
+       if (!push_new (file))\r
                return 0;\r
 \r
        switch (op->type)\r
@@ -688,13 +1020,16 @@ int _slang_assemble_operation (slang_assembly_file *file, slang_operation *op, i
        case slang_oper_block_new_scope:\r
                {\r
                        unsigned int i;\r
+\r
                        for (i = 0; i < op->num_children; i++)\r
                        {\r
                                slang_assembly_stack_info stk;\r
-                               if (!_slang_assemble_operation (file, op->children + i, 0, flow, space, info, &stk))\r
+\r
+                               if (!_slang_assemble_operation (file, &op->children[i], 0, flow, space, info, &stk,\r
+                                               mach, atoms))\r
                                        return 0;\r
-                               /* TODO: pass-in stk to cleanup */\r
-                               if (!_slang_cleanup_stack (file, op->children + i, 0, space))\r
+                               /* ignore the stk */\r
+                               if (!_slang_cleanup_stack (file, &op->children[i], 0, space, mach, atoms))\r
                                        return 0;\r
                        }\r
                }\r
@@ -713,15 +1048,17 @@ int _slang_assemble_operation (slang_assembly_file *file, slang_operation *op, i
        case slang_oper_asm:\r
                {\r
                        unsigned int i;\r
+\r
                        for (i = 0; i < op->num_children; i++)\r
                        {\r
                                slang_assembly_stack_info stk;\r
-                               if (!_slang_assemble_operation (file, op->children + i, i == 0, flow, space, info,\r
-                                       &stk))\r
+\r
+                               if (!_slang_assemble_operation (file, &op->children[i], i == 0, flow, space, info,\r
+                                               &stk, mach, atoms))\r
                                        return 0;\r
-                               /* TODO: inspect stk */\r
+                               /* __asm statement does not support any swizzles, so lets ignore stk for now */\r
                        }\r
-                       if (!call_asm_instruction (file, op->identifier))\r
+                       if (!call_asm_instruction (file, op->a_id, atoms))\r
                                return 0;\r
                }\r
                break;\r
@@ -735,48 +1072,57 @@ int _slang_assemble_operation (slang_assembly_file *file, slang_operation *op, i
                break;\r
        case slang_oper_discard:\r
                file->code[assem].type = slang_asm_discard;\r
-               if (!slang_assembly_file_push (file, slang_asm_exit))\r
+               if (!PUSH (file, slang_asm_exit))\r
                        return 0;\r
                break;\r
        case slang_oper_return:\r
                if (info->ret_size != 0)\r
                {\r
                        slang_assembly_stack_info stk;\r
-                       if (!slang_assembly_file_push_label2 (file, slang_asm_local_addr, 0, info->ret_size))\r
+\r
+                       /* push the result's address */\r
+                       if (!PLAB2 (file, slang_asm_local_addr, 0, info->ret_size))\r
                                return 0;\r
-                       if (!_slang_assemble_operation (file, op->children, 0, flow, space, info, &stk))\r
+                       if (!_slang_assemble_operation (file, &op->children[0], 0, flow, space, info, &stk,\r
+                                       mach, atoms))\r
                                return 0;\r
-                       /* TODO: inspect stk */\r
-                       if (!_slang_assemble_assignment (file, op->children, space, info))\r
+\r
+                       /* ignore the stk from latest operation, reset swizzle to 0 for the assignment */\r
+                       stk.swizzle.num_components = 0;\r
+                       /* assign the operation to the function result (it was reserved on the stack) */\r
+                       if (!_slang_assemble_assignment (file, op->children, space, info, &stk, mach, atoms))\r
                                return 0;\r
-                       if (!slang_assembly_file_push_label (file, slang_asm_local_free, 4))\r
+\r
+                       if (!PLAB (file, slang_asm_local_free, 4))\r
                                return 0;\r
                }\r
-               if (!slang_assembly_file_push_label (file, slang_asm_jump, flow->function_end))\r
+               if (!PLAB (file, slang_asm_jump, flow->function_end))\r
                        return 0;\r
                break;\r
        case slang_oper_expression:\r
                {\r
                        slang_assembly_stack_info stk;\r
-                       if (!_slang_assemble_operation (file, op->children, reference, flow, space, info, &stk))\r
+\r
+                       assert (!reference);\r
+                       if (!_slang_assemble_operation (file, op->children, 0, flow, space, info, &stk, mach, atoms))\r
                                return 0;\r
-                       /* TODO: inspect stk */\r
+                       /* ignore the stk info */\r
                }\r
                break;\r
        case slang_oper_if:\r
-               if (!_slang_assemble_if (file, op, flow, space, info))\r
+               if (!_slang_assemble_if (file, op, flow, space, info, mach, atoms))\r
                        return 0;\r
                break;\r
        case slang_oper_while:\r
-               if (!_slang_assemble_while (file, op, flow, space, info))\r
+               if (!_slang_assemble_while (file, op, flow, space, info, mach, atoms))\r
                        return 0;\r
                break;\r
        case slang_oper_do:\r
-               if (!_slang_assemble_do (file, op, flow, space, info))\r
+               if (!_slang_assemble_do (file, op, flow, space, info, mach, atoms))\r
                        return 0;\r
                break;\r
        case slang_oper_for:\r
-               if (!_slang_assemble_for (file, op, flow, space, info))\r
+               if (!_slang_assemble_for (file, op, flow, space, info, mach, atoms))\r
                        return 0;\r
                break;\r
        case slang_oper_void:\r
@@ -797,69 +1143,75 @@ int _slang_assemble_operation (slang_assembly_file *file, slang_operation *op, i
                {\r
                        slang_variable *var;\r
                        unsigned int size;\r
-                       var = _slang_locate_variable (op->locals, op->identifier, 1);\r
+\r
+                       /* find the variable and calculate its size */\r
+                       var = _slang_locate_variable (op->locals, op->a_id, 1);\r
                        if (var == NULL)\r
                                return 0;\r
                        size = 0;\r
                        if (!sizeof_variable (&var->type.specifier, slang_qual_none, var->array_size, space,\r
-                               &size))\r
+                                       &size, mach, file, atoms))\r
                                return 0;\r
-                       if (var->initializer != NULL)\r
+\r
+                       /* prepare stack for dereferencing */\r
+                       if (!reference)\r
+                               if (!PLAB2 (file, slang_asm_local_addr, info->addr_tmp, 4))\r
+                                       return 0;\r
+\r
+                       /* push the variable's address */\r
+                       if (var->global)\r
                        {\r
-                               assert (!"var->initializer, oper_identifier");\r
+                               if (!PLAB (file, slang_asm_addr_push, var->address))\r
+                                       return 0;\r
                        }\r
                        else\r
                        {\r
-                               if (!reference)\r
-                               {\r
-                                       if (!slang_assembly_file_push_label2 (file, slang_asm_local_addr,\r
-                                               info->addr_tmp, 4))\r
-                                               return 0;\r
-                               }\r
-                               /* XXX: globals! */\r
-                               if (!slang_assembly_file_push_label2 (file, slang_asm_local_addr, var->address,\r
-                                       size))\r
+                               if (!PLAB2 (file, slang_asm_local_addr, var->address, size))\r
+                                       return 0;\r
+                       }\r
+\r
+                       /* perform the dereference */\r
+                       if (!reference)\r
+                       {\r
+                               if (!PUSH (file, slang_asm_addr_copy))\r
+                                       return 0;\r
+                               if (!PLAB (file, slang_asm_local_free, 4))\r
+                                       return 0;\r
+                               if (!_slang_dereference (file, op, space, info, mach, atoms))\r
                                        return 0;\r
-                               if (!reference)\r
-                               {\r
-                                       if (!slang_assembly_file_push (file, slang_asm_addr_copy))\r
-                                               return 0;\r
-                                       if (!slang_assembly_file_push_label (file, slang_asm_local_free, 4))\r
-                                               return 0;\r
-                                       if (!dereference (file, op, space, info))\r
-                                               return 0;\r
-                               }\r
                        }\r
                }\r
                break;\r
        case slang_oper_sequence:\r
                {\r
                        slang_assembly_stack_info stk;\r
-                       if (!_slang_assemble_operation (file, op->children, 0, flow, space, info, &stk))\r
+\r
+                       if (!_slang_assemble_operation (file, &op->children[0], 0, flow, space, info, &stk,\r
+                                       mach, atoms))\r
                                return 0;\r
                        /* TODO: pass-in stk to cleanup */\r
-                       if (!_slang_cleanup_stack (file, op->children, 0, space))\r
+                       if (!_slang_cleanup_stack (file, &op->children[0], 0, space, mach, atoms))\r
                                return 0;\r
-                       if (!_slang_assemble_operation (file, op->children + 1, 0, flow, space, info,\r
-                               &stk))\r
+                       if (!_slang_assemble_operation (file, &op->children[1], 0, flow, space, info,\r
+                                       &stk, mach, atoms))\r
                                return 0;\r
                        /* TODO: inspect stk */\r
                }\r
                break;\r
        case slang_oper_assign:\r
-               if (!_slang_assemble_assign (file, op, "=", reference, space, info))\r
+               if (!_slang_assemble_assign (file, op, "=", reference, space, info, mach, atoms))\r
                        return 0;\r
                break;\r
        case slang_oper_addassign:\r
-               if (!_slang_assemble_assign (file, op, "+=", reference, space, info))\r
+               if (!_slang_assemble_assign (file, op, "+=", reference, space, info, mach, atoms))\r
                        return 0;\r
                break;\r
        case slang_oper_subassign:\r
-               if (!_slang_assemble_assign (file, op, "-=", reference, space, info))\r
+               if (!_slang_assemble_assign (file, op, "-=", reference, space, info, mach, atoms))\r
                        return 0;\r
                break;\r
        case slang_oper_mulassign:\r
-               if (!_slang_assemble_assign (file, op, "*=", reference, space, info))\r
+               if (!_slang_assemble_assign (file, op, "*=", reference, space, info, mach, atoms))\r
                        return 0;\r
                break;\r
        /*case slang_oper_modassign:*/\r
@@ -869,214 +1221,149 @@ int _slang_assemble_operation (slang_assembly_file *file, slang_operation *op, i
        /*case slang_oper_xorassign:*/\r
        /*case slang_oper_andassign:*/\r
        case slang_oper_divassign:\r
-               if (!_slang_assemble_assign (file, op, "/=", reference, space, info))\r
+               if (!_slang_assemble_assign (file, op, "/=", reference, space, info, mach, atoms))\r
                        return 0;\r
                break;\r
        case slang_oper_select:\r
-               if (!_slang_assemble_select (file, op, flow, space, info))\r
+               if (!_slang_assemble_select (file, op, flow, space, info, mach, atoms))\r
                        return 0;\r
                break;\r
        case slang_oper_logicalor:\r
-               if (!_slang_assemble_logicalor (file, op, flow, space, info))\r
+               if (!_slang_assemble_logicalor (file, op, flow, space, info, mach, atoms))\r
                        return 0;\r
                break;\r
        case slang_oper_logicaland:\r
-               if (!_slang_assemble_logicaland (file, op, flow, space, info))\r
+               if (!_slang_assemble_logicaland (file, op, flow, space, info, mach, atoms))\r
                        return 0;\r
                break;\r
        case slang_oper_logicalxor:\r
-               if (!call_function_name (file, "^^", op->children, 2, 0, space, info))\r
+               if (!call_function_name (file, "^^", op->children, 2, 0, space, info, mach, atoms))\r
                        return 0;\r
                break;\r
        /*case slang_oper_bitor:*/\r
        /*case slang_oper_bitxor:*/\r
        /*case slang_oper_bitand:*/\r
        case slang_oper_less:\r
-               if (!call_function_name (file, "<", op->children, 2, 0, space, info))\r
+               if (!call_function_name (file, "<", op->children, 2, 0, space, info, mach, atoms))\r
                        return 0;\r
                break;\r
        case slang_oper_greater:\r
-               if (!call_function_name (file, ">", op->children, 2, 0, space, info))\r
+               if (!call_function_name (file, ">", op->children, 2, 0, space, info, mach, atoms))\r
                        return 0;\r
                break;\r
        case slang_oper_lessequal:\r
-               if (!call_function_name (file, "<=", op->children, 2, 0, space, info))\r
+               if (!call_function_name (file, "<=", op->children, 2, 0, space, info, mach, atoms))\r
                        return 0;\r
                break;\r
        case slang_oper_greaterequal:\r
-               if (!call_function_name (file, ">=", op->children, 2, 0, space, info))\r
+               if (!call_function_name (file, ">=", op->children, 2, 0, space, info, mach, atoms))\r
                        return 0;\r
                break;\r
        /*case slang_oper_lshift:*/\r
        /*case slang_oper_rshift:*/\r
        case slang_oper_add:\r
-               if (!call_function_name (file, "+", op->children, 2, 0, space, info))\r
+               if (!call_function_name (file, "+", op->children, 2, 0, space, info, mach, atoms))\r
                        return 0;\r
                break;\r
        case slang_oper_subtract:\r
-               if (!call_function_name (file, "-", op->children, 2, 0, space, info))\r
+               if (!call_function_name (file, "-", op->children, 2, 0, space, info, mach, atoms))\r
                        return 0;\r
                break;\r
        case slang_oper_multiply:\r
-               if (!call_function_name (file, "*", op->children, 2, 0, space, info))\r
+               if (!call_function_name (file, "*", op->children, 2, 0, space, info, mach, atoms))\r
                        return 0;\r
                break;\r
        /*case slang_oper_modulus:*/\r
        case slang_oper_divide:\r
-               if (!call_function_name (file, "/", op->children, 2, 0, space, info))\r
+               if (!call_function_name (file, "/", op->children, 2, 0, space, info, mach, atoms))\r
                        return 0;\r
                break;\r
        case slang_oper_equal:\r
                {\r
                        slang_assembly_stack_info stk;\r
-                       if (!_slang_assemble_operation (file, op->children, 0, flow, space, info, &stk))\r
+\r
+                       if (!_slang_assemble_operation (file, &op->children[0], 0, flow, space, info, &stk,\r
+                                       mach, atoms))\r
                                return 0;\r
-                       /* TODO: inspect stk */\r
-                       if (!_slang_assemble_operation (file, op->children + 1, 0, flow, space, info, &stk))\r
+                       if (!_slang_assemble_operation (file, &op->children[1], 0, flow, space, info, &stk,\r
+                                       mach, atoms))\r
                                return 0;\r
-                       /* TODO: inspect stk */\r
-                       if (!equality (file, op->children, space, info, 1))\r
+                       if (!equality (file, op->children, space, info, 1, mach, atoms))\r
                                return 0;\r
                }\r
                break;\r
        case slang_oper_notequal:\r
                {\r
                        slang_assembly_stack_info stk;\r
-                       if (!_slang_assemble_operation (file, op->children, 0, flow, space, info, &stk))\r
+\r
+                       if (!_slang_assemble_operation (file, &op->children[0], 0, flow, space, info, &stk,\r
+                                       mach, atoms))\r
                                return 0;\r
-                       /* TODO: inspect stk */\r
-                       if (!_slang_assemble_operation (file, op->children + 1, 0, flow, space, info, &stk))\r
+                       if (!_slang_assemble_operation (file, &op->children[1], 0, flow, space, info, &stk,\r
+                                       mach, atoms))\r
                                return 0;\r
-                       /* TODO: inspect stk */\r
-                       if (!equality (file, op->children, space, info, 0))\r
+                       if (!equality (file, op->children, space, info, 0, mach, atoms))\r
                                return 0;\r
                }\r
                break;\r
        case slang_oper_preincrement:\r
-               if (!_slang_assemble_assign (file, op, "++", reference, space, info))\r
+               if (!_slang_assemble_assign (file, op, "++", reference, space, info, mach, atoms))\r
                        return 0;\r
                break;\r
        case slang_oper_predecrement:\r
-               if (!_slang_assemble_assign (file, op, "--", reference, space, info))\r
+               if (!_slang_assemble_assign (file, op, "--", reference, space, info, mach, atoms))\r
                        return 0;\r
                break;\r
        case slang_oper_plus:\r
-               if (!call_function_name (file, "+", op->children, 1, 0, space, info))\r
+               if (!_slang_dereference (file, op, space, info, mach, atoms))\r
                        return 0;\r
                break;\r
        case slang_oper_minus:\r
-               if (!call_function_name (file, "-", op->children, 1, 0, space, info))\r
+               if (!call_function_name (file, "-", op->children, 1, 0, space, info, mach, atoms))\r
                        return 0;\r
                break;\r
        /*case slang_oper_complement:*/\r
        case slang_oper_not:\r
-               if (!call_function_name (file, "!", op->children, 1, 0, space, info))\r
+               if (!call_function_name (file, "!", op->children, 1, 0, space, info, mach, atoms))\r
                        return 0;\r
                break;\r
        case slang_oper_subscript:\r
                {\r
-                       slang_assembly_stack_info _stk;\r
                        slang_assembly_typeinfo ti_arr, ti_elem;\r
-                       unsigned int arr_size = 0, elem_size = 0;\r
-                       if (!_slang_assemble_operation (file, op->children, reference, flow, space, info,\r
-                               &_stk))\r
-                               return 0;\r
-                       if (!_slang_assemble_operation (file, op->children + 1, 0, flow, space, info, &_stk))\r
-                               return 0;\r
-                       slang_assembly_typeinfo_construct (&ti_arr);\r
-                       if (!_slang_typeof_operation (op->children, space, &ti_arr))\r
-                       {\r
-                               slang_assembly_typeinfo_destruct (&ti_arr);\r
-                               return 0;\r
-                       }\r
-                       if (!sizeof_variable (&ti_arr.spec, slang_qual_none, NULL, space, &arr_size))\r
-                       {\r
-                               slang_assembly_typeinfo_destruct (&ti_arr);\r
-                               return 0;\r
-                       }\r
-                       slang_assembly_typeinfo_construct (&ti_elem);\r
-                       if (!_slang_typeof_operation (op, space, &ti_elem))\r
-                       {\r
-                               slang_assembly_typeinfo_destruct (&ti_arr);\r
-                               slang_assembly_typeinfo_destruct (&ti_elem);\r
-                               return 0;\r
-                       }\r
-                       if (!sizeof_variable (&ti_elem.spec, slang_qual_none, NULL, space, &elem_size))\r
-                       {\r
-                               slang_assembly_typeinfo_destruct (&ti_arr);\r
-                               slang_assembly_typeinfo_destruct (&ti_elem);\r
-                               return 0;\r
-                       }\r
-                       if (!slang_assembly_file_push (file, slang_asm_int_to_addr))\r
-                       {\r
-                               slang_assembly_typeinfo_destruct (&ti_arr);\r
-                               slang_assembly_typeinfo_destruct (&ti_elem);\r
+\r
+                       if (!slang_assembly_typeinfo_construct (&ti_arr))\r
                                return 0;\r
-                       }\r
-                       if (!slang_assembly_file_push_label (file, slang_asm_addr_push, elem_size))\r
+                       if (!slang_assembly_typeinfo_construct (&ti_elem))\r
                        {\r
                                slang_assembly_typeinfo_destruct (&ti_arr);\r
-                               slang_assembly_typeinfo_destruct (&ti_elem);\r
                                return 0;\r
                        }\r
-                       if (!slang_assembly_file_push (file, slang_asm_addr_multiply))\r
+                       if (!handle_subscript (&ti_elem, &ti_arr, file, op, reference, flow, space, info,\r
+                                       mach, atoms))\r
                        {\r
                                slang_assembly_typeinfo_destruct (&ti_arr);\r
                                slang_assembly_typeinfo_destruct (&ti_elem);\r
                                return 0;\r
                        }\r
-                       if (reference)\r
-                       {\r
-                               if (!slang_assembly_file_push (file, slang_asm_addr_add))\r
-                               {\r
-                                       slang_assembly_typeinfo_destruct (&ti_arr);\r
-                                       slang_assembly_typeinfo_destruct (&ti_elem);\r
-                                       return 0;\r
-                               }\r
-                       }\r
-                       else\r
-                       {\r
-                               unsigned int i;\r
-                               for (i = 0; i < elem_size; i += 4)\r
-                               {\r
-                                       if (!slang_assembly_file_push_label2 (file, slang_asm_float_move,\r
-                                               arr_size - elem_size + i + 4, i + 4))\r
-                                       {\r
-                                               slang_assembly_typeinfo_destruct (&ti_arr);\r
-                                               slang_assembly_typeinfo_destruct (&ti_elem);\r
-                                               return 0;\r
-                                       }\r
-                               }\r
-                               if (!slang_assembly_file_push_label (file, slang_asm_local_free, 4))\r
-                               {\r
-                                       slang_assembly_typeinfo_destruct (&ti_arr);\r
-                                       slang_assembly_typeinfo_destruct (&ti_elem);\r
-                                       return 0;\r
-                               }\r
-                               if (!slang_assembly_file_push_label (file, slang_asm_local_free,\r
-                                       arr_size - elem_size))\r
-                               {\r
-                                       slang_assembly_typeinfo_destruct (&ti_arr);\r
-                                       slang_assembly_typeinfo_destruct (&ti_elem);\r
-                                       return 0;\r
-                               }\r
-                       }\r
                        slang_assembly_typeinfo_destruct (&ti_arr);\r
                        slang_assembly_typeinfo_destruct (&ti_elem);\r
                }\r
                break;\r
        case slang_oper_call:\r
                {\r
-                       slang_function *fun = _slang_locate_function (op->identifier, op->children,\r
-                               op->num_children, space);\r
+                       slang_function *fun;\r
+\r
+                       fun = _slang_locate_function (space->funcs, op->a_id, op->children, op->num_children,\r
+                               space, atoms);\r
                        if (fun == NULL)\r
                        {\r
-                               if (!_slang_assemble_constructor (file, op, flow, space, info))\r
-                                       return 0;\r
+/*                             if (!_slang_assemble_constructor (file, op, flow, space, info, mach))\r
+*/                                     return 0;\r
                        }\r
                        else\r
                        {\r
-                               if (!call_function (file, fun, op->children, op->num_children, 0, space, info))\r
+                               if (!_slang_call_function (file, fun, op->children, op->num_children, 0, space,\r
+                                               info, mach, atoms))\r
                                        return 0;\r
                        }\r
                }\r
@@ -1084,101 +1371,31 @@ int _slang_assemble_operation (slang_assembly_file *file, slang_operation *op, i
        case slang_oper_field:\r
                {\r
                        slang_assembly_typeinfo ti_after, ti_before;\r
-                       slang_assembly_stack_info _stk;\r
-                       slang_assembly_typeinfo_construct (&ti_after);\r
-                       if (!_slang_typeof_operation (op, space, &ti_after))\r
-                       {\r
-                               slang_assembly_typeinfo_destruct (&ti_after);\r
+\r
+                       if (!slang_assembly_typeinfo_construct (&ti_after))\r
                                return 0;\r
-                       }\r
-                       slang_assembly_typeinfo_construct (&ti_before);\r
-                       if (!_slang_typeof_operation (op->children, space, &ti_before))\r
+                       if (!slang_assembly_typeinfo_construct (&ti_before))\r
                        {\r
                                slang_assembly_typeinfo_destruct (&ti_after);\r
-                               slang_assembly_typeinfo_destruct (&ti_before);\r
                                return 0;\r
                        }\r
-                       if (!reference && ti_after.is_swizzled)\r
-                       {\r
-                               if (!slang_assembly_file_push_label2 (file, slang_asm_local_addr,\r
-                                       info->swizzle_tmp, 16))\r
-                               {\r
-                                       slang_assembly_typeinfo_destruct (&ti_after);\r
-                                       slang_assembly_typeinfo_destruct (&ti_before);\r
-                                       return 0;\r
-                               }\r
-                       }\r
-                       if (!_slang_assemble_operation (file, op->children, reference, flow, space, info,\r
-                               &_stk))\r
+                       if (!handle_field (&ti_after, &ti_before, file, op, reference, flow, space, info, stk,\r
+                                       mach, atoms))\r
                        {\r
                                slang_assembly_typeinfo_destruct (&ti_after);\r
                                slang_assembly_typeinfo_destruct (&ti_before);\r
                                return 0;\r
                        }\r
-                       /* TODO: inspect stk */\r
-                       if (ti_after.is_swizzled)\r
-                       {\r
-                               if (reference)\r
-                               {\r
-                                       if (ti_after.swz.num_components == 1)\r
-                                       {\r
-                                               if (!slang_assembly_file_push_label (file, slang_asm_addr_push,\r
-                                                       ti_after.swz.swizzle[0] * 4))\r
-                                               {\r
-                                                       slang_assembly_typeinfo_destruct (&ti_after);\r
-                                                       slang_assembly_typeinfo_destruct (&ti_before);\r
-                                                       return 0;\r
-                                               }\r
-                                               if (!slang_assembly_file_push (file, slang_asm_addr_add))\r
-                                               {\r
-                                                       slang_assembly_typeinfo_destruct (&ti_after);\r
-                                                       slang_assembly_typeinfo_destruct (&ti_before);\r
-                                                       return 0;\r
-                                               }\r
-                                       }\r
-                                       else\r
-                                       {\r
-                                               unsigned int i;\r
-                                               for (i = 0; i < ti_after.swz.num_components; i++)\r
-                                                       stk->swizzle_mask |= 1 << ti_after.swz.swizzle[i];\r
-                                       }\r
-                               }\r
-                               else\r
-                               {\r
-                                       if (!_slang_assemble_constructor_from_swizzle (file, &ti_after.swz,\r
-                                               &ti_after.spec, &ti_before.spec, info))\r
-                                       {\r
-                                               slang_assembly_typeinfo_destruct (&ti_after);\r
-                                               slang_assembly_typeinfo_destruct (&ti_before);\r
-                                               return 0;\r
-                                       }\r
-                               }\r
-                       }\r
-                       else\r
-                       {\r
-                               if (reference)\r
-                               {\r
-                                       /* TODO: struct field address */\r
-                               }\r
-                               else\r
-                               {\r
-                                       /* TODO: struct field value */\r
-                               }\r
-                       }\r
                        slang_assembly_typeinfo_destruct (&ti_after);\r
                        slang_assembly_typeinfo_destruct (&ti_before);\r
                }\r
                break;\r
        case slang_oper_postincrement:\r
-               if (!call_function_name_dummyint (file, "++", op->children, space, info))\r
-                       return 0;\r
-               if (!dereference (file, op, space, info))\r
+               if (!call_function_name_dummyint (file, "++", op->children, space, info, mach, atoms))\r
                        return 0;\r
                break;\r
        case slang_oper_postdecrement:\r
-               if (!call_function_name_dummyint (file, "--", op->children, space, info))\r
-                       return 0;\r
-               if (!dereference (file, op, space, info))\r
+               if (!call_function_name_dummyint (file, "--", op->children, space, info, mach, atoms))\r
                        return 0;\r
                break;\r
        default:\r
index d93755c..c3af8d8 100644 (file)
@@ -1,8 +1,8 @@
 /*\r
  * Mesa 3-D graphics library\r
- * Version:  6.3\r
+ * Version:  6.5\r
  *\r
- * Copyright (C) 2005  Brian Paul   All Rights Reserved.\r
+ * Copyright (C) 2005-2006  Brian Paul   All Rights Reserved.\r
  *\r
  * Permission is hereby granted, free of charge, to any person obtaining a\r
  * copy of this software and associated documentation files (the "Software"),\r
@@ -44,8 +44,16 @@ typedef enum slang_assembly_type_
        slang_asm_float_divide,\r
        slang_asm_float_negate,\r
        slang_asm_float_less,\r
-       slang_asm_float_equal,\r
+       slang_asm_float_equal_exp,\r
+       slang_asm_float_equal_int,\r
        slang_asm_float_to_int,\r
+       slang_asm_float_sine,\r
+       slang_asm_float_arcsine,\r
+       slang_asm_float_arctan,\r
+       slang_asm_float_power,\r
+       slang_asm_float_log2,\r
+       slang_asm_float_floor,\r
+       slang_asm_float_ceil,\r
        slang_asm_int_copy,\r
        slang_asm_int_move,\r
        slang_asm_int_push,\r
@@ -72,6 +80,10 @@ typedef enum slang_assembly_type_
        slang_asm_return,\r
        slang_asm_discard,\r
        slang_asm_exit,\r
+       /* mesa-specific extensions */\r
+       slang_asm_float_print,\r
+       slang_asm_int_print,\r
+       slang_asm_bool_print,\r
        slang_asm__last\r
 } slang_assembly_type;\r
 \r
@@ -86,15 +98,26 @@ typedef struct slang_assembly_file_
 {\r
        slang_assembly *code;\r
        unsigned int count;\r
+       unsigned int capacity;\r
 } slang_assembly_file;\r
 \r
-void slang_assembly_file_construct (slang_assembly_file *);\r
+int slang_assembly_file_construct (slang_assembly_file *);\r
 void slang_assembly_file_destruct (slang_assembly_file *);\r
 int slang_assembly_file_push (slang_assembly_file *, slang_assembly_type);\r
 int slang_assembly_file_push_label (slang_assembly_file *, slang_assembly_type, GLuint);\r
 int slang_assembly_file_push_label2 (slang_assembly_file *, slang_assembly_type, GLuint, GLuint);\r
 int slang_assembly_file_push_literal (slang_assembly_file *, slang_assembly_type, GLfloat);\r
 \r
+typedef struct slang_assembly_file_restore_point_\r
+{\r
+       unsigned int count;\r
+} slang_assembly_file_restore_point;\r
+\r
+int slang_assembly_file_restore_point_save (slang_assembly_file *,\r
+       slang_assembly_file_restore_point *);\r
+int slang_assembly_file_restore_point_load (slang_assembly_file *,\r
+       slang_assembly_file_restore_point *);\r
+\r
 typedef struct slang_assembly_flow_control_\r
 {\r
        unsigned int loop_start;                        /* for "continue" statement */\r
@@ -109,19 +132,31 @@ typedef struct slang_assembly_name_space_
        struct slang_variable_scope_ *vars;\r
 } slang_assembly_name_space;\r
 \r
-slang_function *_slang_locate_function (const char *name, slang_operation *params,\r
-       unsigned int num_params, slang_assembly_name_space *space);\r
+slang_function *_slang_locate_function (slang_function_scope *funcs, slang_atom a_name,\r
+       slang_operation *params, unsigned int num_params, slang_assembly_name_space *space,\r
+       slang_atom_pool *);\r
 \r
 int _slang_assemble_function (slang_assembly_file *, struct slang_function_ *,\r
-       slang_assembly_name_space *);\r
+       slang_assembly_name_space *, struct slang_machine_ *, slang_atom_pool *);\r
+\r
+/*\r
+       holds a complete information about vector swizzle - the <swizzle> array contains\r
+       vector component sources indices, where 0 is "x", 1 is "y", ...\r
+       example: "xwz" --> { 3, { 0, 3, 2, n/u } }\r
+*/\r
+typedef struct slang_swizzle_\r
+{\r
+       unsigned int num_components;\r
+       unsigned int swizzle[4];\r
+} slang_swizzle;\r
 \r
 typedef struct slang_assembly_stack_info_\r
 {\r
-       unsigned int swizzle_mask;\r
+       slang_swizzle swizzle;\r
 } slang_assembly_stack_info;\r
 \r
 int _slang_cleanup_stack (slang_assembly_file *, slang_operation *, int ref,\r
-       slang_assembly_name_space *);\r
+       slang_assembly_name_space *, struct slang_machine_ *, slang_atom_pool *);\r
 \r
 typedef struct slang_assembly_local_info_\r
 {\r
@@ -130,9 +165,12 @@ typedef struct slang_assembly_local_info_
        unsigned int swizzle_tmp;\r
 } slang_assembly_local_info;\r
 \r
+int _slang_dereference (slang_assembly_file *, slang_operation *, slang_assembly_name_space *,\r
+       slang_assembly_local_info *, struct slang_machine_ *, slang_atom_pool *);\r
+\r
 int _slang_assemble_operation (slang_assembly_file *, struct slang_operation_ *, int reference,\r
        slang_assembly_flow_control *, slang_assembly_name_space *, slang_assembly_local_info *,\r
-       slang_assembly_stack_info *);\r
+       slang_assembly_stack_info *, struct slang_machine_ *, slang_atom_pool *);\r
 \r
 #ifdef __cplusplus\r
 }\r
index d8821f0..3c35e86 100644 (file)
  */\r
 \r
 #include "imports.h"\r
+#include "slang_utility.h"\r
 #include "slang_assemble_assignment.h"\r
 #include "slang_assemble_typeinfo.h"\r
 #include "slang_storage.h"\r
-#include "slang_utility.h"\r
+#include "slang_execute.h"\r
 \r
 /*\r
        _slang_assemble_assignment()\r
                | addr of variable |\r
                +------------------+\r
 */\r
-/* TODO: add support for swizzle mask */\r
+\r
 static int assign_aggregate (slang_assembly_file *file, const slang_storage_aggregate *agg,\r
-       unsigned int *index, unsigned int size, slang_assembly_local_info *info)\r
+       unsigned int *index, unsigned int size, slang_assembly_local_info *info,\r
+       slang_assembly_stack_info *stk)\r
 {\r
        unsigned int i;\r
 \r
        for (i = 0; i < agg->count; i++)\r
        {\r
-               const slang_storage_array *arr = agg->arrays + i;\r
+               const slang_storage_array *arr = &agg->arrays[i];\r
                unsigned int j;\r
 \r
                for (j = 0; j < arr->length; j++)\r
                {\r
                        if (arr->type == slang_stor_aggregate)\r
                        {\r
-                               if (!assign_aggregate (file, arr->aggregate, index, size, info))\r
+                               if (!assign_aggregate (file, arr->aggregate, index, size, info, stk))\r
                                        return 0;\r
                        }\r
                        else\r
                        {\r
+                               unsigned int dst_addr_loc, dst_offset;\r
                                slang_assembly_type ty;\r
 \r
+                               /* calculate the distance from top of the stack to the destination address */\r
+                               dst_addr_loc = size - *index;\r
+\r
+                               /* calculate the offset within destination variable to write */\r
+                               if (stk->swizzle.num_components != 0)\r
+                               {\r
+                                       /* swizzle the index to get the actual offset */\r
+                                       dst_offset = stk->swizzle.swizzle[*index / 4] * 4;\r
+                               }\r
+                               else\r
+                               {\r
+                                       /* no swizzling - write sequentially */\r
+                                       dst_offset = *index;\r
+                               }\r
+\r
                                switch (arr->type)\r
                                {\r
                                case slang_stor_bool:\r
@@ -90,7 +108,7 @@ static int assign_aggregate (slang_assembly_file *file, const slang_storage_aggr
                                default:\r
                                        break;\r
                                }\r
-                               if (!slang_assembly_file_push_label2 (file, ty, size - *index, *index))\r
+                               if (!slang_assembly_file_push_label2 (file, ty, dst_addr_loc, dst_offset))\r
                                        return 0;\r
                                *index += 4;\r
                        }\r
@@ -100,22 +118,29 @@ static int assign_aggregate (slang_assembly_file *file, const slang_storage_aggr
 }\r
 \r
 int _slang_assemble_assignment (slang_assembly_file *file, slang_operation *op,\r
-       slang_assembly_name_space *space, slang_assembly_local_info *info)\r
+       slang_assembly_name_space *space, slang_assembly_local_info *info, slang_assembly_stack_info *stk,\r
+       struct slang_machine_ *mach, slang_atom_pool *atoms)\r
 {\r
        slang_assembly_typeinfo ti;\r
        int result;\r
        slang_storage_aggregate agg;\r
        unsigned int index, size;\r
 \r
-       slang_assembly_typeinfo_construct (&ti);\r
-       if (!_slang_typeof_operation (op, space, &ti))\r
+       if (!slang_assembly_typeinfo_construct (&ti))\r
+               return 0;\r
+       if (!_slang_typeof_operation (op, space, &ti, atoms))\r
        {\r
                slang_assembly_typeinfo_destruct (&ti);\r
                return 0;\r
        }\r
 \r
-       slang_storage_aggregate_construct (&agg);\r
-       if (!_slang_aggregate_variable (&agg, &ti.spec, NULL, space->funcs, space->structs, space->vars))\r
+       if (!slang_storage_aggregate_construct (&agg))\r
+       {\r
+               slang_assembly_typeinfo_destruct (&ti);\r
+               return 0;\r
+       }\r
+       if (!_slang_aggregate_variable (&agg, &ti.spec, NULL, space->funcs, space->structs,\r
+                       space->vars, mach, file, atoms))\r
        {\r
                slang_storage_aggregate_destruct (&agg);\r
                slang_assembly_typeinfo_destruct (&ti);\r
@@ -124,7 +149,7 @@ int _slang_assemble_assignment (slang_assembly_file *file, slang_operation *op,
 \r
        index = 0;\r
        size = _slang_sizeof_aggregate (&agg);\r
-       result = assign_aggregate (file, &agg, &index, size, info);\r
+       result = assign_aggregate (file, &agg, &index, size, info, stk);\r
 \r
        slang_storage_aggregate_destruct (&agg);\r
        slang_assembly_typeinfo_destruct (&ti);\r
@@ -138,17 +163,15 @@ int _slang_assemble_assignment (slang_assembly_file *file, slang_operation *op,
        children\r
 */\r
 \r
-int dereference (slang_assembly_file *file, slang_operation *op,\r
-       slang_assembly_name_space *space, slang_assembly_local_info *info);\r
-\r
 int call_function_name (slang_assembly_file *file, const char *name, slang_operation *params,\r
        unsigned int param_count, int assignment, slang_assembly_name_space *space,\r
-       slang_assembly_local_info *info);\r
+       slang_assembly_local_info *info, slang_machine *mach, slang_atom_pool *atoms);\r
 \r
 int _slang_assemble_assign (slang_assembly_file *file, slang_operation *op, const char *oper,\r
-       int ref, slang_assembly_name_space *space, slang_assembly_local_info *info)\r
+       int ref, slang_assembly_name_space *space, slang_assembly_local_info *info,\r
+       struct slang_machine_ *mach, slang_atom_pool *atoms)\r
 {\r
-       slang_assembly_stack_info stk;\r
+       slang_assembly_stack_info l_stk, r_stk;\r
        slang_assembly_flow_control flow;\r
 \r
        if (!ref)\r
@@ -159,16 +182,19 @@ int _slang_assemble_assign (slang_assembly_file *file, slang_operation *op, cons
 \r
        if (slang_string_compare ("=", oper) == 0)\r
        {\r
-               if (!_slang_assemble_operation (file, op->children, 1, &flow, space, info, &stk))\r
+               if (!_slang_assemble_operation (file, &op->children[0], 1, &flow, space, info, &l_stk, mach,\r
+                               atoms))\r
                        return 0;\r
-               if (!_slang_assemble_operation (file, op->children + 1, 0, &flow, space, info, &stk))\r
+               if (!_slang_assemble_operation (file, &op->children[1], 0, &flow, space, info, &r_stk, mach,\r
+                               atoms))\r
                        return 0;\r
-               if (!_slang_assemble_assignment (file, op->children, space, info))\r
+               if (!_slang_assemble_assignment (file, op->children, space, info, &l_stk, mach, atoms))\r
                        return 0;\r
        }\r
        else\r
        {\r
-               if (!call_function_name (file, oper, op->children, op->num_children, 1, space, info))\r
+               if (!call_function_name (file, oper, op->children, op->num_children, 1, space, info, mach,\r
+                               atoms))\r
                        return 0;\r
        }\r
 \r
@@ -178,7 +204,7 @@ int _slang_assemble_assign (slang_assembly_file *file, slang_operation *op, cons
                        return 0;\r
                if (!slang_assembly_file_push_label (file, slang_asm_local_free, 4))\r
                        return 0;\r
-               if (!dereference (file, op->children, space, info))\r
+               if (!_slang_dereference (file, op->children, space, info, mach, atoms))\r
                        return 0;\r
        }\r
 \r
index 06972ad..1dc48b1 100644 (file)
@@ -1,8 +1,8 @@
 /*\r
  * Mesa 3-D graphics library\r
- * Version:  6.3\r
+ * Version:  6.5\r
  *\r
- * Copyright (C) 2005  Brian Paul   All Rights Reserved.\r
+ * Copyright (C) 2005-2006  Brian Paul   All Rights Reserved.\r
  *\r
  * Permission is hereby granted, free of charge, to any person obtaining a\r
  * copy of this software and associated documentation files (the "Software"),\r
@@ -32,10 +32,12 @@ extern "C" {
 #endif\r
 \r
 int _slang_assemble_assignment (slang_assembly_file *, slang_operation *,\r
-       slang_assembly_name_space *, slang_assembly_local_info *);\r
+       slang_assembly_name_space *, slang_assembly_local_info *, slang_assembly_stack_info *,\r
+       struct slang_machine_ *, slang_atom_pool *);\r
 \r
 int _slang_assemble_assign (slang_assembly_file *, slang_operation *, const char *, int ref,\r
-       slang_assembly_name_space *, slang_assembly_local_info *);\r
+       slang_assembly_name_space *, slang_assembly_local_info *, struct slang_machine_ *,\r
+       slang_atom_pool *);\r
 \r
 #ifdef __cplusplus\r
 }\r
index 498938b..74324cf 100644 (file)
@@ -1,8 +1,8 @@
 /*\r
  * Mesa 3-D graphics library\r
- * Version:  6.3\r
+ * Version:  6.5\r
  *\r
- * Copyright (C) 2005  Brian Paul   All Rights Reserved.\r
+ * Copyright (C) 2005-2006  Brian Paul   All Rights Reserved.\r
  *\r
  * Permission is hereby granted, free of charge, to any person obtaining a\r
  * copy of this software and associated documentation files (the "Software"),\r
 #include "slang_utility.h"\r
 #include "slang_assemble_conditional.h"\r
 #include "slang_assemble.h"\r
+#include "slang_execute.h"\r
 \r
 /* _slang_assemble_logicaland() */\r
 \r
 int _slang_assemble_logicaland (slang_assembly_file *file, slang_operation *op,\r
        slang_assembly_flow_control *flow, slang_assembly_name_space *space,\r
-       slang_assembly_local_info *info)\r
+       slang_assembly_local_info *info, slang_machine *mach, slang_atom_pool *atoms)\r
 {\r
        /*\r
                and:\r
@@ -54,7 +55,7 @@ int _slang_assemble_logicaland (slang_assembly_file *file, slang_operation *op,
        slang_assembly_stack_info stk;\r
 \r
        /* evaluate left expression */\r
-       if (!_slang_assemble_operation (file, op->children, 0, flow, space, info, &stk))\r
+       if (!_slang_assemble_operation (file, &op->children[0], 0, flow, space, info, &stk, mach, atoms))\r
                return 0;\r
        /* TODO: inspect stk */\r
 \r
@@ -64,7 +65,7 @@ int _slang_assemble_logicaland (slang_assembly_file *file, slang_operation *op,
                return 0;\r
 \r
        /* evaluate right expression */\r
-       if (!_slang_assemble_operation (file, op->children + 1, 0, flow, space, info, &stk))\r
+       if (!_slang_assemble_operation (file, &op->children[1], 0, flow, space, info, &stk, mach, atoms))\r
                return 0;\r
        /* TODO: inspect stk */\r
 \r
@@ -75,7 +76,7 @@ int _slang_assemble_logicaland (slang_assembly_file *file, slang_operation *op,
 \r
        /* push 0 on stack */\r
        file->code[zero_jump].param[0] = file->count;\r
-       if (!slang_assembly_file_push (file, slang_asm_bool_push))\r
+       if (!slang_assembly_file_push_literal (file, slang_asm_bool_push, (GLfloat) 0))\r
                return 0;\r
 \r
        /* the end of the expression */\r
@@ -88,7 +89,7 @@ int _slang_assemble_logicaland (slang_assembly_file *file, slang_operation *op,
 \r
 int _slang_assemble_logicalor (slang_assembly_file *file, slang_operation *op,\r
        slang_assembly_flow_control *flow, slang_assembly_name_space *space,\r
-       slang_assembly_local_info *info)\r
+       slang_assembly_local_info *info, slang_machine *mach, slang_atom_pool *atoms)\r
 {\r
        /*\r
                or:\r
@@ -105,7 +106,7 @@ int _slang_assemble_logicalor (slang_assembly_file *file, slang_operation *op,
        slang_assembly_stack_info stk;\r
 \r
        /* evaluate left expression */\r
-       if (!_slang_assemble_operation (file, op->children, 0, flow, space, info, &stk))\r
+       if (!_slang_assemble_operation (file, &op->children[0], 0, flow, space, info, &stk, mach, atoms))\r
                return 0;\r
        /* TODO: inspect stk */\r
 \r
@@ -115,7 +116,7 @@ int _slang_assemble_logicalor (slang_assembly_file *file, slang_operation *op,
                return 0;\r
 \r
        /* push 1 on stack */\r
-       if (!slang_assembly_file_push_literal (file, slang_asm_bool_push, 1.0f))\r
+       if (!slang_assembly_file_push_literal (file, slang_asm_bool_push, (GLfloat) 1))\r
                return 0;\r
 \r
        /* jump to the end of the expression */\r
@@ -125,7 +126,7 @@ int _slang_assemble_logicalor (slang_assembly_file *file, slang_operation *op,
 \r
        /* evaluate right expression */\r
        file->code[right_jump].param[0] = file->count;\r
-       if (!_slang_assemble_operation (file, op->children + 1, 0, flow, space, info, &stk))\r
+       if (!_slang_assemble_operation (file, &op->children[1], 0, flow, space, info, &stk, mach, atoms))\r
                return 0;\r
        /* TODO: inspect stk */\r
 \r
@@ -139,7 +140,7 @@ int _slang_assemble_logicalor (slang_assembly_file *file, slang_operation *op,
 \r
 int _slang_assemble_select (slang_assembly_file *file, slang_operation *op,\r
        slang_assembly_flow_control *flow, slang_assembly_name_space *space,\r
-       slang_assembly_local_info *info)\r
+       slang_assembly_local_info *info, slang_machine *mach, slang_atom_pool *atoms)\r
 {\r
        /*\r
                select:\r
@@ -156,7 +157,7 @@ int _slang_assemble_select (slang_assembly_file *file, slang_operation *op,
        slang_assembly_stack_info stk;\r
 \r
        /* execute condition expression */\r
-       if (!_slang_assemble_operation (file, op->children, 0, flow, space, info, &stk))\r
+       if (!_slang_assemble_operation (file, &op->children[0], 0, flow, space, info, &stk, mach, atoms))\r
                return 0;\r
        /* TODO: inspect stk */\r
 \r
@@ -166,7 +167,7 @@ int _slang_assemble_select (slang_assembly_file *file, slang_operation *op,
                return 0;\r
 \r
        /* execute true expression */\r
-       if (!_slang_assemble_operation (file, op->children + 1, 0, flow, space, info, &stk))\r
+       if (!_slang_assemble_operation (file, &op->children[1], 0, flow, space, info, &stk, mach, atoms))\r
                return 0;\r
        /* TODO: inspect stk */\r
 \r
@@ -179,7 +180,7 @@ int _slang_assemble_select (slang_assembly_file *file, slang_operation *op,
        file->code[cond_jump].param[0] = file->count;\r
 \r
        /* execute false expression */\r
-       if (!_slang_assemble_operation (file, op->children + 2, 0, flow, space, info, &stk))\r
+       if (!_slang_assemble_operation (file, &op->children[2], 0, flow, space, info, &stk, mach, atoms))\r
                return 0;\r
        /* TODO: inspect stk */\r
 \r
@@ -193,7 +194,7 @@ int _slang_assemble_select (slang_assembly_file *file, slang_operation *op,
 \r
 int _slang_assemble_for (slang_assembly_file *file, slang_operation *op,\r
        slang_assembly_flow_control *flow, slang_assembly_name_space *space,\r
-       slang_assembly_local_info *info)\r
+       slang_assembly_local_info *info, slang_machine *mach, slang_atom_pool *atoms)\r
 {\r
        /*\r
                for:\r
@@ -217,10 +218,10 @@ int _slang_assemble_for (slang_assembly_file *file, slang_operation *op,
        slang_assembly_stack_info stk;\r
 \r
        /* execute initialization statement */\r
-       if (!_slang_assemble_operation (file, op->children, 0, flow, space, info, &stk))\r
+       if (!_slang_assemble_operation (file, &op->children[0], 0, flow, space, info, &stk, mach, atoms))\r
                return 0;\r
        /* TODO: pass-in stk to cleanup */\r
-       if (!_slang_cleanup_stack (file, op->children, 0, space))\r
+       if (!_slang_cleanup_stack (file, &op->children[0], 0, space, mach, atoms))\r
                return 0;\r
 \r
        /* skip the "go to the end of the loop" and loop-increment statements */\r
@@ -238,17 +239,17 @@ int _slang_assemble_for (slang_assembly_file *file, slang_operation *op,
        cont_label = file->count;\r
 \r
        /* execute loop-increment statement */\r
-       if (!_slang_assemble_operation (file, op->children + 2, 0, flow, space, info, &stk))\r
+       if (!_slang_assemble_operation (file, &op->children[2], 0, flow, space, info, &stk, mach, atoms))\r
                return 0;\r
        /* TODO: pass-in stk to cleanup */\r
-       if (!_slang_cleanup_stack (file, op->children + 2, 0, space))\r
+       if (!_slang_cleanup_stack (file, &op->children[2], 0, space, mach, atoms))\r
                return 0;\r
 \r
        /* resolve the condition point */\r
        file->code[start_jump].param[0] = file->count;\r
 \r
        /* execute condition statement */\r
-       if (!_slang_assemble_operation (file, op->children + 1, 0, flow, space, info, &stk))\r
+       if (!_slang_assemble_operation (file, &op->children[1], 0, flow, space, info, &stk, mach, atoms))\r
                return 0;\r
        /* TODO: inspect stk */\r
 \r
@@ -260,10 +261,10 @@ int _slang_assemble_for (slang_assembly_file *file, slang_operation *op,
        /* execute loop body */\r
        loop_flow.loop_start = cont_label;\r
        loop_flow.loop_end = break_label;\r
-       if (!_slang_assemble_operation (file, op->children + 3, 0, &loop_flow, space, info, &stk))\r
+       if (!_slang_assemble_operation (file, &op->children[3], 0, &loop_flow, space, info, &stk, mach, atoms))\r
                return 0;\r
        /* TODO: pass-in stk to cleanup */\r
-       if (!_slang_cleanup_stack (file, op->children + 3, 0, space))\r
+       if (!_slang_cleanup_stack (file, &op->children[3], 0, space, mach, atoms))\r
                return 0;\r
 \r
        /* go to the beginning of the loop */\r
@@ -281,7 +282,7 @@ int _slang_assemble_for (slang_assembly_file *file, slang_operation *op,
 \r
 int _slang_assemble_do (slang_assembly_file *file, slang_operation *op,\r
        slang_assembly_flow_control *flow, slang_assembly_name_space *space,\r
-       slang_assembly_local_info *info)\r
+       slang_assembly_local_info *info, slang_machine *mach, slang_atom_pool *atoms)\r
 {\r
        /*\r
                do:\r
@@ -327,17 +328,17 @@ int _slang_assemble_do (slang_assembly_file *file, slang_operation *op,
        /* execute loop body */\r
        loop_flow.loop_start = cont_label;\r
        loop_flow.loop_end = break_label;\r
-       if (!_slang_assemble_operation (file, op->children, 0, &loop_flow, space, info, &stk))\r
+       if (!_slang_assemble_operation (file, &op->children[0], 0, &loop_flow, space, info, &stk, mach, atoms))\r
                return 0;\r
        /* TODO: pass-in stk to cleanup */\r
-       if (!_slang_cleanup_stack (file, op->children, 0, space))\r
+       if (!_slang_cleanup_stack (file, &op->children[0], 0, space, mach, atoms))\r
                return 0;\r
 \r
        /* resolve condition point */\r
        file->code[cont_jump].param[0] = file->count;\r
 \r
        /* execute condition statement */\r
-       if (!_slang_assemble_operation (file, op->children + 1, 0, flow, space, info, &stk))\r
+       if (!_slang_assemble_operation (file, &op->children[1], 0, flow, space, info, &stk, mach, atoms))\r
                return 0;\r
        /* TODO: pass-in stk to cleanup */\r
 \r
@@ -361,7 +362,7 @@ int _slang_assemble_do (slang_assembly_file *file, slang_operation *op,
 \r
 int _slang_assemble_while (slang_assembly_file *file, slang_operation *op,\r
        slang_assembly_flow_control *flow, slang_assembly_name_space *space,\r
-       slang_assembly_local_info *info)\r
+       slang_assembly_local_info *info, slang_machine *mach, slang_atom_pool *atoms)\r
 {\r
        /*\r
                while:\r
@@ -396,7 +397,7 @@ int _slang_assemble_while (slang_assembly_file *file, slang_operation *op,
        file->code[skip_jump].param[0] = file->count;\r
 \r
        /* execute condition statement */\r
-       if (!_slang_assemble_operation (file, op->children, 0, flow, space, info, &stk))\r
+       if (!_slang_assemble_operation (file, &op->children[0], 0, flow, space, info, &stk, mach, atoms))\r
                return 0;\r
        /* TODO: pass-in stk to cleanup */\r
 \r
@@ -408,10 +409,10 @@ int _slang_assemble_while (slang_assembly_file *file, slang_operation *op,
        /* execute loop body */\r
        loop_flow.loop_start = file->code[skip_jump].param[0];\r
        loop_flow.loop_end = break_label;\r
-       if (!_slang_assemble_operation (file, op->children + 1, 0, &loop_flow, space, info, &stk))\r
+       if (!_slang_assemble_operation (file, &op->children[1], 0, &loop_flow, space, info, &stk, mach, atoms))\r
                return 0;\r
        /* TODO: pass-in stk to cleanup */\r
-       if (!_slang_cleanup_stack (file, op->children + 1, 0, space))\r
+       if (!_slang_cleanup_stack (file, &op->children[1], 0, space, mach, atoms))\r
                return 0;\r
 \r
        /* jump to the beginning of the loop */\r
@@ -429,7 +430,7 @@ int _slang_assemble_while (slang_assembly_file *file, slang_operation *op,
 \r
 int _slang_assemble_if (slang_assembly_file *file, slang_operation *op,\r
        slang_assembly_flow_control *flow, slang_assembly_name_space *space,\r
-       slang_assembly_local_info *info)\r
+       slang_assembly_local_info *info, slang_machine *mach, slang_atom_pool *atoms)\r
 {\r
        /*\r
                if:\r
@@ -446,7 +447,7 @@ int _slang_assemble_if (slang_assembly_file *file, slang_operation *op,
        slang_assembly_stack_info stk;\r
 \r
        /* execute condition statement */\r
-       if (!_slang_assemble_operation (file, op->children, 0, flow, space, info, &stk))\r
+       if (!_slang_assemble_operation (file, &op->children[0], 0, flow, space, info, &stk, mach, atoms))\r
                return 0;\r
        /* TODO: pass-in stk to cleanup */\r
 \r
@@ -456,10 +457,10 @@ int _slang_assemble_if (slang_assembly_file *file, slang_operation *op,
                return 0;\r
 \r
        /* execute true-statement */\r
-       if (!_slang_assemble_operation (file, op->children + 1, 0, flow, space, info, &stk))\r
+       if (!_slang_assemble_operation (file, &op->children[1], 0, flow, space, info, &stk, mach, atoms))\r
                return 0;\r
        /* TODO: pass-in stk to cleanup */\r
-       if (!_slang_cleanup_stack (file, op->children + 1, 0, space))\r
+       if (!_slang_cleanup_stack (file, &op->children[1], 0, space, mach, atoms))\r
                return 0;\r
 \r
        /* skip if-false statement */\r
@@ -471,10 +472,10 @@ int _slang_assemble_if (slang_assembly_file *file, slang_operation *op,
        file->code[cond_jump].param[0] = file->count;\r
 \r
        /* execute false-statement */\r
-       if (!_slang_assemble_operation (file, op->children + 2, 0, flow, space, info, &stk))\r
+       if (!_slang_assemble_operation (file, &op->children[2], 0, flow, space, info, &stk, mach, atoms))\r
                return 0;\r
        /* TODO: pass-in stk to cleanup */\r
-       if (!_slang_cleanup_stack (file, op->children + 2, 0, space))\r
+       if (!_slang_cleanup_stack (file, &op->children[2], 0, space, mach, atoms))\r
                return 0;\r
 \r
        /* resolve end of if-false statement */\r
index f52b412..f5aa0d4 100644 (file)
@@ -1,8 +1,8 @@
 /*\r
  * Mesa 3-D graphics library\r
- * Version:  6.3\r
+ * Version:  6.5\r
  *\r
- * Copyright (C) 2005  Brian Paul   All Rights Reserved.\r
+ * Copyright (C) 2005-2006  Brian Paul   All Rights Reserved.\r
  *\r
  * Permission is hereby granted, free of charge, to any person obtaining a\r
  * copy of this software and associated documentation files (the "Software"),\r
@@ -33,31 +33,31 @@ extern "C" {
 \r
 int _slang_assemble_logicaland (slang_assembly_file *file, slang_operation *op,\r
        slang_assembly_flow_control *flow, slang_assembly_name_space *space,\r
-       slang_assembly_local_info *info);\r
+       slang_assembly_local_info *info, struct slang_machine_ *, slang_atom_pool *);\r
 \r
 int _slang_assemble_logicalor (slang_assembly_file *file, slang_operation *op,\r
        slang_assembly_flow_control *flow, slang_assembly_name_space *space,\r
-       slang_assembly_local_info *info);\r
+       slang_assembly_local_info *info, struct slang_machine_ *, slang_atom_pool *);\r
 \r
 int _slang_assemble_select (slang_assembly_file *file, slang_operation *op,\r
        slang_assembly_flow_control *flow, slang_assembly_name_space *space,\r
-       slang_assembly_local_info *info);\r
+       slang_assembly_local_info *info, struct slang_machine_ *, slang_atom_pool *);\r
 \r
 int _slang_assemble_for (slang_assembly_file *file, slang_operation *op,\r
        slang_assembly_flow_control *flow, slang_assembly_name_space *space,\r
-       slang_assembly_local_info *info);\r
+       slang_assembly_local_info *info, struct slang_machine_ *, slang_atom_pool *);\r
 \r
 int _slang_assemble_do (slang_assembly_file *file, slang_operation *op,\r
        slang_assembly_flow_control *flow, slang_assembly_name_space *space,\r
-       slang_assembly_local_info *info);\r
+       slang_assembly_local_info *info, struct slang_machine_ *, slang_atom_pool *);\r
 \r
 int _slang_assemble_while (slang_assembly_file *file, slang_operation *op,\r
        slang_assembly_flow_control *flow, slang_assembly_name_space *space,\r
-       slang_assembly_local_info *info);\r
+       slang_assembly_local_info *info, struct slang_machine_ *, slang_atom_pool *);\r
 \r
 int _slang_assemble_if (slang_assembly_file *file, slang_operation *op,\r
        slang_assembly_flow_control *flow, slang_assembly_name_space *space,\r
-       slang_assembly_local_info *info);\r
+       slang_assembly_local_info *info, struct slang_machine_ *, slang_atom_pool *);\r
 \r
 #ifdef __cplusplus\r
 }\r
index e62f88b..aa2e019 100644 (file)
@@ -84,25 +84,23 @@ int _slang_is_swizzle (const char *field, unsigned int rows, slang_swizzle *swz)
                case 'y':\r
                case 'g':\r
                case 't':\r
-                       if (rows < 2)\r
-                               return 0;\r
                        swz->swizzle[i] = 1;\r
                        break;\r
                case 'z':\r
                case 'b':\r
                case 'p':\r
-                       if (rows < 3)\r
-                               return 0;\r
                        swz->swizzle[i] = 2;\r
                        break;\r
                case 'w':\r
                case 'a':\r
                case 'q':\r
-                       if (rows < 4)\r
-                               return 0;\r
                        swz->swizzle[i] = 3;\r
                        break;\r
                }\r
+\r
+               /* check if the component is valid for given vector's row count */\r
+               if (rows <= swz->swizzle[i])\r
+                       return 0;\r
        }\r
 \r
        /* only one swizzle group can be used */\r
@@ -116,16 +114,18 @@ int _slang_is_swizzle (const char *field, unsigned int rows, slang_swizzle *swz)
 \r
 int _slang_is_swizzle_mask (const slang_swizzle *swz, unsigned int rows)\r
 {\r
-       unsigned int c, i;\r
+       unsigned int i, c = 0;\r
 \r
+       /* the swizzle may not be longer than the vector dim */\r
        if (swz->num_components > rows)\r
                return 0;\r
-       c = swz->swizzle[0];\r
-       for (i = 1; i < swz->num_components; i++)\r
+\r
+       /* the swizzle components cannot be duplicated */\r
+       for (i = 0; i < swz->num_components; i++)\r
        {\r
-               if (swz->swizzle[i] <= c)\r
+               if ((c & (1 << swz->swizzle[i])) != 0)\r
                        return 0;\r
-               c = swz->swizzle[i];\r
+               c |= 1 << swz->swizzle[i];\r
        }\r
        return 1;\r
 }\r
@@ -136,13 +136,14 @@ void _slang_multiply_swizzles (slang_swizzle *dst, const slang_swizzle *left,
        const slang_swizzle *right)\r
 {\r
        unsigned int i;\r
+\r
        dst->num_components = right->num_components;\r
        for (i = 0; i < right->num_components; i++)\r
                dst->swizzle[i] = left->swizzle[right->swizzle[i]];\r
 }\r
 \r
 /* _slang_assemble_constructor() */\r
-\r
+/*\r
 static int constructor_aggregate (slang_assembly_file *file, const slang_storage_aggregate *flat,\r
        unsigned int *index, slang_operation *op, unsigned int size, slang_assembly_flow_control *flow,\r
        slang_assembly_name_space *space, slang_assembly_local_info *info)\r
@@ -177,10 +178,10 @@ static int constructor_aggregate (slang_assembly_file *file, const slang_storage
                if (arr1->type != arr2->type)\r
                {\r
                        /* TODO: convert (generic) from arr1 to arr2 */\r
-               }\r
+/*             }\r
                (*index)++;\r
                /* TODO: watch the index, if it reaches the size, pop off the stack subsequent values */\r
-       }\r
+/*     }\r
 \r
        result = 1;\r
 end:\r
@@ -192,38 +193,41 @@ end1:
        return result;\r
 }\r
 /* XXX: general swizzle! */\r
-int _slang_assemble_constructor (slang_assembly_file *file, slang_operation *op,\r
+/*int _slang_assemble_constructor (slang_assembly_file *file, slang_operation *op,\r
        slang_assembly_flow_control *flow, slang_assembly_name_space *space,\r
-       slang_assembly_local_info *info)\r
+       slang_assembly_local_info *info, struct slang_machine_ *pmach)\r
 {\r
        slang_assembly_typeinfo ti;\r
        int result;\r
        slang_storage_aggregate agg, flat;\r
        unsigned int size, index, i;\r
 \r
-       slang_assembly_typeinfo_construct (&ti);\r
+       if (!slang_assembly_typeinfo_construct (&ti))\r
+               return 0;\r
        if (!(result = _slang_typeof_operation (op, space, &ti)))\r
                goto end1;\r
 \r
-       slang_storage_aggregate_construct (&agg);\r
+       if (!(result = slang_storage_aggregate_construct (&agg)))\r
+               goto end1;\r
        if (!(result = _slang_aggregate_variable (&agg, &ti.spec, NULL, space->funcs, space->structs,\r
-                       space->vars)))\r
+                       space->vars, pmach, file)))\r
                goto end2;\r
 \r
        size = _slang_sizeof_aggregate (&agg);\r
 \r
-       slang_storage_aggregate_construct (&flat);\r
+       if (!(result = slang_storage_aggregate_construct (&flat)))\r
+               goto end2;\r
        if (!(result = _slang_flatten_aggregate (&flat, &agg)))\r
                goto end;\r
 \r
        index = 0;\r
        for (i = 0; i < op->num_children; i++)\r
        {\r
-               if (!(result = constructor_aggregate (file, &flat, &index, op->children + i, size, flow,\r
+/*             if (!(result = constructor_aggregate (file, &flat, &index, op->children + i, size, flow,\r
                        space, info)))\r
                        goto end;\r
                /* TODO: watch the index, if it reaches the size, raise an error */\r
-       }\r
+/*     }\r
 \r
        result = 1;\r
 end:\r
@@ -236,66 +240,34 @@ end1:
 }\r
 \r
 /* _slang_assemble_constructor_from_swizzle() */\r
-/* XXX: wrong */\r
+\r
 int _slang_assemble_constructor_from_swizzle (slang_assembly_file *file, const slang_swizzle *swz,\r
        slang_type_specifier *spec, slang_type_specifier *master_spec, slang_assembly_local_info *info)\r
 {\r
        unsigned int master_rows, i;\r
-       switch (master_spec->type)\r
-       {\r
-       case slang_spec_bool:\r
-       case slang_spec_int:\r
-       case slang_spec_float:\r
-               master_rows = 1;\r
-               break;\r
-       case slang_spec_bvec2:\r
-       case slang_spec_ivec2:\r
-       case slang_spec_vec2:\r
-               master_rows = 2;\r
-               break;\r
-       case slang_spec_bvec3:\r
-       case slang_spec_ivec3:\r
-       case slang_spec_vec3:\r
-               master_rows = 3;\r
-               break;\r
-       case slang_spec_bvec4:\r
-       case slang_spec_ivec4:\r
-       case slang_spec_vec4:\r
-               master_rows = 4;\r
-               break;\r
-       default:\r
-          break;\r
-       }\r
+\r
+       master_rows = _slang_type_dim (master_spec->type);\r
        for (i = 0; i < master_rows; i++)\r
        {\r
-               switch (master_spec->type)\r
+               switch (_slang_type_base (master_spec->type))\r
                {\r
                case slang_spec_bool:\r
-               case slang_spec_bvec2:\r
-               case slang_spec_bvec3:\r
-               case slang_spec_bvec4:\r
-                       if (!slang_assembly_file_push_label2 (file, slang_asm_bool_copy, (master_rows - i) * 4,\r
-                               i * 4))\r
+                       if (!slang_assembly_file_push_label2 (file, slang_asm_bool_copy,\r
+                                       (master_rows - i) * 4, i * 4))\r
                                return 0;\r
                        break;\r
                case slang_spec_int:\r
-               case slang_spec_ivec2:\r
-               case slang_spec_ivec3:\r
-               case slang_spec_ivec4:\r
-                       if (!slang_assembly_file_push_label2 (file, slang_asm_int_copy, (master_rows - i) * 4,\r
-                               i * 4))\r
+                       if (!slang_assembly_file_push_label2 (file, slang_asm_int_copy,\r
+                                       (master_rows - i) * 4, i * 4))\r
                                return 0;\r
                        break;\r
                case slang_spec_float:\r
-               case slang_spec_vec2:\r
-               case slang_spec_vec3:\r
-               case slang_spec_vec4:\r
                        if (!slang_assembly_file_push_label2 (file, slang_asm_float_copy,\r
-                               (master_rows - i) * 4, i * 4))\r
+                                       (master_rows - i) * 4, i * 4))\r
                                return 0;\r
                        break;\r
                default:\r
-                     break;\r
+                       break;\r
                }\r
        }\r
        if (!slang_assembly_file_push_label (file, slang_asm_local_free, 4))\r
@@ -303,37 +275,29 @@ int _slang_assemble_constructor_from_swizzle (slang_assembly_file *file, const s
        for (i = swz->num_components; i > 0; i--)\r
        {\r
                unsigned int n = i - 1;\r
+\r
                if (!slang_assembly_file_push_label2 (file, slang_asm_local_addr, info->swizzle_tmp, 16))\r
                        return 0;\r
                if (!slang_assembly_file_push_label (file, slang_asm_addr_push, swz->swizzle[n] * 4))\r
                        return 0;\r
                if (!slang_assembly_file_push (file, slang_asm_addr_add))\r
                        return 0;\r
-               switch (master_spec->type)\r
+               switch (_slang_type_base (master_spec->type))\r
                {\r
                case slang_spec_bool:\r
-               case slang_spec_bvec2:\r
-               case slang_spec_bvec3:\r
-               case slang_spec_bvec4:\r
                        if (!slang_assembly_file_push (file, slang_asm_bool_deref))\r
                                return 0;\r
                        break;\r
                case slang_spec_int:\r
-               case slang_spec_ivec2:\r
-               case slang_spec_ivec3:\r
-               case slang_spec_ivec4:\r
                        if (!slang_assembly_file_push (file, slang_asm_int_deref))\r
                                return 0;\r
                        break;\r
                case slang_spec_float:\r
-               case slang_spec_vec2:\r
-               case slang_spec_vec3:\r
-               case slang_spec_vec4:\r
                        if (!slang_assembly_file_push (file, slang_asm_float_deref))\r
                                return 0;\r
                        break;\r
                default:\r
-                  break;\r
+                       break;\r
                }\r
        }\r
        return 1;\r
index f8a0fea..b87e9cc 100644 (file)
@@ -1,8 +1,8 @@
 /*\r
  * Mesa 3-D graphics library\r
- * Version:  6.3\r
+ * Version:  6.5\r
  *\r
- * Copyright (C) 2005  Brian Paul   All Rights Reserved.\r
+ * Copyright (C) 2005-2006  Brian Paul   All Rights Reserved.\r
  *\r
  * Permission is hereby granted, free of charge, to any person obtaining a\r
  * copy of this software and associated documentation files (the "Software"),\r
@@ -33,17 +33,6 @@ extern "C" {
 #endif\r
 \r
 /*\r
-       holds a complete information about vector swizzle - the <swizzle> array contains\r
-       vector component sources indices, where 0 is "x", 1 is "y", ...\r
-       example: "xwz" --> { 3, { 0, 3, 2, n/u } }\r
-*/\r
-typedef struct slang_swizzle_\r
-{\r
-       unsigned int num_components;\r
-       unsigned int swizzle[4];\r
-} slang_swizzle;\r
-\r
-/*\r
        checks if a field selector is a general swizzle (an r-value swizzle with replicated\r
        components or an l-value swizzle mask) for a vector\r
        returns 1 if this is the case, <swz> is filled with swizzle information\r
@@ -67,7 +56,7 @@ void _slang_multiply_swizzles (slang_swizzle *, const slang_swizzle *, const sla
 \r
 int _slang_assemble_constructor (slang_assembly_file *file, slang_operation *op,\r
        slang_assembly_flow_control *flow, slang_assembly_name_space *space,\r
-       slang_assembly_local_info *info);\r
+       slang_assembly_local_info *info, struct slang_machine_ *);\r
 \r
 int _slang_assemble_constructor_from_swizzle (slang_assembly_file *file, const slang_swizzle *swz,\r
        slang_type_specifier *spec, slang_type_specifier *master_spec, slang_assembly_local_info *info);\r
index f550556..778ba04 100644 (file)
 \r
 /* slang_assembly_typeinfo */\r
 \r
-void slang_assembly_typeinfo_construct (slang_assembly_typeinfo *ti)\r
+int slang_assembly_typeinfo_construct (slang_assembly_typeinfo *ti)\r
 {\r
-       slang_type_specifier_construct (&ti->spec);\r
+       if (!slang_type_specifier_construct (&ti->spec))\r
+               return 0;\r
+       ti->array_size = NULL;\r
+       return 1;\r
 }\r
 \r
 void slang_assembly_typeinfo_destruct (slang_assembly_typeinfo *ti)\r
 {\r
        slang_type_specifier_destruct (&ti->spec);\r
+       /* do not free ti->array_size */\r
 }\r
 \r
 /* _slang_typeof_operation() */\r
 \r
+static int typeof_existing_function (const char *name, slang_operation *params,\r
+       unsigned int num_params, slang_assembly_name_space *space, slang_type_specifier *spec,\r
+       slang_atom_pool *atoms)\r
+{\r
+       slang_atom atom;\r
+       int exists;\r
+\r
+       atom = slang_atom_pool_atom (atoms, name);\r
+       if (!_slang_typeof_function (atom, params, num_params, space, spec, &exists, atoms))\r
+               return 0;\r
+       return exists;\r
+}\r
+\r
 int _slang_typeof_operation (slang_operation *op, slang_assembly_name_space *space,\r
-       slang_assembly_typeinfo *ti)\r
+       slang_assembly_typeinfo *ti, slang_atom_pool *atoms)\r
 {\r
        ti->can_be_referenced = 0;\r
        ti->is_swizzled = 0;\r
@@ -77,7 +94,7 @@ int _slang_typeof_operation (slang_operation *op, slang_assembly_name_space *spa
        case slang_oper_divassign:\r
        case slang_oper_preincrement:\r
        case slang_oper_predecrement:\r
-               if (!_slang_typeof_operation (op->children, space, ti))\r
+               if (!_slang_typeof_operation (op->children, space, ti, atoms))\r
                        return 0;\r
                break;\r
        case slang_oper_literal_bool:\r
@@ -103,17 +120,18 @@ int _slang_typeof_operation (slang_operation *op, slang_assembly_name_space *spa
                {\r
                        slang_variable *var;\r
 \r
-                       var = _slang_locate_variable (op->locals, op->identifier, 1);\r
+                       var = _slang_locate_variable (op->locals, op->a_id, 1);\r
                        if (var == NULL)\r
                                return 0;\r
                        if (!slang_type_specifier_copy (&ti->spec, &var->type.specifier))\r
                                return 0;\r
                        ti->can_be_referenced = 1;\r
+                       ti->array_size = var->array_size;\r
                }\r
                break;\r
        case slang_oper_sequence:\r
                /* TODO: check [0] and [1] if they match */\r
-               if (!_slang_typeof_operation (op->children + 1, space, ti))\r
+               if (!_slang_typeof_operation (&op->children[1], space, ti, atoms))\r
                        return 0;\r
                ti->can_be_referenced = 0;\r
                ti->is_swizzled = 0;\r
@@ -126,7 +144,7 @@ int _slang_typeof_operation (slang_operation *op, slang_assembly_name_space *spa
        /*case slang_oper_andassign:*/\r
        case slang_oper_select:\r
                /* TODO: check [1] and [2] if they match */\r
-               if (!_slang_typeof_operation (op->children + 1, space, ti))\r
+               if (!_slang_typeof_operation (&op->children[1], space, ti, atoms))\r
                        return 0;\r
                ti->can_be_referenced = 0;\r
                ti->is_swizzled = 0;\r
@@ -137,107 +155,61 @@ int _slang_typeof_operation (slang_operation *op, slang_assembly_name_space *spa
        /*case slang_oper_lshift:*/\r
        /*case slang_oper_rshift:*/\r
        case slang_oper_add:\r
-               {\r
-                       int exists;\r
-                       if (!_slang_typeof_function ("+", op->children, 2, space, &ti->spec, &exists))\r
-                               return 0;\r
-                       if (!exists)\r
-                               return 0;\r
-               }\r
+               if (!typeof_existing_function ("+", op->children, 2, space, &ti->spec, atoms))\r
+                       return 0;\r
                break;\r
        case slang_oper_subtract:\r
-               {\r
-                       int exists;\r
-                       if (!_slang_typeof_function ("-", op->children, 2, space, &ti->spec, &exists))\r
-                               return 0;\r
-                       if (!exists)\r
-                               return 0;\r
-               }\r
+               if (!typeof_existing_function ("-", op->children, 2, space, &ti->spec, atoms))\r
+                       return 0;\r
                break;\r
        case slang_oper_multiply:\r
-               {\r
-                       int exists;\r
-                       if (!_slang_typeof_function ("*", op->children, 2, space, &ti->spec, &exists))\r
-                               return 0;\r
-                       if (!exists)\r
-                               return 0;\r
-               }\r
+               if (!typeof_existing_function ("*", op->children, 2, space, &ti->spec, atoms))\r
+                       return 0;\r
                break;\r
        case slang_oper_divide:\r
-               {\r
-                       int exists;\r
-                       if (!_slang_typeof_function ("/", op->children, 2, space, &ti->spec, &exists))\r
-                               return 0;\r
-                       if (!exists)\r
-                               return 0;\r
-               }\r
+               if (!typeof_existing_function ("/", op->children, 2, space, &ti->spec, atoms))\r
+                       return 0;\r
                break;\r
        /*case slang_oper_modulus:*/\r
        case slang_oper_plus:\r
-               {\r
-                       int exists;\r
-                       if (!_slang_typeof_function ("+", op->children, 1, space, &ti->spec, &exists))\r
-                               return 0;\r
-                       if (!exists)\r
-                               return 0;\r
-               }\r
+               if (!_slang_typeof_operation (op->children, space, ti, atoms))\r
+                       return 0;\r
+               ti->can_be_referenced = 0;\r
+               ti->is_swizzled = 0;\r
                break;\r
        case slang_oper_minus:\r
-               {\r
-                       int exists;\r
-                       if (!_slang_typeof_function ("-", op->children, 1, space, &ti->spec, &exists))\r
-                               return 0;\r
-                       if (!exists)\r
-                               return 0;\r
-               }\r
+               if (!typeof_existing_function ("-", op->children, 1, space, &ti->spec, atoms))\r
+                       return 0;\r
                break;\r
        /*case slang_oper_complement:*/\r
        case slang_oper_subscript:\r
                {\r
                        slang_assembly_typeinfo _ti;\r
-                       slang_assembly_typeinfo_construct (&_ti);\r
-                       if (!_slang_typeof_operation (op->children, space, &_ti))\r
+\r
+                       if (!slang_assembly_typeinfo_construct (&_ti))\r
+                               return 0;\r
+                       if (!_slang_typeof_operation (op->children, space, &_ti, atoms))\r
                        {\r
                                slang_assembly_typeinfo_destruct (&_ti);\r
                                return 0;\r
                        }\r
                        ti->can_be_referenced = _ti.can_be_referenced;\r
-                       switch (_ti.spec.type)\r
+                       if (_ti.spec.type == slang_spec_array)\r
                        {\r
-                       case slang_spec_bvec2:\r
-                       case slang_spec_bvec3:\r
-                       case slang_spec_bvec4:\r
-                               ti->spec.type = slang_spec_bool;\r
-                               break;\r
-                       case slang_spec_ivec2:\r
-                       case slang_spec_ivec3:\r
-                       case slang_spec_ivec4:\r
-                               ti->spec.type = slang_spec_int;\r
-                               break;\r
-                       case slang_spec_vec2:\r
-                       case slang_spec_vec3:\r
-                       case slang_spec_vec4:\r
-                               ti->spec.type = slang_spec_float;\r
-                               break;\r
-                       case slang_spec_mat2:\r
-                               ti->spec.type = slang_spec_vec2;\r
-                               break;\r
-                       case slang_spec_mat3:\r
-                               ti->spec.type = slang_spec_vec3;\r
-                               break;\r
-                       case slang_spec_mat4:\r
-                               ti->spec.type = slang_spec_vec4;\r
-                               break;\r
-                       case slang_spec_array:\r
                                if (!slang_type_specifier_copy (&ti->spec, _ti.spec._array))\r
                                {\r
                                        slang_assembly_typeinfo_destruct (&_ti);\r
                                        return 0;\r
                                }\r
-                               break;\r
-                       default:\r
-                               slang_assembly_typeinfo_destruct (&_ti);\r
-                               return 0;\r
+                       }\r
+                       else\r
+                       {\r
+                               if (!_slang_type_is_vector (_ti.spec.type) && !_slang_type_is_matrix (_ti.spec.type))\r
+                               {\r
+                                       slang_assembly_typeinfo_destruct (&_ti);\r
+                                       return 0;\r
+                               }\r
+                               ti->spec.type = _slang_type_base (_ti.spec.type);\r
                        }\r
                        slang_assembly_typeinfo_destruct (&_ti);\r
                }\r
@@ -245,12 +217,13 @@ int _slang_typeof_operation (slang_operation *op, slang_assembly_name_space *spa
        case slang_oper_call:\r
                {\r
                        int exists;\r
-                       if (!_slang_typeof_function (op->identifier, op->children, op->num_children, space,\r
-                               &ti->spec, &exists))\r
+\r
+                       if (!_slang_typeof_function (op->a_id, op->children, op->num_children, space, &ti->spec,\r
+                                       &exists, atoms))\r
                                return 0;\r
                        if (!exists)\r
                        {\r
-                               slang_struct *s = slang_struct_scope_find (space->structs, op->identifier, 1);\r
+/*                             slang_struct *s = slang_struct_scope_find (space->structs, op->identifier, 1);\r
                                if (s != NULL)\r
                                {\r
                                        ti->spec.type = slang_spec_struct;\r
@@ -267,9 +240,12 @@ int _slang_typeof_operation (slang_operation *op, slang_assembly_name_space *spa
                                                return 0;\r
                                }\r
                                else\r
-                               {\r
-                                       slang_type_specifier_type type = slang_type_specifier_type_from_string (\r
-                                               op->identifier);\r
+*/                             {\r
+                                       const char *name;\r
+                                       slang_type_specifier_type type;\r
+\r
+                                       name = slang_atom_pool_id (atoms, op->a_id);\r
+                                       type = slang_type_specifier_type_from_string (name);\r
                                        if (type == slang_spec_void)\r
                                                return 0;\r
                                        ti->spec.type = type;\r
@@ -280,16 +256,19 @@ int _slang_typeof_operation (slang_operation *op, slang_assembly_name_space *spa
        case slang_oper_field:\r
                {\r
                        slang_assembly_typeinfo _ti;\r
-                       slang_assembly_typeinfo_construct (&_ti);\r
-                       if (!_slang_typeof_operation (op->children, space, &_ti))\r
+\r
+                       if (!slang_assembly_typeinfo_construct (&_ti))\r
+                               return 0;\r
+                       if (!_slang_typeof_operation (op->children, space, &_ti, atoms))\r
                        {\r
                                slang_assembly_typeinfo_destruct (&_ti);\r
                                return 0;\r
                        }\r
                        if (_ti.spec.type == slang_spec_struct)\r
                        {\r
-                               slang_variable *field = _slang_locate_variable (_ti.spec._struct->fields,\r
-                                       op->identifier, 0);\r
+                               slang_variable *field;\r
+                               \r
+                               field = _slang_locate_variable (_ti.spec._struct->fields, op->a_id, 0);\r
                                if (field == NULL)\r
                                {\r
                                        slang_assembly_typeinfo_destruct (&_ti);\r
@@ -300,112 +279,96 @@ int _slang_typeof_operation (slang_operation *op, slang_assembly_name_space *spa
                                        slang_assembly_typeinfo_destruct (&_ti);\r
                                        return 0;\r
                                }\r
+                               ti->can_be_referenced = _ti.can_be_referenced;\r
                        }\r
                        else\r
                        {\r
                                unsigned int rows;\r
-                               switch (_ti.spec.type)\r
+                               const char *swizzle;\r
+                               slang_type_specifier_type base;\r
+\r
+                               /* determine the swizzle of the field expression */\r
+                               if (!_slang_type_is_vector (_ti.spec.type))\r
                                {\r
-                               case slang_spec_vec2:\r
-                               case slang_spec_ivec2:\r
-                               case slang_spec_bvec2:\r
-                                       rows = 2;\r
-                                       break;\r
-                               case slang_spec_vec3:\r
-                               case slang_spec_ivec3:\r
-                               case slang_spec_bvec3:\r
-                                       rows = 3;\r
-                                       break;\r
-                               case slang_spec_vec4:\r
-                               case slang_spec_ivec4:\r
-                               case slang_spec_bvec4:\r
-                                       rows = 4;\r
-                                       break;\r
-                               default:\r
                                        slang_assembly_typeinfo_destruct (&_ti);\r
                                        return 0;\r
                                }\r
-                               if (!_slang_is_swizzle (op->identifier, rows, &ti->swz))\r
+                               rows = _slang_type_dim (_ti.spec.type);\r
+                               swizzle = slang_atom_pool_id (atoms, op->a_id);\r
+                               if (!_slang_is_swizzle (swizzle, rows, &ti->swz))\r
+                               {\r
+                                       slang_assembly_typeinfo_destruct (&_ti);\r
                                        return 0;\r
+                               }\r
                                ti->is_swizzled = 1;\r
                                ti->can_be_referenced = _ti.can_be_referenced && _slang_is_swizzle_mask (&ti->swz,\r
                                        rows);\r
                                if (_ti.is_swizzled)\r
                                {\r
                                        slang_swizzle swz;\r
+\r
+                                       /* swizzle the swizzle */\r
                                        _slang_multiply_swizzles (&swz, &_ti.swz, &ti->swz);\r
                                        ti->swz = swz;\r
                                }\r
-                               switch (_ti.spec.type)\r
+                               base = _slang_type_base (_ti.spec.type);\r
+                               switch (ti->swz.num_components)\r
                                {\r
-                               case slang_spec_vec2:\r
-                               case slang_spec_vec3:\r
-                               case slang_spec_vec4:\r
-                                       switch (ti->swz.num_components)\r
+                               case 1:\r
+                                       ti->spec.type = base;\r
+                                       break;\r
+                               case 2:\r
+                                       switch (base)\r
                                        {\r
-                                       case 1:\r
-                                               ti->spec.type = slang_spec_float;\r
-                                               break;\r
-                                       case 2:\r
+                                       case slang_spec_float:\r
                                                ti->spec.type = slang_spec_vec2;\r
                                                break;\r
-                                       case 3:\r
-                                               ti->spec.type = slang_spec_vec3;\r
+                                       case slang_spec_int:\r
+                                               ti->spec.type = slang_spec_ivec2;\r
                                                break;\r
-                                       case 4:\r
-                                               ti->spec.type = slang_spec_vec4;\r
+                                       case slang_spec_bool:\r
+                                               ti->spec.type = slang_spec_bvec2;\r
                                                break;\r
                                        }\r
                                        break;\r
-                               case slang_spec_ivec2:\r
-                               case slang_spec_ivec3:\r
-                               case slang_spec_ivec4:\r
-                                       switch (ti->swz.num_components)\r
+                               case 3:\r
+                                       switch (base)\r
                                        {\r
-                                       case 1:\r
-                                               ti->spec.type = slang_spec_int;\r
-                                               break;\r
-                                       case 2:\r
-                                               ti->spec.type = slang_spec_ivec2;\r
+                                       case slang_spec_float:\r
+                                               ti->spec.type = slang_spec_vec3;\r
                                                break;\r
-                                       case 3:\r
+                                       case slang_spec_int:\r
                                                ti->spec.type = slang_spec_ivec3;\r
                                                break;\r
-                                       case 4:\r
-                                               ti->spec.type = slang_spec_ivec4;\r
+                                       case slang_spec_bool:\r
+                                               ti->spec.type = slang_spec_bvec3;\r
                                                break;\r
                                        }\r
                                        break;\r
-                               case slang_spec_bvec2:\r
-                               case slang_spec_bvec3:\r
-                               case slang_spec_bvec4:\r
-                                       switch (ti->swz.num_components)\r
+                               case 4:\r
+                                       switch (base)\r
                                        {\r
-                                       case 1:\r
-                                               ti->spec.type = slang_spec_bool;\r
-                                               break;\r
-                                       case 2:\r
-                                               ti->spec.type = slang_spec_bvec2;\r
+                                       case slang_spec_float:\r
+                                               ti->spec.type = slang_spec_vec4;\r
                                                break;\r
-                                       case 3:\r
-                                               ti->spec.type = slang_spec_bvec3;\r
+                                       case slang_spec_int:\r
+                                               ti->spec.type = slang_spec_ivec4;\r
                                                break;\r
-                                       case 4:\r
+                                       case slang_spec_bool:\r
                                                ti->spec.type = slang_spec_bvec4;\r
                                                break;\r
                                        }\r
                                        break;\r
                                default:\r
-                                  break;\r
+                                       break;\r
                                }\r
                        }\r
                        slang_assembly_typeinfo_destruct (&_ti);\r
-                       return 1;\r
                }\r
                break;\r
        case slang_oper_postincrement:\r
        case slang_oper_postdecrement:\r
-               if (!_slang_typeof_operation (op->children, space, ti))\r
+               if (!_slang_typeof_operation (op->children, space, ti, atoms))\r
                        return 0;\r
                ti->can_be_referenced = 0;\r
                ti->is_swizzled = 0;\r
@@ -418,13 +381,113 @@ int _slang_typeof_operation (slang_operation *op, slang_assembly_name_space *spa
 \r
 /* _slang_typeof_function() */\r
 \r
-int _slang_typeof_function (const char *name, slang_operation *params, unsigned int num_params,\r
-       slang_assembly_name_space *space, slang_type_specifier *spec, int *exists)\r
+int _slang_typeof_function (slang_atom a_name, slang_operation *params, unsigned int num_params,\r
+       slang_assembly_name_space *space, slang_type_specifier *spec, int *exists, slang_atom_pool *atoms)\r
 {\r
-       slang_function *fun = _slang_locate_function (name, params, num_params, space);\r
+       slang_function *fun;\r
+       \r
+       fun = _slang_locate_function (space->funcs, a_name, params, num_params, space, atoms);\r
        *exists = fun != NULL;\r
        if (fun == NULL)\r
                return 1;\r
        return slang_type_specifier_copy (spec, &fun->header.type.specifier);\r
 }\r
 \r
+/* _slang_type_is_matrix() */\r
+\r
+int _slang_type_is_matrix (slang_type_specifier_type ty)\r
+{\r
+       switch (ty)\r
+       {\r
+       case slang_spec_mat2:\r
+       case slang_spec_mat3:\r
+       case slang_spec_mat4:\r
+               return 1;\r
+       default:\r
+               return 0;\r
+       }\r
+}\r
+\r
+/* _slang_type_is_vector() */\r
+\r
+int _slang_type_is_vector (slang_type_specifier_type ty)\r
+{\r
+       switch (ty)\r
+       {\r
+       case slang_spec_vec2:\r
+       case slang_spec_vec3:\r
+       case slang_spec_vec4:\r
+       case slang_spec_ivec2:\r
+       case slang_spec_ivec3:\r
+       case slang_spec_ivec4:\r
+       case slang_spec_bvec2:\r
+       case slang_spec_bvec3:\r
+       case slang_spec_bvec4:\r
+               return 1;\r
+       default:\r
+               return 0;\r
+       }\r
+}\r
+\r
+/* _slang_type_base_of_vector() */\r
+\r
+slang_type_specifier_type _slang_type_base (slang_type_specifier_type ty)\r
+{\r
+       switch (ty)\r
+       {\r
+       case slang_spec_float:\r
+       case slang_spec_vec2:\r
+       case slang_spec_vec3:\r
+       case slang_spec_vec4:\r
+               return slang_spec_float;\r
+       case slang_spec_int:\r
+       case slang_spec_ivec2:\r
+       case slang_spec_ivec3:\r
+       case slang_spec_ivec4:\r
+               return slang_spec_int;\r
+       case slang_spec_bool:\r
+       case slang_spec_bvec2:\r
+       case slang_spec_bvec3:\r
+       case slang_spec_bvec4:\r
+               return slang_spec_bool;\r
+       case slang_spec_mat2:\r
+               return slang_spec_vec2;\r
+       case slang_spec_mat3:\r
+               return slang_spec_vec3;\r
+       case slang_spec_mat4:\r
+               return slang_spec_vec4;\r
+       default:\r
+               return slang_spec_void;\r
+       }\r
+}\r
+\r
+/* _slang_type_dim */\r
+\r
+unsigned int _slang_type_dim (slang_type_specifier_type ty)\r
+{\r
+       switch (ty)\r
+       {\r
+       case slang_spec_float:\r
+       case slang_spec_int:\r
+       case slang_spec_bool:\r
+               return 1;\r
+       case slang_spec_vec2:\r
+       case slang_spec_ivec2:\r
+       case slang_spec_bvec2:\r
+       case slang_spec_mat2:\r
+               return 2;\r
+       case slang_spec_vec3:\r
+       case slang_spec_ivec3:\r
+       case slang_spec_bvec3:\r
+       case slang_spec_mat3:\r
+               return 3;\r
+       case slang_spec_vec4:\r
+       case slang_spec_ivec4:\r
+       case slang_spec_bvec4:\r
+       case slang_spec_mat4:\r
+               return 4;\r
+       default:\r
+               return 0;\r
+       }\r
+}\r
+\r
index 1c18394..cd16440 100644 (file)
@@ -1,8 +1,8 @@
 /*\r
  * Mesa 3-D graphics library\r
- * Version:  6.3\r
+ * Version:  6.5\r
  *\r
- * Copyright (C) 2005  Brian Paul   All Rights Reserved.\r
+ * Copyright (C) 2005-2006  Brian Paul   All Rights Reserved.\r
  *\r
  * Permission is hereby granted, free of charge, to any person obtaining a\r
  * copy of this software and associated documentation files (the "Software"),\r
@@ -38,9 +38,10 @@ typedef struct slang_assembly_typeinfo_
        int is_swizzled;\r
        slang_swizzle swz;\r
        slang_type_specifier spec;\r
+       slang_operation *array_size;\r
 } slang_assembly_typeinfo;\r
 \r
-void slang_assembly_typeinfo_construct (slang_assembly_typeinfo *);\r
+int slang_assembly_typeinfo_construct (slang_assembly_typeinfo *);\r
 void slang_assembly_typeinfo_destruct (slang_assembly_typeinfo *);\r
 \r
 /*\r
@@ -49,15 +50,20 @@ void slang_assembly_typeinfo_destruct (slang_assembly_typeinfo *);
        returns 0 otherwise\r
 */\r
 int _slang_typeof_operation (slang_operation *, slang_assembly_name_space *,\r
-       slang_assembly_typeinfo *);\r
+       slang_assembly_typeinfo *, slang_atom_pool *);\r
 \r
 /*\r
        retrieves type of a function prototype, if one exists\r
        returns 1 on success, even if the function was not found\r
        returns 0 otherwise\r
 */\r
-int _slang_typeof_function (const char *name, slang_operation *params, unsigned int num_params,\r
-       slang_assembly_name_space *space, slang_type_specifier *spec, int *exists);\r
+int _slang_typeof_function (slang_atom a_name, slang_operation *params, unsigned int num_params,\r
+       slang_assembly_name_space *space, slang_type_specifier *spec, int *exists, slang_atom_pool *);\r
+\r
+int _slang_type_is_matrix (slang_type_specifier_type);\r
+int _slang_type_is_vector (slang_type_specifier_type);\r
+slang_type_specifier_type _slang_type_base (slang_type_specifier_type);\r
+unsigned int _slang_type_dim (slang_type_specifier_type);\r
 \r
 #ifdef __cplusplus\r
 }\r
index ce5653c..1124320 100644 (file)
@@ -59,30 +59,83 @@ static GLuint slang_var_pool_alloc (slang_var_pool *pool, unsigned int size)
 
 int slang_translation_unit_construct (slang_translation_unit *unit)
 {
-       if (!slang_variable_scope_construct (&unit->globals))\r
+       unit->assembly = (slang_assembly_file *) slang_alloc_malloc (sizeof (slang_assembly_file));\r
+       if (unit->assembly == NULL)\r
                return 0;\r
-       if (!slang_function_scope_construct (&unit->functions))\r
+       if (!slang_assembly_file_construct (unit->assembly))\r
        {\r
-               slang_variable_scope_destruct (&unit->globals);\r
+               slang_alloc_free (unit->assembly);\r
                return 0;\r
-       }
-       if (!slang_struct_scope_construct (&unit->structs))\r
+       }\r
+       unit->global_pool = (slang_var_pool *) slang_alloc_malloc (sizeof (slang_var_pool));\r
+       if (unit->global_pool == NULL)\r
+       {\r
+               slang_assembly_file_destruct (unit->assembly);\r
+               slang_alloc_free (unit->assembly);\r
+               return 0;\r
+       }\r
+       unit->global_pool->next_addr = 0;\r
+       unit->machine = (slang_machine *) slang_alloc_malloc (sizeof (slang_machine));\r
+       if (unit->machine == NULL)\r
+       {\r
+               slang_alloc_free (unit->global_pool);\r
+               slang_assembly_file_destruct (unit->assembly);\r
+               slang_alloc_free (unit->assembly);\r
+               return 0;\r
+       }\r
+       slang_machine_init (unit->machine);\r
+       unit->atom_pool = (slang_atom_pool *) slang_alloc_malloc (sizeof (slang_atom_pool));\r
+       if (unit->atom_pool == NULL)\r
+       {\r
+               slang_alloc_free (unit->machine);\r
+               slang_alloc_free (unit->global_pool);\r
+               slang_assembly_file_destruct (unit->assembly);\r
+               slang_alloc_free (unit->assembly);\r
+               return 0;\r
+       }\r
+       slang_atom_pool_construct (unit->atom_pool);\r
+       if (!slang_translation_unit_construct2 (unit, unit->assembly, unit->global_pool, unit->machine,\r
+                       unit->atom_pool))\r
+       {\r
+               slang_alloc_free (unit->atom_pool);\r
+               slang_alloc_free (unit->machine);\r
+               slang_alloc_free (unit->global_pool);\r
+               slang_assembly_file_destruct (unit->assembly);\r
+               slang_alloc_free (unit->assembly);\r
+               return 0;\r
+       }\r
+       unit->free_assembly = 1;\r
+       unit->free_global_pool = 1;\r
+       unit->free_machine = 1;\r
+       unit->free_atom_pool = 1;\r
+       return 1;
+}\r
+\r
+int slang_translation_unit_construct2 (slang_translation_unit *unit, slang_assembly_file *file,\r
+       slang_var_pool *pool, struct slang_machine_ *mach, slang_atom_pool *atoms)\r
+{\r
+       if (!slang_variable_scope_construct (&unit->globals))\r
+               return 0;\r
+       if (!slang_function_scope_construct (&unit->functions))\r
        {\r
                slang_variable_scope_destruct (&unit->globals);\r
-               slang_function_scope_destruct (&unit->functions);\r
                return 0;\r
        }\r
-       unit->assembly = (slang_assembly_file *) slang_alloc_malloc (sizeof (slang_assembly_file));\r
-       if (unit->assembly == NULL)\r
+       if (!slang_struct_scope_construct (&unit->structs))\r
        {\r
                slang_variable_scope_destruct (&unit->globals);\r
                slang_function_scope_destruct (&unit->functions);\r
-               slang_struct_scope_destruct (&unit->structs);\r
                return 0;\r
        }\r
-       slang_assembly_file_construct (unit->assembly);\r
-       unit->global_pool.next_addr = 0;\r
-       return 1;
+       unit->assembly = file;\r
+       unit->free_assembly = 0;\r
+       unit->global_pool = pool;\r
+       unit->free_global_pool = 0;\r
+       unit->machine = mach;\r
+       unit->free_machine = 0;\r
+       unit->atom_pool = atoms;\r
+       unit->free_atom_pool = 0;\r
+       return 1;\r
 }
 
 void slang_translation_unit_destruct (slang_translation_unit *unit)
@@ -90,8 +143,20 @@ void slang_translation_unit_destruct (slang_translation_unit *unit)
        slang_variable_scope_destruct (&unit->globals);
        slang_function_scope_destruct (&unit->functions);
        slang_struct_scope_destruct (&unit->structs);\r
-       slang_assembly_file_destruct (unit->assembly);\r
-       slang_alloc_free (unit->assembly);
+       if (unit->free_assembly)\r
+       {\r
+               slang_assembly_file_destruct (unit->assembly);\r
+               slang_alloc_free (unit->assembly);\r
+       }\r
+       if (unit->free_global_pool)\r
+               slang_alloc_free (unit->global_pool);\r
+       if (unit->free_machine)\r
+               slang_alloc_free (unit->machine);\r
+       if (unit->free_atom_pool)\r
+       {\r
+               slang_atom_pool_destruct (unit->atom_pool);\r
+               slang_alloc_free (unit->atom_pool);\r
+       }
 }
 
 /* slang_info_log */
@@ -182,7 +247,8 @@ typedef struct slang_parse_ctx_
        const byte *I;
        slang_info_log *L;
        int parsing_builtin;\r
-       int global_scope;
+       int global_scope;\r
+       slang_atom_pool *atoms;
 } slang_parse_ctx;\r
 \r
 /* slang_output_ctx */\r
@@ -194,20 +260,24 @@ typedef struct slang_output_ctx_
        slang_struct_scope *structs;\r
        slang_assembly_file *assembly;\r
        slang_var_pool *global_pool;\r
+       slang_machine *machine;\r
 } slang_output_ctx;
 
 /* _slang_compile() */
 
-static int parse_identifier (slang_parse_ctx *C, char **id)
+static void parse_identifier_str (slang_parse_ctx *C, char **id)
 {
-       *id = slang_string_duplicate ((const char *) C->I);
-       if (*id == NULL)
-       {
-               slang_info_log_memory (C->L);
-               return 0;
-       }
-       C->I += _mesa_strlen ((const char *) C->I) + 1;
-       return 1;
+       *id = (char *) C->I;\r
+       C->I += _mesa_strlen (*id) + 1;
+}\r
+\r
+static slang_atom parse_identifier (slang_parse_ctx *C)\r
+{\r
+       const char *id;\r
+       \r
+       id = (const char *) C->I;\r
+       C->I += _mesa_strlen (id) + 1;\r
+       return slang_atom_pool_atom (C->atoms, id);\r
 }
 
 static int parse_number (slang_parse_ctx *C, int *number)
@@ -239,30 +309,14 @@ static int parse_float (slang_parse_ctx *C, float *number)
        char *exponent = NULL;
        char *whole = NULL;
 
-       if (!parse_identifier (C, &integral))
-               return 0;
-
-       if (!parse_identifier (C, &fractional))
-       {
-               slang_alloc_free (integral);
-               return 0;
-       }
-
-       if (!parse_identifier (C, &exponent))
-       {
-               slang_alloc_free (fractional);
-               slang_alloc_free (integral);
-               return 0;
-       }
+       parse_identifier_str (C, &integral);
+       parse_identifier_str (C, &fractional);
+       parse_identifier_str (C, &exponent);\r
 
-       whole = (char *) (slang_alloc_malloc ((_mesa_strlen (integral) + 
-               _mesa_strlen (fractional) + _mesa_strlen (exponent) + 3) * 
-               sizeof (char)));
+       whole = (char *) (slang_alloc_malloc ((_mesa_strlen (integral) + _mesa_strlen (fractional) +\r
+               _mesa_strlen (exponent) + 3) * sizeof (char)));
        if (whole == NULL)
        {
-               slang_alloc_free (exponent);
-               slang_alloc_free (fractional);
-               slang_alloc_free (integral);
                slang_info_log_memory (C->L);
                return 0;
        }
@@ -276,14 +330,11 @@ static int parse_float (slang_parse_ctx *C, float *number)
        *number = (float) (_mesa_strtod(whole, (char **)NULL));
 
        slang_alloc_free (whole);
-       slang_alloc_free (exponent);
-       slang_alloc_free (fractional);
-       slang_alloc_free (integral);
        return 1;
 }
 
 /* revision number - increment after each change affecting emitted output */
-#define REVISION 2
+#define REVISION 3
 
 static int check_revision (slang_parse_ctx *C)
 {
@@ -307,8 +358,10 @@ static int parse_type_specifier (slang_parse_ctx *, slang_output_ctx *, slang_ty
 \r
 static int parse_struct_field_var (slang_parse_ctx *C, slang_output_ctx *O, slang_variable *var)\r
 {\r
-       if (!parse_identifier (C, &var->name))\r
+       var->a_name = parse_identifier (C);\r
+       if (var->a_name == SLANG_ATOM_NULL)\r
                return 0;\r
+\r
        switch (*C->I++)\r
        {\r
        case FIELD_NONE:\r
@@ -332,6 +385,7 @@ static int parse_struct_field_var (slang_parse_ctx *C, slang_output_ctx *O, slan
        default:\r
                return 0;\r
        }\r
+\r
        return 1;\r
 }\r
 \r
@@ -355,7 +409,7 @@ static int parse_struct_field (slang_parse_ctx *C, slang_output_ctx *O, slang_st
                        slang_info_log_memory (C->L);\r
                        return 0;\r
                }\r
-               var = st->fields->variables + st->fields->num_variables;\r
+               var = &st->fields->variables[st->fields->num_variables];\r
                if (!slang_variable_construct (var))\r
                        return 0;\r
                st->fields->num_variables++;\r
@@ -365,25 +419,30 @@ static int parse_struct_field (slang_parse_ctx *C, slang_output_ctx *O, slang_st
                        return 0;\r
        }\r
        while (*C->I++ != FIELD_NONE);\r
+\r
        return 1;\r
 }\r
 \r
 static int parse_struct (slang_parse_ctx *C, slang_output_ctx *O, slang_struct **st)\r
 {\r
-       char *name;\r
+       slang_atom a_name;\r
+       const char *name;\r
 \r
-       if (!parse_identifier (C, &name))\r
+       /* parse struct name (if any) and make sure it is unique in current scope */\r
+       a_name = parse_identifier (C);\r
+       if (a_name == SLANG_ATOM_NULL)\r
                return 0;\r
-       if (name[0] != '\0' && slang_struct_scope_find (O->structs, name, 0) != NULL)\r
+       name = slang_atom_pool_id (C->atoms, a_name);\r
+       if (name[0] != '\0' && slang_struct_scope_find (O->structs, a_name, 0) != NULL)\r
        {\r
                slang_info_log_error (C->L, "%s: duplicate type name", name);\r
-               slang_alloc_free (name);\r
                return 0;\r
        }\r
+\r
+       /* set-up a new struct */\r
        *st = (slang_struct *) slang_alloc_malloc (sizeof (slang_struct));\r
        if (*st == NULL)\r
        {\r
-               slang_alloc_free (name);\r
                slang_info_log_memory (C->L);\r
                return 0;\r
        }\r
@@ -391,13 +450,13 @@ static int parse_struct (slang_parse_ctx *C, slang_output_ctx *O, slang_struct *
        {\r
                slang_alloc_free (*st);\r
                *st = NULL;\r
-               slang_alloc_free (name);\r
                slang_info_log_memory (C->L);\r
                return 0;\r
        }\r
-       (**st).name = name;\r
+       (**st).a_name = a_name;\r
        (**st).structs->outer_scope = O->structs;\r
 \r
+       /* parse individual struct fields */\r
        do\r
        {\r
                slang_type_specifier sp;\r
@@ -412,13 +471,14 @@ static int parse_struct (slang_parse_ctx *C, slang_output_ctx *O, slang_struct *
        }\r
        while (*C->I++ != FIELD_NONE);\r
 \r
-       if ((**st).name != '\0')\r
+       /* if named struct, copy it to current scope */\r
+       if (name[0] != '\0')\r
        {\r
                slang_struct *s;\r
 \r
                O->structs->structs = (slang_struct *) slang_alloc_realloc (O->structs->structs,\r
-                               O->structs->num_structs * sizeof (slang_struct),\r
-                               (O->structs->num_structs + 1) * sizeof (slang_struct));\r
+                       O->structs->num_structs * sizeof (slang_struct),\r
+                       (O->structs->num_structs + 1) * sizeof (slang_struct));\r
                if (O->structs->structs == NULL)\r
                {\r
                        slang_info_log_memory (C->L);\r
@@ -576,21 +636,24 @@ static int parse_type_specifier (slang_parse_ctx *C, slang_output_ctx *O, slang_
                if (!parse_struct (C, O, &spec->_struct))
                        return 0;
                break;
-       case TYPE_SPECIFIER_TYPENAME:
+       case TYPE_SPECIFIER_TYPENAME:\r
                spec->type = slang_spec_struct;
                {
-                       char *name;
-                       slang_struct *stru;
-                       if (!parse_identifier (C, &name))
-                               return 0;
-                       stru = slang_struct_scope_find (O->structs, name, 1);
+                       slang_atom a_name;
+                       slang_struct *stru;\r
+
+                       a_name = parse_identifier (C);\r
+                       if (a_name == NULL)
+                               return 0;\r
+
+                       stru = slang_struct_scope_find (O->structs, a_name, 1);
                        if (stru == NULL)
                        {
-                               slang_info_log_error (C->L, "%s: undeclared type name", name);
-                               slang_alloc_free (name);
+                               slang_info_log_error (C->L, "%s: undeclared type name",\r
+                                       slang_atom_pool_id (C->atoms, a_name));
                                return 0;
                        }
-                       slang_alloc_free (name);
+
                        spec->_struct = (slang_struct *) slang_alloc_malloc (sizeof (slang_struct));
                        if (spec->_struct == NULL)
                        {
@@ -687,7 +750,9 @@ static int parse_fully_specified_type (slang_parse_ctx *C, slang_output_ctx *O,
 
 static int parse_child_operation (slang_parse_ctx *C, slang_output_ctx *O, slang_operation *oper,\r
        int statement)
-{
+{\r
+       slang_operation *ch;\r
+
        oper->children = (slang_operation *) slang_alloc_realloc (oper->children,
                oper->num_children * sizeof (slang_operation),
                (oper->num_children + 1) * sizeof (slang_operation));
@@ -695,16 +760,17 @@ static int parse_child_operation (slang_parse_ctx *C, slang_output_ctx *O, slang
        {
                slang_info_log_memory (C->L);
                return 0;
-       }
-       if (!slang_operation_construct (oper->children + oper->num_children))
+       }\r
+       ch = &oper->children[oper->num_children];
+       if (!slang_operation_construct (ch))
        {
                slang_info_log_memory (C->L);
                return 0;
        }
        oper->num_children++;
        if (statement)
-               return parse_statement (C, O, &oper->children[oper->num_children - 1]);
-       return parse_expression (C, O, &oper->children[oper->num_children - 1]);
+               return parse_statement (C, O, ch);
+       return parse_expression (C, O, ch);
 }
 
 static int parse_declaration (slang_parse_ctx *C, slang_output_ctx *O);
@@ -714,29 +780,34 @@ static int parse_statement (slang_parse_ctx *C, slang_output_ctx *O, slang_opera
        oper->locals->outer_scope = O->vars;
        switch (*C->I++)
        {
-       case OP_BLOCK_BEGIN_NO_NEW_SCOPE:
+       case OP_BLOCK_BEGIN_NO_NEW_SCOPE:\r
+               /* parse child statements, do not create new variable scope */
                oper->type = slang_oper_block_no_new_scope;
                while (*C->I != OP_END)
                        if (!parse_child_operation (C, O, oper, 1))
                                return 0;
                C->I++;
                break;
-       case OP_BLOCK_BEGIN_NEW_SCOPE:
-               oper->type = slang_oper_block_new_scope;
-               while (*C->I != OP_END)\r
+       case OP_BLOCK_BEGIN_NEW_SCOPE:\r
+               /* parse child statements, create new variable scope */
                {\r
                        slang_output_ctx o = *O;\r
+\r
+                       oper->type = slang_oper_block_new_scope;\r
                        o.vars = oper->locals;
-                       if (!parse_child_operation (C, &o, oper, 1))
-                               return 0;\r
+                       while (*C->I != OP_END)\r
+                               if (!parse_child_operation (C, &o, oper, 1))
+                                       return 0;\r
+                       C->I++;\r
                }
-               C->I++;
                break;
-       case OP_DECLARE:
+       case OP_DECLARE:\r
+               /* local variable declaration, individual declarators are stored as children identifiers */
                oper->type = slang_oper_variable_decl;
                {
                        const unsigned int first_var = O->vars->num_variables;\r
-
+\r
+                       /* parse the declaration, note that there can be zero or more than one declarators */
                        if (!parse_declaration (C, O))
                                return 0;
                        if (first_var < O->vars->num_variables)
@@ -751,36 +822,28 @@ static int parse_statement (slang_parse_ctx *C, slang_output_ctx *O, slang_opera
                                        slang_info_log_memory (C->L);
                                        return 0;
                                }
-                               for (i = 0; i < num_vars; i++)
-                                       if (!slang_operation_construct (oper->children + i))
+                               for (oper->num_children = 0; oper->num_children < num_vars; oper->num_children++)
+                                       if (!slang_operation_construct (&oper->children[oper->num_children]))
                                        {
-                                               unsigned int j;
-                                               for (j = 0; j < i; j++)
-                                                       slang_operation_destruct (oper->children + j);
-                                               slang_alloc_free (oper->children);
-                                               oper->children = NULL;
                                                slang_info_log_memory (C->L);
                                                return 0;
                                        }
-                               oper->num_children = num_vars;
                                for (i = first_var; i < O->vars->num_variables; i++)
                                {
-                                       slang_operation *o = oper->children + i - first_var;
+                                       slang_operation *o = &oper->children[i - first_var];\r
+
                                        o->type = slang_oper_identifier;
                                        o->locals->outer_scope = O->vars;
-                                       o->identifier = slang_string_duplicate (O->vars->variables[i].name);
-                                       if (o->identifier == NULL)
-                                       {
-                                               slang_info_log_memory (C->L);
-                                               return 0;
-                                       }
+                                       o->a_id = O->vars->variables[i].a_name;
                                }
                        }
                }
                break;
-       case OP_ASM:
-               oper->type = slang_oper_asm;
-               if (!parse_identifier (C, &oper->identifier))
+       case OP_ASM:\r
+               /* the __asm statement, parse the mnemonic and all its arguments as expressions */
+               oper->type = slang_oper_asm;\r
+               oper->a_id = parse_identifier (C);\r
+               if (oper->a_id == SLANG_ATOM_NULL)
                        return 0;
                while (*C->I != OP_END)
                        if (!parse_child_operation (C, O, oper, 0))
@@ -816,9 +879,10 @@ static int parse_statement (slang_parse_ctx *C, slang_output_ctx *O, slang_opera
                        return 0;
                break;
        case OP_WHILE:
-               oper->type = slang_oper_while;\r
                {\r
                        slang_output_ctx o = *O;\r
+\r
+                       oper->type = slang_oper_while;\r
                        o.vars = oper->locals;
                        if (!parse_child_operation (C, &o, oper, 1))
                                return 0;
@@ -834,9 +898,10 @@ static int parse_statement (slang_parse_ctx *C, slang_output_ctx *O, slang_opera
                        return 0;
                break;
        case OP_FOR:
-               oper->type = slang_oper_for;\r
                {\r
                        slang_output_ctx o = *O;\r
+\r
+                       oper->type = slang_oper_for;\r
                        o.vars = oper->locals;
                        if (!parse_child_operation (C, &o, oper, 1))
                                return 0;
@@ -852,85 +917,41 @@ static int parse_statement (slang_parse_ctx *C, slang_output_ctx *O, slang_opera
                return 0;
        }
        return 1;
+}\r
+\r
+static int handle_nary_expression (slang_parse_ctx *C, slang_operation *op, slang_operation **ops,\r
+       unsigned int *total_ops, unsigned int n)\r
+{\r
+       unsigned int i;\r
+\r
+       op->children = (slang_operation *) slang_alloc_malloc (n * sizeof (slang_operation));\r
+       if (op->children == NULL)\r
+       {\r
+               slang_info_log_memory (C->L);\r
+               return 0;\r
+       }\r
+       op->num_children = n;\r
+\r
+       for (i = 0; i < n; i++)\r
+               op->children[i] = (*ops)[*total_ops - (n + 1 - i)];\r
+       (*ops)[*total_ops - (n + 1)] = (*ops)[*total_ops - 1];\r
+       *total_ops -= n;\r
+\r
+       *ops = (slang_operation *) slang_alloc_realloc (*ops, (*total_ops + n) * sizeof (slang_operation),\r
+               *total_ops * sizeof (slang_operation));\r
+       if (*ops == NULL)\r
+       {\r
+               slang_info_log_memory (C->L);\r
+               return 0;\r
+       }\r
+       return 1;\r
 }
 
-static int handle_trinary_expression (slang_parse_ctx *C, slang_operation *op,
-       slang_operation **ops, unsigned int *num_ops)
-{
-       op->num_children = 3;
-       op->children = (slang_operation *) slang_alloc_malloc (3 * sizeof (slang_operation));
-       if (op->children == NULL)
-       {
-               slang_info_log_memory (C->L);
-               return 0;
-       }
-       op->children[0] = (*ops)[*num_ops - 4];
-       op->children[1] = (*ops)[*num_ops - 3];
-       op->children[2] = (*ops)[*num_ops - 2];
-       (*ops)[*num_ops - 4] = (*ops)[*num_ops - 1];
-       *num_ops -= 3;
-       *ops = (slang_operation *) slang_alloc_realloc (*ops, (*num_ops + 3) * sizeof (slang_operation),
-               *num_ops * sizeof (slang_operation));
-       if (*ops == NULL)
-       {
-               slang_info_log_memory (C->L);
-               return 0;
-       }
-       return 1;
-}
-
-static int handle_binary_expression (slang_parse_ctx *C, slang_operation *op,
-       slang_operation **ops, unsigned int *num_ops)
-{
-       op->num_children = 2;
-       op->children = (slang_operation *) slang_alloc_malloc (2 * sizeof (slang_operation));
-       if (op->children == NULL)
-       {
-               slang_info_log_memory (C->L);
-               return 0;
-       }
-       op->children[0] = (*ops)[*num_ops - 3];
-       op->children[1] = (*ops)[*num_ops - 2];
-       (*ops)[*num_ops - 3] = (*ops)[*num_ops - 1];
-       *num_ops -= 2;
-       *ops = (slang_operation *) slang_alloc_realloc (*ops, (*num_ops + 2) * sizeof (slang_operation),
-               *num_ops * sizeof (slang_operation));
-       if (*ops == NULL)
-       {
-               slang_info_log_memory (C->L);
-               return 0;
-       }
-       return 1;
-}
-
-static int handle_unary_expression (slang_parse_ctx *C, slang_operation *op,
-       slang_operation **ops, unsigned int *num_ops)
-{
-       op->num_children = 1;
-       op->children = (slang_operation *) slang_alloc_malloc (sizeof (slang_operation));
-       if (op->children == NULL)
-       {
-               slang_info_log_memory (C->L);
-               return 0;
-       }
-       op->children[0] = (*ops)[*num_ops - 2];
-       (*ops)[*num_ops - 2] = (*ops)[*num_ops - 1];
-       (*num_ops)--;
-       *ops = (slang_operation *) slang_alloc_realloc (*ops, (*num_ops + 1) * sizeof (slang_operation),
-               *num_ops * sizeof (slang_operation));
-       if (*ops == NULL)
-       {
-               slang_info_log_memory (C->L);
-               return 0;
-       }
-       return 1;
-}
-
-static int is_constructor_name (const char *name, slang_struct_scope *structs)
+static int is_constructor_name (const char *name, slang_atom a_name, slang_struct_scope *structs)
 {
        if (slang_type_specifier_type_from_string (name) != slang_spec_void)
                return 1;
-       return slang_struct_scope_find (structs, name, 1) != NULL;
+       return slang_struct_scope_find (structs, a_name, 1) != NULL;
 }
 
 static int parse_expression (slang_parse_ctx *C, slang_output_ctx *O, slang_operation *oper)
@@ -942,7 +963,9 @@ static int parse_expression (slang_parse_ctx *C, slang_output_ctx *O, slang_oper
        while (*C->I != OP_END)
        {
                slang_operation *op;
-               const unsigned int op_code = *C->I++;
+               const unsigned int op_code = *C->I++;\r
+\r
+               /* allocate default operation, becomes a no-op if not used  */
                ops = (slang_operation *) slang_alloc_realloc (ops,
                        num_ops * sizeof (slang_operation), (num_ops + 1) * sizeof (slang_operation));
                if (ops == NULL)
@@ -950,14 +973,15 @@ static int parse_expression (slang_parse_ctx *C, slang_output_ctx *O, slang_oper
                        slang_info_log_memory (C->L);
                        return 0;
                }
-               op = ops + num_ops;
+               op = &ops[num_ops];
                if (!slang_operation_construct (op))
                {
                        slang_info_log_memory (C->L);
                        return 0;
                }
                num_ops++;
-               op->locals->outer_scope = O->vars;
+               op->locals->outer_scope = O->vars;\r
+
                switch (op_code)
                {
                case OP_PUSH_VOID:
@@ -967,13 +991,13 @@ static int parse_expression (slang_parse_ctx *C, slang_output_ctx *O, slang_oper
                        op->type = slang_oper_literal_bool;
                        if (!parse_number (C, &number))
                                return 0;
-                       op->literal = (float) number;
+                       op->literal = (GLfloat) number;
                        break;
                case OP_PUSH_INT:
                        op->type = slang_oper_literal_int;
                        if (!parse_number (C, &number))
                                return 0;
-                       op->literal = (float) number;
+                       op->literal = (GLfloat) number;
                        break;
                case OP_PUSH_FLOAT:
                        op->type = slang_oper_literal_float;
@@ -982,37 +1006,38 @@ static int parse_expression (slang_parse_ctx *C, slang_output_ctx *O, slang_oper
                        break;
                case OP_PUSH_IDENTIFIER:
                        op->type = slang_oper_identifier;
-                       if (!parse_identifier (C, &op->identifier))
+                       op->a_id = parse_identifier (C);\r
+                       if (op->a_id == SLANG_ATOM_NULL)
                                return 0;
                        break;
                case OP_SEQUENCE:
                        op->type = slang_oper_sequence;
-                       if (!handle_binary_expression (C, op, &ops, &num_ops))
+                       if (!handle_nary_expression (C, op, &ops, &num_ops, 2))
                                return 0;
                        break;
                case OP_ASSIGN:
                        op->type = slang_oper_assign;
-                       if (!handle_binary_expression (C, op, &ops, &num_ops))
+                       if (!handle_nary_expression (C, op, &ops, &num_ops, 2))
                                return 0;
                        break;
                case OP_ADDASSIGN:
                        op->type = slang_oper_addassign;
-                       if (!handle_binary_expression (C, op, &ops, &num_ops))
+                       if (!handle_nary_expression (C, op, &ops, &num_ops, 2))
                                return 0;
                        break;
                case OP_SUBASSIGN:
                        op->type = slang_oper_subassign;
-                       if (!handle_binary_expression (C, op, &ops, &num_ops))
+                       if (!handle_nary_expression (C, op, &ops, &num_ops, 2))
                                return 0;
                        break;
                case OP_MULASSIGN:
                        op->type = slang_oper_mulassign;
-                       if (!handle_binary_expression (C, op, &ops, &num_ops))
+                       if (!handle_nary_expression (C, op, &ops, &num_ops, 2))
                                return 0;
                        break;
                case OP_DIVASSIGN:
                        op->type = slang_oper_divassign;
-                       if (!handle_binary_expression (C, op, &ops, &num_ops))
+                       if (!handle_nary_expression (C, op, &ops, &num_ops, 2))
                                return 0;
                        break;
                /*case OP_MODASSIGN:*/
@@ -1023,22 +1048,22 @@ static int parse_expression (slang_parse_ctx *C, slang_output_ctx *O, slang_oper
                /*case OP_ANDASSIGN:*/
                case OP_SELECT:
                        op->type = slang_oper_select;
-                       if (!handle_trinary_expression (C, op, &ops, &num_ops))
+                       if (!handle_nary_expression (C, op, &ops, &num_ops, 3))
                                return 0;
                        break;
                case OP_LOGICALOR:
                        op->type = slang_oper_logicalor;
-                       if (!handle_binary_expression (C, op, &ops, &num_ops))
+                       if (!handle_nary_expression (C, op, &ops, &num_ops, 2))
                                return 0;
                        break;
                case OP_LOGICALXOR:
                        op->type = slang_oper_logicalxor;
-                       if (!handle_binary_expression (C, op, &ops, &num_ops))
+                       if (!handle_nary_expression (C, op, &ops, &num_ops, 2))
                                return 0;
                        break;
                case OP_LOGICALAND:
                        op->type = slang_oper_logicaland;
-                       if (!handle_binary_expression (C, op, &ops, &num_ops))
+                       if (!handle_nary_expression (C, op, &ops, &num_ops, 2))
                                return 0;
                        break;
                /*case OP_BITOR:*/
@@ -1046,126 +1071,133 @@ static int parse_expression (slang_parse_ctx *C, slang_output_ctx *O, slang_oper
                /*case OP_BITAND:*/
                case OP_EQUAL:
                        op->type = slang_oper_equal;
-                       if (!handle_binary_expression (C, op, &ops, &num_ops))
+                       if (!handle_nary_expression (C, op, &ops, &num_ops, 2))
                                return 0;
                        break;
                case OP_NOTEQUAL:
                        op->type = slang_oper_notequal;
-                       if (!handle_binary_expression (C, op, &ops, &num_ops))
+                       if (!handle_nary_expression (C, op, &ops, &num_ops, 2))
                                return 0;
                        break;
                case OP_LESS:
                        op->type = slang_oper_less;
-                       if (!handle_binary_expression (C, op, &ops, &num_ops))
+                       if (!handle_nary_expression (C, op, &ops, &num_ops, 2))
                                return 0;
                        break;
                case OP_GREATER:
                        op->type = slang_oper_greater;
-                       if (!handle_binary_expression (C, op, &ops, &num_ops))
+                       if (!handle_nary_expression (C, op, &ops, &num_ops, 2))
                                return 0;
                        break;
                case OP_LESSEQUAL:
                        op->type = slang_oper_lessequal;
-                       if (!handle_binary_expression (C, op, &ops, &num_ops))
+                       if (!handle_nary_expression (C, op, &ops, &num_ops, 2))
                                return 0;
                        break;
                case OP_GREATEREQUAL:
                        op->type = slang_oper_greaterequal;
-                       if (!handle_binary_expression (C, op, &ops, &num_ops))
+                       if (!handle_nary_expression (C, op, &ops, &num_ops, 2))
                                return 0;
                        break;
                /*case OP_LSHIFT:*/
                /*case OP_RSHIFT:*/
                case OP_ADD:
                        op->type = slang_oper_add;
-                       if (!handle_binary_expression (C, op, &ops, &num_ops))
+                       if (!handle_nary_expression (C, op, &ops, &num_ops, 2))
                                return 0;
                        break;
                case OP_SUBTRACT:
                        op->type = slang_oper_subtract;
-                       if (!handle_binary_expression (C, op, &ops, &num_ops))
+                       if (!handle_nary_expression (C, op, &ops, &num_ops, 2))
                                return 0;
                        break;
                case OP_MULTIPLY:
                        op->type = slang_oper_multiply;
-                       if (!handle_binary_expression (C, op, &ops, &num_ops))
+                       if (!handle_nary_expression (C, op, &ops, &num_ops, 2))
                                return 0;
                        break;
                case OP_DIVIDE:
                        op->type = slang_oper_divide;
-                       if (!handle_binary_expression (C, op, &ops, &num_ops))
+                       if (!handle_nary_expression (C, op, &ops, &num_ops, 2))
                                return 0;
                        break;
                /*case OP_MODULUS:*/
                case OP_PREINCREMENT:
                        op->type = slang_oper_preincrement;
-                       if (!handle_unary_expression (C, op, &ops, &num_ops))
+                       if (!handle_nary_expression (C, op, &ops, &num_ops, 1))
                                return 0;
                        break;
                case OP_PREDECREMENT:
                        op->type = slang_oper_predecrement;
-                       if (!handle_unary_expression (C, op, &ops, &num_ops))
+                       if (!handle_nary_expression (C, op, &ops, &num_ops, 1))
                                return 0;
                        break;
                case OP_PLUS:
                        op->type = slang_oper_plus;
-                       if (!handle_unary_expression (C, op, &ops, &num_ops))
+                       if (!handle_nary_expression (C, op, &ops, &num_ops, 1))
                                return 0;
                        break;
                case OP_MINUS:
                        op->type = slang_oper_minus;
-                       if (!handle_unary_expression (C, op, &ops, &num_ops))
+                       if (!handle_nary_expression (C, op, &ops, &num_ops, 1))
                                return 0;
                        break;
                case OP_NOT:
                        op->type = slang_oper_not;
-                       if (!handle_unary_expression (C, op, &ops, &num_ops))
+                       if (!handle_nary_expression (C, op, &ops, &num_ops, 1))
                                return 0;
                        break;
                /*case OP_COMPLEMENT:*/
                case OP_SUBSCRIPT:
                        op->type = slang_oper_subscript;
-                       if (!handle_binary_expression (C, op, &ops, &num_ops))
+                       if (!handle_nary_expression (C, op, &ops, &num_ops, 2))
                                return 0;
                        break;
                case OP_CALL:
                        op->type = slang_oper_call;
-                       if (!parse_identifier (C, &op->identifier))
+                       op->a_id = parse_identifier (C);\r
+                       if (op->a_id == SLANG_ATOM_NULL)
                                return 0;
                        while (*C->I != OP_END)
                                if (!parse_child_operation (C, O, op, 0))
                                        return 0;
                        C->I++;
-                       if (!C->parsing_builtin &&
-                               !slang_function_scope_find_by_name (O->funs, op->identifier, 1) &&
-                               !is_constructor_name (op->identifier, O->structs))
-                       {
-                               slang_info_log_error (C->L, "%s: undeclared function name", op->identifier);
-                               return 0;
+                       if (!C->parsing_builtin && !slang_function_scope_find_by_name (O->funs, op->a_id, 1))\r
+                       {\r
+                               const char *id;\r
+\r
+                               id = slang_atom_pool_id (C->atoms, op->a_id);
+                               if (!is_constructor_name (id, op->a_id, O->structs))
+                               {
+                                       slang_info_log_error (C->L, "%s: undeclared function name", id);
+                                       return 0;
+                               }\r
                        }
                        break;
                case OP_FIELD:
                        op->type = slang_oper_field;
-                       if (!parse_identifier (C, &op->identifier))
+                       op->a_id = parse_identifier (C);\r
+                       if (op->a_id == SLANG_ATOM_NULL)
                                return 0;
-                       if (!handle_unary_expression (C, op, &ops, &num_ops))
+                       if (!handle_nary_expression (C, op, &ops, &num_ops, 1))
                                return 0;
                        break;
                case OP_POSTINCREMENT:
                        op->type = slang_oper_postincrement;
-                       if (!handle_unary_expression (C, op, &ops, &num_ops))
+                       if (!handle_nary_expression (C, op, &ops, &num_ops, 1))
                                return 0;
                        break;
                case OP_POSTDECREMENT:
                        op->type = slang_oper_postdecrement;
-                       if (!handle_unary_expression (C, op, &ops, &num_ops))
+                       if (!handle_nary_expression (C, op, &ops, &num_ops, 1))
                                return 0;
                        break;
                default:
                        return 0;
                }
        }
-       C->I++;
+       C->I++;\r
+
        *oper = *ops;
        slang_alloc_free (ops);
        return 1;
@@ -1183,7 +1215,10 @@ static int parse_expression (slang_parse_ctx *C, slang_output_ctx *O, slang_oper
 static int parse_parameter_declaration (slang_parse_ctx *C, slang_output_ctx *O,\r
        slang_variable *param)
 {
-       slang_storage_aggregate agg;
+       slang_storage_aggregate agg;\r
+\r
+       /* parse and validate the parameter's type qualifiers (there can be two at most) because\r
+        * not all combinations are valid */
        if (!parse_type_qualifier (C, &param->type.qualifier))
                return 0;
        switch (*C->I++)
@@ -1215,11 +1250,16 @@ static int parse_parameter_declaration (slang_parse_ctx *C, slang_output_ctx *O,
                break;
        default:
                return 0;
-       }
+       }\r
+\r
+       /* parse parameter's type specifier and name */
        if (!parse_type_specifier (C, O, &param->type.specifier))
-               return 0;
-       if (!parse_identifier (C, &param->name))
-               return 0;
+               return 0;\r
+       param->a_name = parse_identifier (C);
+       if (param->a_name == SLANG_ATOM_NULL)\r
+               return 0;\r
+\r
+       /* if the parameter is an array, parse its size (the size must be explicitly defined */
        if (*C->I++ == PARAMETER_ARRAY_PRESENT)
        {
                param->array_size = (slang_operation *) slang_alloc_malloc (sizeof (slang_operation));
@@ -1236,16 +1276,22 @@ static int parse_parameter_declaration (slang_parse_ctx *C, slang_output_ctx *O,
                        return 0;
                }
                if (!parse_expression (C, O, param->array_size))
-                       return 0;
-       }
-       slang_storage_aggregate_construct (&agg);
-       if (!_slang_aggregate_variable (&agg, &param->type.specifier, param->array_size, O->funs,
-                       O->structs, O->vars))
-       {
-               slang_storage_aggregate_destruct (&agg);
-               return 0;
-       }
-       slang_storage_aggregate_destruct (&agg);
+                       return 0;\r
+               /* TODO: execute the array_size */
+       }\r
+\r
+       /* calculate the parameter size */\r
+       if (!slang_storage_aggregate_construct (&agg))\r
+               return 0;\r
+       if (!_slang_aggregate_variable (&agg, &param->type.specifier, param->array_size, O->funs,\r
+                       O->structs, O->vars, O->machine, O->assembly, C->atoms))\r
+       {\r
+               slang_storage_aggregate_destruct (&agg);\r
+               return 0;\r
+       }\r
+       param->size = _slang_sizeof_aggregate (&agg);\r
+       slang_storage_aggregate_destruct (&agg);\r
+       /* TODO: allocate the local address here? */\r
        return 1;
 }
 
@@ -1259,38 +1305,35 @@ static int parse_parameter_declaration (slang_parse_ctx *C, slang_output_ctx *O,
 #define PARAMETER_NEXT 1
 
 /* operator type */
-#define OPERATOR_ASSIGN 1
-#define OPERATOR_ADDASSIGN 2
-#define OPERATOR_SUBASSIGN 3
-#define OPERATOR_MULASSIGN 4
-#define OPERATOR_DIVASSIGN 5
-/*#define OPERATOR_MODASSIGN 6*/
-/*#define OPERATOR_LSHASSIGN 7*/
-/*#define OPERATOR_RSHASSIGN 8*/
-/*#define OPERATOR_ANDASSIGN 9*/
-/*#define OPERATOR_XORASSIGN 10*/
-/*#define OPERATOR_ORASSIGN 11*/
-#define OPERATOR_LOGICALXOR 12
-/*#define OPERATOR_BITOR 13*/
-/*#define OPERATOR_BITXOR 14*/
-/*#define OPERATOR_BITAND 15*/
-#define OPERATOR_EQUAL 16
-#define OPERATOR_NOTEQUAL 17
-#define OPERATOR_LESS 18
-#define OPERATOR_GREATER 19
-#define OPERATOR_LESSEQUAL 20
-#define OPERATOR_GREATEREQUAL 21
-/*#define OPERATOR_LSHIFT 22*/
-/*#define OPERATOR_RSHIFT 23*/
-#define OPERATOR_MULTIPLY 24
-#define OPERATOR_DIVIDE 25
-/*#define OPERATOR_MODULUS 26*/
-#define OPERATOR_INCREMENT 27
-#define OPERATOR_DECREMENT 28
-#define OPERATOR_PLUS 29
-#define OPERATOR_MINUS 30
-/*#define OPERATOR_COMPLEMENT 31*/
-#define OPERATOR_NOT 32
+#define OPERATOR_ADDASSIGN 1
+#define OPERATOR_SUBASSIGN 2
+#define OPERATOR_MULASSIGN 3
+#define OPERATOR_DIVASSIGN 4
+/*#define OPERATOR_MODASSIGN 5*/
+/*#define OPERATOR_LSHASSIGN 6*/
+/*#define OPERATOR_RSHASSIGN 7*/
+/*#define OPERATOR_ANDASSIGN 8*/
+/*#define OPERATOR_XORASSIGN 9*/
+/*#define OPERATOR_ORASSIGN 10*/
+#define OPERATOR_LOGICALXOR 11
+/*#define OPERATOR_BITOR 12*/
+/*#define OPERATOR_BITXOR 13*/
+/*#define OPERATOR_BITAND 14*/
+#define OPERATOR_LESS 15
+#define OPERATOR_GREATER 16
+#define OPERATOR_LESSEQUAL 17
+#define OPERATOR_GREATEREQUAL 18
+/*#define OPERATOR_LSHIFT 19*/
+/*#define OPERATOR_RSHIFT 20*/
+#define OPERATOR_MULTIPLY 21
+#define OPERATOR_DIVIDE 22
+/*#define OPERATOR_MODULUS 23*/
+#define OPERATOR_INCREMENT 24
+#define OPERATOR_DECREMENT 25
+#define OPERATOR_PLUS 26
+#define OPERATOR_MINUS 27
+/*#define OPERATOR_COMPLEMENT 28*/
+#define OPERATOR_NOT 29
 
 static const struct {
        unsigned int o_code;
@@ -1302,7 +1345,6 @@ static const struct {
        { OPERATOR_DECREMENT, "--" },
        { OPERATOR_SUBASSIGN, "-=" },
        { OPERATOR_MINUS, "-" },
-       { OPERATOR_NOTEQUAL, "!=" },
        { OPERATOR_NOT, "!" },
        { OPERATOR_MULASSIGN, "*=" },
        { OPERATOR_MULTIPLY, "*" },
@@ -1316,8 +1358,6 @@ static const struct {
        /*{ OPERATOR_RSHASSIGN, ">>=" },*/
        /*{ OPERATOR_RSHIFT, ">>" },*/
        { OPERATOR_GREATER, ">" },
-       { OPERATOR_EQUAL, "==" },
-       { OPERATOR_ASSIGN, "=" },
        /*{ OPERATOR_MODASSIGN, "%=" },*/
        /*{ OPERATOR_MODULUS, "%" },*/
        /*{ OPERATOR_ANDASSIGN, "&=" },*/
@@ -1326,46 +1366,51 @@ static const struct {
        /*{ OPERATOR_BITOR, "|" },*/
        /*{ OPERATOR_COMPLEMENT, "~" },*/
        /*{ OPERATOR_XORASSIGN, "^=" },*/
-       { OPERATOR_LOGICALXOR, "^^" }/*,*/
+       { OPERATOR_LOGICALXOR, "^^" },
        /*{ OPERATOR_BITXOR, "^" }*/
 };
 
-static int parse_operator_name (slang_parse_ctx *C, char **pname)
+static slang_atom parse_operator_name (slang_parse_ctx *C)
 {
-       unsigned int i;
-       for (i = 0; i < sizeof (operator_names) / sizeof (*operator_names); i++)
+       unsigned int i;\r
+
+       for (i = 0; i < sizeof (operator_names) / sizeof (*operator_names); i++)\r
+       {
                if (operator_names[i].o_code == (unsigned int) (*C->I))
                {
-                       *pname = slang_string_duplicate (operator_names[i].o_name);
-                       if (*pname == NULL)
+                       slang_atom atom = slang_atom_pool_atom (C->atoms, operator_names[i].o_name);
+                       if (atom == SLANG_ATOM_NULL)
                        {
                                slang_info_log_memory (C->L);
                                return 0;
                        }
                        C->I++;
-                       return 1;
-               }
+                       return atom;
+               }\r
+       }
        return 0;
 }
 
 static int parse_function_prototype (slang_parse_ctx *C, slang_output_ctx *O, slang_function *func)
-{
+{\r
+       /* parse function type and name */
        if (!parse_fully_specified_type (C, O, &func->header.type))
                return 0;
        switch (*C->I++)
        {
-       case FUNCTION_ORDINARY:
+       case FUNCTION_ORDINARY:\r
                func->kind = slang_func_ordinary;
-               if (!parse_identifier (C, &func->header.name))
-                       return 0;
+               func->header.a_name = parse_identifier (C);
+               if (func->header.a_name == SLANG_ATOM_NULL)\r
+                       return 0;\r
                break;
        case FUNCTION_CONSTRUCTOR:
                func->kind = slang_func_constructor;
                if (func->header.type.specifier.type == slang_spec_struct)
                        return 0;
-               func->header.name = slang_string_duplicate (
+               func->header.a_name = slang_atom_pool_atom (C->atoms,
                        slang_type_specifier_type_to_string (func->header.type.specifier.type));
-               if (func->header.name == NULL)
+               if (func->header.a_name == SLANG_ATOM_NULL)
                {
                        slang_info_log_memory (C->L);
                        return 0;
@@ -1373,15 +1418,19 @@ static int parse_function_prototype (slang_parse_ctx *C, slang_output_ctx *O, sl
                break;
        case FUNCTION_OPERATOR:
                func->kind = slang_func_operator;
-               if (!parse_operator_name (C, &func->header.name))
+               func->header.a_name = parse_operator_name (C);\r
+               if (func->header.a_name == SLANG_ATOM_NULL)
                        return 0;
                break;
        default:
                return 0;
        }\r
-       func->parameters->outer_scope = O->vars;
+\r
+       /* parse function parameters */
        while (*C->I++ == PARAMETER_NEXT)
-       {
+       {\r
+               slang_variable *p;\r
+
                func->parameters->variables = (slang_variable *) slang_alloc_realloc (
                        func->parameters->variables,
                        func->parameters->num_variables * sizeof (slang_variable),
@@ -1390,14 +1439,21 @@ static int parse_function_prototype (slang_parse_ctx *C, slang_output_ctx *O, sl
                {
                        slang_info_log_memory (C->L);
                        return 0;
-               }
-               slang_variable_construct (func->parameters->variables + func->parameters->num_variables);
+               }\r
+               p = &func->parameters->variables[func->parameters->num_variables];
+               if (!slang_variable_construct (p))\r
+                       return 0;\r
                func->parameters->num_variables++;
-               if (!parse_parameter_declaration (C, O,\r
-                               &func->parameters->variables[func->parameters->num_variables - 1]))
+               if (!parse_parameter_declaration (C, O, p))
                        return 0;
-       }
-       func->param_count = func->parameters->num_variables;
+       }\r
+\r
+       /* function formal parameters and local variables share the same scope, so save\r
+        * the information about param count in a seperate place\r
+        * also link the scope to the global variable scope so when a given identifier is not\r
+        * found here, the search process continues in the global space */
+       func->param_count = func->parameters->num_variables;\r
+       func->parameters->outer_scope = O->vars;
        return 1;
 }
 
@@ -1406,7 +1462,9 @@ static int parse_function_definition (slang_parse_ctx *C, slang_output_ctx *O, s
        slang_output_ctx o = *O;\r
 
        if (!parse_function_prototype (C, O, func))
-               return 0;
+               return 0;\r
+\r
+       /* create function's body operation */
        func->body = (slang_operation *) slang_alloc_malloc (sizeof (slang_operation));
        if (func->body == NULL)
        {
@@ -1420,12 +1478,110 @@ static int parse_function_definition (slang_parse_ctx *C, slang_output_ctx *O, s
                slang_info_log_memory (C->L);
                return 0;
        }\r
+\r
+       /* to parse the body the parse context is modified in order to capture parsed variables\r
+        * into function's local variable scope */\r
        C->global_scope = 0;\r
        o.vars = func->parameters;
        if (!parse_statement (C, &o, func->body))
                return 0;\r
        C->global_scope = 1;
        return 1;
+}\r
+\r
+static int initialize_global (slang_assembly_file *file, slang_machine *pmach,\r
+       slang_assembly_name_space *space, slang_variable *var, slang_atom_pool *atoms)\r
+{\r
+       slang_assembly_file_restore_point point;\r
+       slang_machine mach;\r
+       slang_assembly_local_info info;\r
+       slang_operation op_id, op_assign;\r
+       int result;\r
+       slang_assembly_flow_control flow;\r
+       slang_assembly_stack_info stk;\r
+\r
+       /* save the current assembly */\r
+       if (!slang_assembly_file_restore_point_save (file, &point))\r
+               return 0;\r
+\r
+       /* setup the machine */\r
+       mach = *pmach;\r
+       mach.ip = file->count;\r
+\r
+       /* allocate local storage for expression */\r
+       info.ret_size = 0;\r
+       info.addr_tmp = 0;\r
+       info.swizzle_tmp = 4;\r
+       if (!slang_assembly_file_push_label (file, slang_asm_local_alloc, 20))\r
+               return 0;\r
+       if (!slang_assembly_file_push_label (file, slang_asm_enter, 20))\r
+               return 0;\r
+\r
+       /* construct the left side of assignment */\r
+       if (!slang_operation_construct (&op_id))\r
+               return 0;\r
+       op_id.type = slang_oper_identifier;\r
+       op_id.a_id = var->a_name;\r
+\r
+       /* put the variable into operation's scope */\r
+       op_id.locals->variables = (slang_variable *) slang_alloc_malloc (sizeof (slang_variable));\r
+       if (op_id.locals->variables == NULL)\r
+       {\r
+               slang_operation_destruct (&op_id);\r
+               return 0;\r
+       }\r
+       op_id.locals->num_variables = 1;\r
+       op_id.locals->variables[0] = *var;\r
+\r
+       /* construct the assignment expression */\r
+       if (!slang_operation_construct (&op_assign))\r
+       {\r
+               op_id.locals->num_variables = 0;\r
+               slang_operation_destruct (&op_id);\r
+               return 0;\r
+       }\r
+       op_assign.type = slang_oper_assign;\r
+       op_assign.children = (slang_operation *) slang_alloc_malloc (2 * sizeof (slang_operation));\r
+       if (op_assign.children == NULL)\r
+       {\r
+               slang_operation_destruct (&op_assign);\r
+               op_id.locals->num_variables = 0;\r
+               slang_operation_destruct (&op_id);\r
+               return 0;\r
+       }\r
+       op_assign.num_children = 2;\r
+       op_assign.children[0] = op_id;\r
+       op_assign.children[1] = *var->initializer;\r
+\r
+       /* insert the actual expression */\r
+       result = _slang_assemble_operation (file, &op_assign, 0, &flow, space, &info, &stk, pmach, atoms);\r
+\r
+       /* carefully destroy the operations */\r
+       op_assign.num_children = 0;\r
+       slang_alloc_free (op_assign.children);\r
+       op_assign.children = NULL;\r
+       slang_operation_destruct (&op_assign);\r
+       op_id.locals->num_variables = 0;\r
+       slang_operation_destruct (&op_id);\r
+\r
+       if (!result)\r
+               return 0;\r
+       if (!slang_assembly_file_push (file, slang_asm_exit))\r
+               return 0;\r
+\r
+       /* execute the expression */\r
+       if (!_slang_execute2 (file, &mach))\r
+               return 0;\r
+\r
+       /* restore the old assembly */\r
+       if (!slang_assembly_file_restore_point_load (file, &point))\r
+               return 0;\r
+\r
+       /* now we copy the contents of the initialized variable back to the original machine */\r
+       _mesa_memcpy ((GLubyte *) pmach->mem + var->address, (GLubyte *) mach.mem + var->address,\r
+               var->size);\r
+\r
+       return 1;\r
 }
 
 /* init declarator list */
@@ -1442,9 +1598,9 @@ static int parse_function_definition (slang_parse_ctx *C, slang_output_ctx *O, s
 static int parse_init_declarator (slang_parse_ctx *C, slang_output_ctx *O,\r
        const slang_fully_specified_type *type)
 {
-       slang_variable *var;
+       slang_variable *var;\r
 \r
-       /* empty init declatator, e.g. "float ;" */\r
+       /* empty init declatator (without name, e.g. "float ;") */\r
        if (*C->I++ == VARIABLE_NONE)
                return 1;\r
 \r
@@ -1458,12 +1614,15 @@ static int parse_init_declarator (slang_parse_ctx *C, slang_output_ctx *O,
                return 0;
        }
        var = &O->vars->variables[O->vars->num_variables];
-       slang_variable_construct (var);\r
+       if (!slang_variable_construct (var))\r
+               return 0;\r
        O->vars->num_variables++;\r
 \r
-       /* copy the declarator qualifier type, parse the identifier */
+       /* copy the declarator qualifier type, parse the identifier */\r
+       var->global = C->global_scope;
        var->type.qualifier = type->qualifier;
-       if (!parse_identifier (C, &var->name))
+       var->a_name = parse_identifier (C);
+       if (var->a_name == SLANG_ATOM_NULL)\r
                return 0;\r
 
        switch (*C->I++)
@@ -1491,11 +1650,12 @@ static int parse_init_declarator (slang_parse_ctx *C, slang_output_ctx *O,
                        return 0;
                }
                if (!parse_expression (C, O, var->initializer))
-                       return 0;
+                       return 0;\r
+               /* TODO: execute the initializer */
                break;
-       case VARIABLE_ARRAY_UNKNOWN:\r
+/*     case VARIABLE_ARRAY_UNKNOWN:\r
                /* unsized array - mark it as array and copy the specifier to the array element */
-               var->type.specifier.type = slang_spec_array;
+/*             var->type.specifier.type = slang_spec_array;
                var->type.specifier._array = (slang_type_specifier *) slang_alloc_malloc (sizeof (
                        slang_type_specifier));
                if (var->type.specifier._array == NULL)
@@ -1506,9 +1666,9 @@ static int parse_init_declarator (slang_parse_ctx *C, slang_output_ctx *O,
                slang_type_specifier_construct (var->type.specifier._array);
                if (!slang_type_specifier_copy (var->type.specifier._array, &type->specifier))
                        return 0;
-               break;
+               break;*/
        case VARIABLE_ARRAY_EXPLICIT:\r
-               /* an array - mark it as array, copy the specifier to the array element and\r
+               /* sized array - mark it as array, copy the specifier to the array element and\r
                 * parse the expression */
                var->type.specifier.type = slang_spec_array;
                var->type.specifier._array = (slang_type_specifier *) slang_alloc_malloc (sizeof (
@@ -1518,7 +1678,13 @@ static int parse_init_declarator (slang_parse_ctx *C, slang_output_ctx *O,
                        slang_info_log_memory (C->L);
                        return 0;
                }
-               slang_type_specifier_construct (var->type.specifier._array);
+               if (!slang_type_specifier_construct (var->type.specifier._array))\r
+               {\r
+                       slang_alloc_free (var->type.specifier._array);\r
+                       var->type.specifier._array = NULL;\r
+                       slang_info_log_memory (C->L);\r
+                       return 0;\r
+               }
                if (!slang_type_specifier_copy (var->type.specifier._array, &type->specifier))
                        return 0;
                var->array_size = (slang_operation *) slang_alloc_malloc (sizeof (slang_operation));
@@ -1546,15 +1712,29 @@ static int parse_init_declarator (slang_parse_ctx *C, slang_output_ctx *O,
        {
                slang_storage_aggregate agg;
 
-               slang_storage_aggregate_construct (&agg);
+               if (!slang_storage_aggregate_construct (&agg))\r
+                       return 0;
                if (!_slang_aggregate_variable (&agg, &var->type.specifier, var->array_size, O->funs,
-                               O->structs, O->vars))
+                               O->structs, O->vars, O->machine, O->assembly, C->atoms))
                {
                        slang_storage_aggregate_destruct (&agg);
                        return 0;
                }\r
-               var->address = slang_var_pool_alloc (O->global_pool, _slang_sizeof_aggregate (&agg));
-               slang_storage_aggregate_destruct (&agg);
+               var->size = _slang_sizeof_aggregate (&agg);\r
+               slang_storage_aggregate_destruct (&agg);\r
+               var->address = slang_var_pool_alloc (O->global_pool, var->size);
+       }\r
+\r
+       /* initialize global variable */\r
+       if (C->global_scope && var->initializer != NULL)\r
+       {\r
+               slang_assembly_name_space space;\r
+\r
+               space.funcs = O->funs;\r
+               space.structs = O->structs;\r
+               space.vars = O->vars;\r
+               if (!initialize_global (O->assembly, O->machine, &space, var, C->atoms))\r
+                       return 0;\r
        }
        return 1;
 }
@@ -1562,13 +1742,17 @@ static int parse_init_declarator (slang_parse_ctx *C, slang_output_ctx *O,
 static int parse_init_declarator_list (slang_parse_ctx *C, slang_output_ctx *O)
 {
        slang_fully_specified_type type;
-
-       slang_fully_specified_type_construct (&type);
+\r
+       /* parse the fully specified type, common to all declarators */
+       if (!slang_fully_specified_type_construct (&type))\r
+               return 0;
        if (!parse_fully_specified_type (C, O, &type))
        {
                slang_fully_specified_type_destruct (&type);
                return 0;
-       }
+       }\r
+\r
+       /* parse declarators, pass-in the parsed type */
        do
        {
                if (!parse_init_declarator (C, O, &type))
@@ -1577,7 +1761,8 @@ static int parse_init_declarator_list (slang_parse_ctx *C, slang_output_ctx *O)
                        return 0;
                }
        }
-       while (*C->I++ == DECLARATOR_NEXT);
+       while (*C->I++ == DECLARATOR_NEXT);\r
+
        slang_fully_specified_type_destruct (&type);
        return 1;
 }
@@ -1598,7 +1783,7 @@ static int parse_function (slang_parse_ctx *C, slang_output_ctx *O, int definiti
                        return 0;
                }
        }
-       else
+/*     else
        {
                if (!parse_function_prototype (C, O, &parsed_func))
                {
@@ -1608,7 +1793,7 @@ static int parse_function (slang_parse_ctx *C, slang_output_ctx *O, int definiti
        }
 
        /* find a function with a prototype matching the parsed one - only the current scope
-       is being searched to allow built-in function overriding */
+        * is being searched to allow built-in function overriding */
        found_func = slang_function_scope_find (O->funs, &parsed_func, 0);
        if (found_func == NULL)
        {
@@ -1628,13 +1813,13 @@ static int parse_function (slang_parse_ctx *C, slang_output_ctx *O, int definiti
                /* return the newly parsed function */
                *parsed_func_ret = &O->funs->functions[O->funs->num_functions - 1];
        }
-       else
+/*     else
        {
                /* TODO: check function return type qualifiers and specifiers */
-               if (definition)
+/*             if (definition)
                {
                        /* destroy the existing function declaration and replace it with the new one */
-                       if (found_func->body != NULL)
+/*                     if (found_func->body != NULL)
                        {
                                slang_info_log_error (C->L, "%s: function already has a body",
                                        parsed_func.header.name);
@@ -1647,11 +1832,11 @@ static int parse_function (slang_parse_ctx *C, slang_output_ctx *O, int definiti
                else
                {
                        /* another declaration of the same function prototype - ignore it */
-                       slang_function_destruct (&parsed_func);
+/*                     slang_function_destruct (&parsed_func);
                }
 
                /* return the found function */
-               *parsed_func_ret = found_func;
+/*             *parsed_func_ret = found_func;
        }
 
        /* assemble the parsed function */
@@ -1661,11 +1846,12 @@ static int parse_function (slang_parse_ctx *C, slang_output_ctx *O, int definiti
 \r
                space.funcs = O->funs;
                space.structs = O->structs;
-               space.vars = O->vars;
-
-               (**parsed_func_ret).address = O->assembly->count;
-               /*if (!_slang_assemble_function (O->assembly, *parsed_func_ret, &space))
-                       return 0;*/
+               space.vars = O->vars;\r
+               if (!_slang_assemble_function (O->assembly, *parsed_func_ret, &space, O->machine, C->atoms))\r
+               {\r
+                       const char *name = slang_atom_pool_id (C->atoms, (**parsed_func_ret).header.a_name);
+                       return 0;\r
+               }
        }
        return 1;
 }
@@ -1676,17 +1862,19 @@ static int parse_function (slang_parse_ctx *C, slang_output_ctx *O, int definiti
 
 static int parse_declaration (slang_parse_ctx *C, slang_output_ctx *O)
 {
-       slang_function *dummy_func;
-
        switch (*C->I++)
        {
        case DECLARATION_INIT_DECLARATOR_LIST:
                if (!parse_init_declarator_list (C, O))
                        return 0;
                break;
-       case DECLARATION_FUNCTION_PROTOTYPE:
-               if (!parse_function (C, O, 0, &dummy_func))
-                       return 0;
+       case DECLARATION_FUNCTION_PROTOTYPE:\r
+               {\r
+                       slang_function *dummy_func;\r
+
+                       if (!parse_function (C, O, 0, &dummy_func))
+                               return 0;\r
+               }
                break;
        default:
                return 0;
@@ -1703,21 +1891,26 @@ static int parse_translation_unit (slang_parse_ctx *C, slang_translation_unit *u
 {\r
        slang_output_ctx o;\r
 \r
+       /* setup output context */\r
        o.funs = &unit->functions;\r
        o.structs = &unit->structs;\r
        o.vars = &unit->globals;\r
        o.assembly = unit->assembly;\r
-       o.global_pool = &unit->global_pool;\r
-
+       o.global_pool = unit->global_pool;\r
+       o.machine = unit->machine;\r
+\r
+       /* parse individual functions and declarations */
        while (*C->I != EXTERNAL_NULL)
-       {\r
-               slang_function *func;\r
-
+       {
                switch (*C->I++)
                {
-               case EXTERNAL_FUNCTION_DEFINITION:
-                       if (!parse_function (C, &o, 1, &func))
-                               return 0;
+               case EXTERNAL_FUNCTION_DEFINITION:\r
+                       {\r
+                               slang_function *func;\r
+
+                               if (!parse_function (C, &o, 1, &func))
+                                       return 0;\r
+                       }
                        break;
                case EXTERNAL_DECLARATION:
                        if (!parse_declaration (C, &o))
@@ -1737,36 +1930,38 @@ static int parse_translation_unit (slang_parse_ctx *C, slang_translation_unit *u
 #define BUILTIN_TOTAL 3
 
 static int compile_binary (const byte *prod, slang_translation_unit *unit, slang_unit_type type,
-       slang_info_log *log, slang_translation_unit *builtins)
+       slang_info_log *log, slang_translation_unit *builtins, slang_assembly_file *file,\r
+       slang_var_pool *pool, slang_machine *mach, slang_translation_unit *downlink,\r
+       slang_atom_pool *atoms)
 {
-       slang_parse_ctx C;
+       slang_parse_ctx C;\r
+\r
+       /* create translation unit object */\r
+       if (file != NULL)\r
+       {\r
+               if (!slang_translation_unit_construct2 (unit, file, pool, mach, atoms))\r
+                       return 0;\r
+               unit->type = type;\r
+       }
 
        /* set-up parse context */
        C.I = prod;
        C.L = log;
        C.parsing_builtin = builtins == NULL;\r
-       C.global_scope = 1;
+       C.global_scope = 1;\r
+       C.atoms = unit->atom_pool;\r
 
        if (!check_revision (&C))
-               return 0;
-
-       /* create translation unit object */
-       slang_translation_unit_construct (unit);
-       unit->type = type;
+       {\r
+               slang_translation_unit_destruct (unit);\r
+               return 0;\r
+       }
 
-       if (builtins != NULL)
+       if (downlink != NULL)
        {
-               /* link to built-in functions */
-               builtins[BUILTIN_COMMON].functions.outer_scope = &builtins[BUILTIN_CORE].functions;
-               builtins[BUILTIN_TARGET].functions.outer_scope = &builtins[BUILTIN_COMMON].functions;
-               unit->functions.outer_scope = &builtins[BUILTIN_TARGET].functions;
-
-               /* link to built-in variables - core unit does not define any */
-               builtins[BUILTIN_TARGET].globals.outer_scope = &builtins[BUILTIN_COMMON].globals;
-               unit->globals.outer_scope = &builtins[BUILTIN_TARGET].globals;
-
-               /* link to built-in structure typedefs - only in common unit */
-               unit->structs.outer_scope = &builtins[BUILTIN_COMMON].structs;
+               unit->functions.outer_scope = &downlink->functions;
+               unit->globals.outer_scope = &downlink->globals;
+               unit->structs.outer_scope = &downlink->structs;
        }
 
        /* parse translation unit */
@@ -1789,7 +1984,7 @@ static int compile_with_grammar (grammar id, const char *source, slang_translati
        if (!_slang_preprocess_version (source, &version, &start, log))
                return 0;
 
-       /* check the syntax */
+       /* check the syntax and generate its binary representation */
        if (!grammar_fast_check (id, (const byte *) source + start, &prod, &size, 65536))
        {
                char buf[1024];
@@ -1798,8 +1993,10 @@ static int compile_with_grammar (grammar id, const char *source, slang_translati
                slang_info_log_error (log, buf);
                return 0;
        }
-
-       if (!compile_binary (prod, unit, type, log, builtins))
+\r
+       /* syntax is okay - translate it to internal representation */
+       if (!compile_binary (prod, unit, type, log, builtins, NULL, NULL, NULL,\r
+                       &builtins[BUILTIN_TARGET], NULL))
        {
                grammar_alloc_free (prod);
                return 0;
@@ -1858,26 +2055,33 @@ static int compile (grammar *id, slang_translation_unit *builtin_units, int *com
        /* if parsing user-specified shader, load built-in library */\r
        if (type == slang_unit_fragment_shader || type == slang_unit_vertex_shader)\r
        {\r
+               /* compile core functionality first */\r
                if (!compile_binary (slang_core_gc, &builtin_units[BUILTIN_CORE],\r
-                               slang_unit_fragment_builtin, log, NULL))\r
+                               slang_unit_fragment_builtin, log, NULL, unit->assembly, unit->global_pool,\r
+                               unit->machine, NULL, unit->atom_pool))\r
                        return 0;\r
                compiled[BUILTIN_CORE] = 1;\r
 \r
+               /* compile common functions and variables, link to core */\r
                if (!compile_binary (slang_common_builtin_gc, &builtin_units[BUILTIN_COMMON],\r
-                               slang_unit_fragment_builtin, log, NULL))\r
+                               slang_unit_fragment_builtin, log, NULL, unit->assembly, unit->global_pool,\r
+                               unit->machine, &builtin_units[BUILTIN_CORE], unit->atom_pool))\r
                        return 0;\r
                compiled[BUILTIN_COMMON] = 1;\r
 \r
+               /* compile target-specific functions and variables, link to common */\r
                if (type == slang_unit_fragment_shader)\r
                {\r
                        if (!compile_binary (slang_fragment_builtin_gc, &builtin_units[BUILTIN_TARGET],\r
-                                       slang_unit_fragment_builtin, log, NULL))\r
+                                       slang_unit_fragment_builtin, log, NULL, unit->assembly, unit->global_pool,\r
+                                       unit->machine, &builtin_units[BUILTIN_COMMON], unit->atom_pool))\r
                                return 0;\r
                }\r
                else if (type == slang_unit_vertex_shader)\r
                {\r
                        if (!compile_binary (slang_vertex_builtin_gc, &builtin_units[BUILTIN_TARGET],\r
-                                       slang_unit_vertex_builtin, log, NULL))\r
+                                       slang_unit_vertex_builtin, log, NULL, unit->assembly, unit->global_pool,\r
+                                       unit->machine, &builtin_units[BUILTIN_COMMON], unit->atom_pool))\r
                                return 0;\r
                }\r
                compiled[BUILTIN_TARGET] = 1;\r
@@ -1899,20 +2103,28 @@ int _slang_compile (const char *source, slang_translation_unit *unit, slang_unit
 {\r
        int success;
        grammar id = 0;
-       slang_translation_unit builtin_units[BUILTIN_TOTAL];\r
-       int compiled[BUILTIN_TOTAL] = { 0 };
-
+//     slang_translation_unit builtin_units[BUILTIN_TOTAL];\r
+       slang_translation_unit *builtin_units;\r
+       int compiled[BUILTIN_TOTAL] = { 0 };\r
+\r
+       /* create the main unit first */\r
+       if (!slang_translation_unit_construct (unit))\r
+               return 0;\r
+       unit->type = type;
+\r
+       builtin_units = (slang_translation_unit *) slang_alloc_malloc (BUILTIN_TOTAL * sizeof (slang_translation_unit));
        success = compile (&id, builtin_units, compiled, source, unit, type, log);
 
-       /* destroy built-in library */
-       if (type == slang_unit_fragment_shader || type == slang_unit_vertex_shader)
+       /* destroy built-in library */\r
+       /* XXX: free with the unit */
+       /*if (type == slang_unit_fragment_shader || type == slang_unit_vertex_shader)
        {\r
                int i;\r
 \r
                for (i = 0; i < BUILTIN_TOTAL; i++)\r
                        if (compiled[i] != 0)
                                slang_translation_unit_destruct (&builtin_units[i]);
-       }\r
+       }*/\r
        if (id != 0)
                grammar_destroy (id);\r
 
index dd774dd..8c7b96c 100644 (file)
@@ -54,10 +54,18 @@ typedef struct slang_translation_unit_
        slang_struct_scope structs;
        slang_unit_type type;\r
        struct slang_assembly_file_ *assembly;\r
-       slang_var_pool global_pool;
+       int free_assembly;\r
+       slang_var_pool *global_pool;\r
+       int free_global_pool;\r
+       struct slang_machine_ *machine;\r
+       int free_machine;\r
+       slang_atom_pool *atom_pool;\r
+       int free_atom_pool;
 } slang_translation_unit;
 
-int slang_translation_unit_construct (slang_translation_unit *);
+int slang_translation_unit_construct (slang_translation_unit *);\r
+int slang_translation_unit_construct2 (slang_translation_unit *, struct slang_assembly_file_ *,\r
+       slang_var_pool *, struct slang_machine_ *, slang_atom_pool *);
 void slang_translation_unit_destruct (slang_translation_unit *);
 
 typedef struct slang_info_log_
index 970c6fa..d62b009 100644 (file)
@@ -31,7 +31,6 @@
 #include "imports.h"\r
 #include "slang_utility.h"\r
 #include "slang_compile_variable.h"\r
-#include "slang_compile_struct.h"\r
 #include "slang_compile_operation.h"\r
 #include "slang_compile_function.h"\r
 \r
@@ -91,15 +90,15 @@ void slang_function_scope_destruct (slang_function_scope *scope)
        slang_alloc_free (scope->functions);\r
 }\r
 \r
-int slang_function_scope_find_by_name (slang_function_scope *funcs, const char *name, int all_scopes)\r
+int slang_function_scope_find_by_name (slang_function_scope *funcs, slang_atom a_name, int all_scopes)\r
 {\r
        unsigned int i;\r
 \r
        for (i = 0; i < funcs->num_functions; i++)\r
-               if (slang_string_compare (name, funcs->functions[i].header.name) == 0)\r
+               if (a_name == funcs->functions[i].header.a_name)\r
                        return 1;\r
        if (all_scopes && funcs->outer_scope != NULL)\r
-               return slang_function_scope_find_by_name (funcs->outer_scope, name, 1);\r
+               return slang_function_scope_find_by_name (funcs->outer_scope, a_name, 1);\r
        return 0;\r
 }\r
 \r
@@ -110,10 +109,10 @@ slang_function *slang_function_scope_find (slang_function_scope *funcs, slang_fu
 \r
        for (i = 0; i < funcs->num_functions; i++)\r
        {\r
-               slang_function *f = funcs->functions + i;\r
+               slang_function *f = &funcs->functions[i];\r
                unsigned int j;\r
 \r
-               if (slang_string_compare (fun->header.name, f->header.name) != 0)\r
+               if (fun->header.a_name != f->header.a_name)\r
                        continue;\r
                if (fun->param_count != f->param_count)\r
                        continue;\r
index 7f13bff..59743df 100644 (file)
@@ -58,7 +58,7 @@ typedef struct slang_function_scope_
 \r
 int slang_function_scope_construct (slang_function_scope *);\r
 void slang_function_scope_destruct (slang_function_scope *);\r
-int slang_function_scope_find_by_name (slang_function_scope *, const char *, int);\r
+int slang_function_scope_find_by_name (slang_function_scope *, slang_atom, int);\r
 slang_function *slang_function_scope_find (slang_function_scope *, slang_function *, int);\r
 \r
 #ifdef __cplusplus\r
index f6d371a..6783f1d 100644 (file)
@@ -31,9 +31,7 @@
 #include "imports.h"\r
 #include "slang_utility.h"\r
 #include "slang_compile_variable.h"\r
-#include "slang_compile_struct.h"\r
 #include "slang_compile_operation.h"\r
-#include "slang_compile_function.h"\r
 \r
 /* slang_operation */\r
 \r
@@ -43,7 +41,7 @@ int slang_operation_construct (slang_operation *oper)
        oper->children = NULL;\r
        oper->num_children = 0;\r
        oper->literal = (float) 0;\r
-       oper->identifier = NULL;\r
+       oper->a_id = SLANG_ATOM_NULL;\r
        oper->locals = (slang_variable_scope *) slang_alloc_malloc (sizeof (slang_variable_scope));\r
        if (oper->locals == NULL)\r
                return 0;\r
@@ -62,7 +60,6 @@ void slang_operation_destruct (slang_operation *oper)
        for (i = 0; i < oper->num_children; i++)\r
                slang_operation_destruct (oper->children + i);\r
        slang_alloc_free (oper->children);\r
-       slang_alloc_free (oper->identifier);\r
        slang_variable_scope_destruct (oper->locals);\r
        slang_alloc_free (oper->locals);\r
 }\r
@@ -94,15 +91,7 @@ int slang_operation_copy (slang_operation *x, const slang_operation *y)
                        return 0;\r
                }\r
        z.literal = y->literal;\r
-       if (y->identifier != NULL)\r
-       {\r
-               z.identifier = slang_string_duplicate (y->identifier);\r
-               if (z.identifier == NULL)\r
-               {\r
-                       slang_operation_destruct (&z);\r
-                       return 0;\r
-               }\r
-       }\r
+       z.a_id = y->a_id;\r
        if (!slang_variable_scope_copy (z.locals, y->locals))\r
        {\r
                slang_operation_destruct (&z);\r
index 54b2d17..9e64848 100644 (file)
@@ -101,7 +101,7 @@ typedef struct slang_operation_
        struct slang_operation_ *children;\r
        unsigned int num_children;\r
        float literal;          /* type: bool, literal_int, literal_float */\r
-       char *identifier;       /* type: asm, identifier, call, field */\r
+       slang_atom a_id;        /* type: asm, identifier, call, field */\r
        slang_variable_scope *locals;\r
 } slang_operation;\r
 \r
index bad58f4..0828d23 100644 (file)
@@ -32,8 +32,6 @@
 #include "slang_utility.h"\r
 #include "slang_compile_variable.h"\r
 #include "slang_compile_struct.h"\r
-#include "slang_compile_operation.h"\r
-#include "slang_compile_function.h"\r
 \r
 /* slang_struct_scope */\r
 \r
@@ -86,15 +84,15 @@ int slang_struct_scope_copy (slang_struct_scope *x, const slang_struct_scope *y)
        return 1;\r
 }\r
 \r
-slang_struct *slang_struct_scope_find (slang_struct_scope *stru, const char *name, int all_scopes)\r
+slang_struct *slang_struct_scope_find (slang_struct_scope *stru, slang_atom a_name, int all_scopes)\r
 {\r
        unsigned int i;\r
 \r
        for (i = 0; i < stru->num_structs; i++)\r
-               if (slang_string_compare (name, stru->structs[i].name) == 0)\r
-                       return stru->structs + i;\r
+               if (a_name == stru->structs[i].a_name)\r
+                       return &stru->structs[i];\r
        if (all_scopes && stru->outer_scope != NULL)\r
-               return slang_struct_scope_find (stru->outer_scope, name, 1);\r
+               return slang_struct_scope_find (stru->outer_scope, a_name, 1);\r
        return NULL;\r
 }\r
 \r
@@ -102,7 +100,7 @@ slang_struct *slang_struct_scope_find (slang_struct_scope *stru, const char *nam
 \r
 int slang_struct_construct (slang_struct *stru)\r
 {\r
-       stru->name = NULL;\r
+       stru->a_name = SLANG_ATOM_NULL;\r
        stru->fields = (slang_variable_scope *) slang_alloc_malloc (sizeof (slang_variable_scope));\r
        if (stru->fields == NULL)\r
                return 0;\r
@@ -130,7 +128,6 @@ int slang_struct_construct (slang_struct *stru)
 \r
 void slang_struct_destruct (slang_struct *stru)\r
 {\r
-       slang_alloc_free (stru->name);\r
        slang_variable_scope_destruct (stru->fields);\r
        slang_alloc_free (stru->fields);\r
        slang_struct_scope_destruct (stru->structs);\r
@@ -143,15 +140,7 @@ int slang_struct_copy (slang_struct *x, const slang_struct *y)
 \r
        if (!slang_struct_construct (&z))\r
                return 0;\r
-       if (y->name != NULL)\r
-       {\r
-               z.name = slang_string_duplicate (y->name);\r
-               if (z.name == NULL)\r
-               {\r
-                       slang_struct_destruct (&z);\r
-                       return 0;\r
-               }\r
-       }\r
+       z.a_name = y->a_name;\r
        if (!slang_variable_scope_copy (z.fields, y->fields))\r
        {\r
                slang_struct_destruct (&z);\r
@@ -175,15 +164,16 @@ int slang_struct_equal (const slang_struct *x, const slang_struct *y)
                return 0;\r
        for (i = 0; i < x->fields->num_variables; i++)\r
        {\r
-               slang_variable *varx = x->fields->variables + i;\r
-               slang_variable *vary = y->fields->variables + i;\r
-               if (slang_string_compare (varx->name, vary->name) != 0)\r
+               slang_variable *varx = &x->fields->variables[i];\r
+               slang_variable *vary = &y->fields->variables[i];\r
+\r
+               if (varx->a_name != vary->a_name)\r
                        return 0;\r
                if (!slang_type_specifier_equal (&varx->type.specifier, &vary->type.specifier))\r
                        return 0;\r
                if (varx->type.specifier.type == slang_spec_array)\r
                {\r
-                       /* TODO compare array sizes */\r
+                       /* TODO: compare array sizes */\r
                }\r
        }\r
        return 1;\r
index 10af980..4798b60 100644 (file)
@@ -39,11 +39,11 @@ typedef struct slang_struct_scope_
 int slang_struct_scope_construct (slang_struct_scope *);\r
 void slang_struct_scope_destruct (slang_struct_scope *);\r
 int slang_struct_scope_copy (slang_struct_scope *, const slang_struct_scope *);\r
-struct slang_struct_ *slang_struct_scope_find (slang_struct_scope *, const char *, int);\r
+struct slang_struct_ *slang_struct_scope_find (slang_struct_scope *, slang_atom, int);\r
 \r
 typedef struct slang_struct_\r
 {\r
-       char *name;\r
+       slang_atom a_name;\r
        struct slang_variable_scope_ *fields;\r
        slang_struct_scope *structs;\r
 } slang_struct;\r
index 39aabd8..da3b24f 100644 (file)
@@ -33,7 +33,6 @@
 #include "slang_compile_variable.h"\r
 #include "slang_compile_struct.h"\r
 #include "slang_compile_operation.h"\r
-#include "slang_compile_function.h"\r
 \r
 /* slang_type_specifier_type */\r
 \r
@@ -269,17 +268,18 @@ int slang_variable_construct (slang_variable *var)
 {\r
        if (!slang_fully_specified_type_construct (&var->type))\r
                return 0;\r
-       var->name = NULL;\r
+       var->a_name = SLANG_ATOM_NULL;\r
        var->array_size = NULL;\r
        var->initializer = NULL;\r
        var->address = ~0;\r
+       var->size = 0;\r
+       var->global = 0;\r
        return 1;\r
 }\r
 \r
 void slang_variable_destruct (slang_variable *var)\r
 {\r
        slang_fully_specified_type_destruct (&var->type);\r
-       slang_alloc_free (var->name);\r
        if (var->array_size != NULL)\r
        {\r
                slang_operation_destruct (var->array_size);\r
@@ -303,15 +303,7 @@ int slang_variable_copy (slang_variable *x, const slang_variable *y)
                slang_variable_destruct (&z);\r
                return 0;\r
        }\r
-       if (y->name != NULL)\r
-       {\r
-               z.name = slang_string_duplicate (y->name);\r
-               if (z.name == NULL)\r
-               {\r
-                       slang_variable_destruct (&z);\r
-                       return 0;\r
-               }\r
-       }\r
+       z.a_name = y->a_name;\r
        if (y->array_size != NULL)\r
        {\r
                z.array_size = (slang_operation *) slang_alloc_malloc (sizeof (slang_operation));\r
@@ -352,20 +344,23 @@ int slang_variable_copy (slang_variable *x, const slang_variable *y)
                        return 0;\r
                }\r
        }\r
+       z.address = y->address;\r
+       z.size = y->size;\r
+       z.global = y->global;\r
        slang_variable_destruct (x);\r
        *x = z;\r
        return 1;\r
 }\r
 \r
-slang_variable *_slang_locate_variable (slang_variable_scope *scope, const char *name, int all)\r
+slang_variable *_slang_locate_variable (slang_variable_scope *scope, slang_atom a_name, int all)\r
 {\r
        unsigned int i;\r
 \r
        for (i = 0; i < scope->num_variables; i++)\r
-               if (slang_string_compare (name, scope->variables[i].name) == 0)\r
-                       return scope->variables + i;\r
+               if (a_name == scope->variables[i].a_name)\r
+                       return &scope->variables[i];\r
        if (all && scope->outer_scope != NULL)\r
-               return _slang_locate_variable (scope->outer_scope, name, 1);\r
+               return _slang_locate_variable (scope->outer_scope, a_name, 1);\r
        return NULL;\r
 }\r
 \r
index d82a661..fc42280 100644 (file)
@@ -109,17 +109,19 @@ int slang_variable_scope_copy (slang_variable_scope *, const slang_variable_scop
 typedef struct slang_variable_\r
 {\r
        slang_fully_specified_type type;\r
-       char *name;\r
+       slang_atom a_name;\r
        struct slang_operation_ *array_size;    /* type: spec_array */\r
        struct slang_operation_ *initializer;\r
        unsigned int address;\r
+       unsigned int size;\r
+       int global;\r
 } slang_variable;\r
 \r
 int slang_variable_construct (slang_variable *);\r
 void slang_variable_destruct (slang_variable *);\r
 int slang_variable_copy (slang_variable *, const slang_variable *);\r
 \r
-slang_variable *_slang_locate_variable (slang_variable_scope *scope, const char *name, int all);\r
+slang_variable *_slang_locate_variable (slang_variable_scope *scope, slang_atom a_name, int all);\r
 \r
 #ifdef __cplusplus\r
 }\r
index e4df832..a40a35c 100644 (file)
@@ -1,8 +1,8 @@
 /*\r
  * Mesa 3-D graphics library\r
- * Version:  6.3\r
+ * Version:  6.5\r
  *\r
- * Copyright (C) 2005  Brian Paul   All Rights Reserved.\r
+ * Copyright (C) 2005-2006  Brian Paul   All Rights Reserved.\r
  *\r
  * Permission is hereby granted, free of charge, to any person obtaining a\r
  * copy of this software and associated documentation files (the "Software"),\r
 #include "slang_storage.h"\r
 #include "slang_execute.h"\r
 \r
-#define DEBUG_SLANG 1\r
+#define DEBUG_SLANG 0\r
+\r
+void slang_machine_init (slang_machine *mach)\r
+{\r
+       mach->ip = 0;\r
+       mach->sp = SLANG_MACHINE_STACK_SIZE;\r
+       mach->bp = 0;\r
+       mach->kill = 0;\r
+       mach->exit = 0;\r
+}\r
+\r
+int _slang_execute (const slang_assembly_file *file)\r
+{\r
+       slang_machine mach;\r
+\r
+       slang_machine_init (&mach);\r
+       return _slang_execute2 (file, &mach);\r
+}\r
 \r
 #if DEBUG_SLANG\r
 \r
@@ -44,6 +61,7 @@ static void dump_instruction (FILE *f, slang_assembly *a, unsigned int i)
        \r
        switch (a->type)\r
        {\r
+       /* core */\r
        case slang_asm_none:\r
                fprintf (f, "none");\r
                break;\r
@@ -74,12 +92,36 @@ static void dump_instruction (FILE *f, slang_assembly *a, unsigned int i)
        case slang_asm_float_less:\r
                fprintf (f, "float_less");\r
                break;\r
-       case slang_asm_float_equal:\r
+       case slang_asm_float_equal_exp:\r
+               fprintf (f, "float_equal");\r
+               break;\r
+       case slang_asm_float_equal_int:\r
                fprintf (f, "float_equal\t%d, %d", a->param[0], a->param[1]);\r
                break;\r
        case slang_asm_float_to_int:\r
                fprintf (f, "float_to_int");\r
                break;\r
+       case slang_asm_float_sine:\r
+               fprintf (f, "float_sine");\r
+               break;\r
+       case slang_asm_float_arcsine:\r
+               fprintf (f, "float_arcsine");\r
+               break;\r
+       case slang_asm_float_arctan:\r
+               fprintf (f, "float_arctan");\r
+               break;\r
+       case slang_asm_float_power:\r
+               fprintf (f, "float_power");\r
+               break;\r
+       case slang_asm_float_log2:\r
+               fprintf (f, "float_log2");\r
+               break;\r
+       case slang_asm_float_floor:\r
+               fprintf (f, "float_floor");\r
+               break;\r
+       case slang_asm_float_ceil:\r
+               fprintf (f, "float_ceil");\r
+               break;\r
        case slang_asm_int_copy:\r
                fprintf (f, "int_copy\t%d, %d", a->param[0], a->param[1]);\r
                break;\r
@@ -158,6 +200,16 @@ static void dump_instruction (FILE *f, slang_assembly *a, unsigned int i)
        case slang_asm_exit:\r
                fprintf (f, "exit");\r
                break;\r
+       /* mesa-specific extensions */\r
+       case slang_asm_float_print:\r
+               fprintf (f, "float_print");\r
+               break;\r
+       case slang_asm_int_print:\r
+               fprintf (f, "int_print");\r
+               break;\r
+       case slang_asm_bool_print:\r
+               fprintf (f, "bool_print");\r
+               break;\r
        default:\r
                break;\r
        }\r
@@ -186,11 +238,13 @@ static void dump (const slang_assembly_file *file)
 \r
 #endif\r
 \r
-int _slang_execute (const slang_assembly_file *file)\r
+int _slang_execute2 (const slang_assembly_file *file, slang_machine *mach)\r
 {\r
-       slang_machine mach;\r
+       slang_machine_slot *stack;\r
 \r
-#ifdef DEBUG_SLANG\r
+#if DEBUG_SLANG\r
+       static unsigned int counter = 0;\r
+       char filename[256];\r
        FILE *f;\r
 #endif\r
 \r
@@ -198,161 +252,195 @@ int _slang_execute (const slang_assembly_file *file)
        static_assert(sizeof (GLfloat) == 4);\r
        static_assert(sizeof (GLuint) == 4);\r
 \r
-       mach.ip = 0;\r
-       mach.sp = SLANG_MACHINE_STACK_SIZE;\r
-       mach.bp = 0;\r
-       mach.kill = 0;\r
-       mach.exit = 0;\r
-       mach.global = mach.mem;\r
-       mach.stack = mach.global + SLANG_MACHINE_GLOBAL_SIZE;\r
-\r
 #if DEBUG_SLANG\r
        dump (file);\r
-       f = fopen ("~mesa-slang-assembly-execution.txt", "w");\r
+       counter++;\r
+       _mesa_sprintf (filename, "~mesa-slang-assembly-exec-(%u).txt", counter);\r
+       f = fopen (filename, "w");\r
 #endif\r
 \r
-       while (!mach.exit)\r
+       stack = mach->mem + SLANG_MACHINE_GLOBAL_SIZE;\r
+\r
+       while (!mach->exit)\r
        {\r
-               slang_assembly *a;\r
+               slang_assembly *a = &file->code[mach->ip];\r
 \r
 #if DEBUG_SLANG\r
-               if (f != NULL)\r
+               if (f != NULL && a->type != slang_asm_none)\r
                {\r
                        unsigned int i;\r
 \r
-                       dump_instruction (f, file->code + mach.ip, mach.ip);\r
-                       fprintf (f, "\t\tsp=%u bp=%u\n", mach.sp, mach.bp);\r
-                       for (i = mach.sp; i < SLANG_MACHINE_STACK_SIZE; i++)\r
-                               fprintf (f, "\t%.5u\t%6f\t%u\n", i, mach.stack[i]._float, mach.stack[i]._addr);\r
+                       dump_instruction (f, file->code + mach->ip, mach->ip);\r
+                       fprintf (f, "\t\tsp=%u bp=%u\n", mach->sp, mach->bp);\r
+                       for (i = mach->sp; i < SLANG_MACHINE_STACK_SIZE; i++)\r
+                               fprintf (f, "\t%.5u\t%6f\t%u\n", i, stack[i]._float, stack[i]._addr);\r
                        fflush (f);\r
                }\r
 #endif\r
 \r
-               a = file->code + mach.ip;\r
-               mach.ip++;\r
+               mach->ip++;\r
 \r
                switch (a->type)\r
                {\r
+               /* core */\r
                case slang_asm_none:\r
                        break;\r
                case slang_asm_float_copy:\r
                case slang_asm_int_copy:\r
                case slang_asm_bool_copy:\r
-                       mach.mem[mach.stack[mach.sp + a->param[0] / 4]._addr + a->param[1] / 4]._float =\r
-                               mach.stack[mach.sp]._float;\r
-                       mach.sp++;\r
+                       mach->mem[(stack[mach->sp + a->param[0] / 4]._addr + a->param[1]) / 4]._float =\r
+                               stack[mach->sp]._float;\r
+                       mach->sp++;\r
                        break;\r
                case slang_asm_float_move:\r
                case slang_asm_int_move:\r
                case slang_asm_bool_move:\r
-                       mach.stack[mach.sp + a->param[0] / 4]._float =\r
-                               mach.stack[mach.sp + (mach.stack[mach.sp]._addr + a->param[1]) / 4]._float;\r
+                       stack[mach->sp + a->param[0] / 4]._float =\r
+                               stack[mach->sp + (stack[mach->sp]._addr + a->param[1]) / 4]._float;\r
                        break;\r
                case slang_asm_float_push:\r
                case slang_asm_int_push:\r
                case slang_asm_bool_push:\r
-                       mach.sp--;\r
-                       mach.stack[mach.sp]._float = a->literal;\r
+                       mach->sp--;\r
+                       stack[mach->sp]._float = a->literal;\r
                        break;\r
                case slang_asm_float_deref:\r
                case slang_asm_int_deref:\r
                case slang_asm_bool_deref:\r
-                       mach.stack[mach.sp]._float = mach.mem[mach.stack[mach.sp]._addr]._float;\r
+                       stack[mach->sp]._float = mach->mem[stack[mach->sp]._addr / 4]._float;\r
                        break;\r
                case slang_asm_float_add:\r
-                       mach.stack[mach.sp + 1]._float += mach.stack[mach.sp]._float;\r
-                       mach.sp++;\r
+                       stack[mach->sp + 1]._float += stack[mach->sp]._float;\r
+                       mach->sp++;\r
                        break;\r
                case slang_asm_float_multiply:\r
-                       mach.stack[mach.sp + 1]._float *= mach.stack[mach.sp]._float;\r
-                       mach.sp++;\r
+                       stack[mach->sp + 1]._float *= stack[mach->sp]._float;\r
+                       mach->sp++;\r
                        break;\r
                case slang_asm_float_divide:\r
-                       mach.stack[mach.sp + 1]._float /= mach.stack[mach.sp]._float;\r
-                       mach.sp++;\r
+                       stack[mach->sp + 1]._float /= stack[mach->sp]._float;\r
+                       mach->sp++;\r
                        break;\r
                case slang_asm_float_negate:\r
-                       mach.stack[mach.sp]._float = -mach.stack[mach.sp]._float;\r
+                       stack[mach->sp]._float = -stack[mach->sp]._float;\r
                        break;\r
                case slang_asm_float_less:\r
-                       mach.stack[mach.sp + 1]._float =\r
-                               mach.stack[mach.sp + 1]._float < mach.stack[mach.sp]._float ? 1.0f : 0.0f;\r
-                       mach.sp++;\r
+                       stack[mach->sp + 1]._float =\r
+                               stack[mach->sp + 1]._float < stack[mach->sp]._float ? (GLfloat) 1 : (GLfloat) 0;\r
+                       mach->sp++;\r
+                       break;\r
+               case slang_asm_float_equal_exp:\r
+                       stack[mach->sp + 1]._float =\r
+                               stack[mach->sp + 1]._float == stack[mach->sp]._float ? (GLfloat) 1 : (GLfloat) 0;\r
+                       mach->sp++;\r
                        break;\r
-               case slang_asm_float_equal:\r
-                       mach.sp--;\r
-                       mach.stack[mach.sp]._float = mach.stack[mach.sp + 1 + a->param[0] / 4]._float ==\r
-                               mach.stack[mach.sp + 1 + a->param[1] / 4]._float ? 1.0f : 0.0f;\r
+               case slang_asm_float_equal_int:\r
+                       mach->sp--;\r
+                       stack[mach->sp]._float = stack[mach->sp + 1 + a->param[0] / 4]._float ==\r
+                               stack[mach->sp + 1 + a->param[1] / 4]._float ? (GLfloat) 1 : (GLfloat) 0;\r
                        break;\r
                case slang_asm_float_to_int:\r
-                       mach.stack[mach.sp]._float = (GLfloat) (GLint) mach.stack[mach.sp]._float;\r
+                       stack[mach->sp]._float = (GLfloat) (GLint) stack[mach->sp]._float;\r
+                       break;\r
+               case slang_asm_float_sine:\r
+                       stack[mach->sp]._float = (GLfloat) _mesa_sin (stack[mach->sp]._float);\r
+                       break;\r
+               case slang_asm_float_arcsine:\r
+                       stack[mach->sp]._float = _mesa_asinf (stack[mach->sp]._float);\r
+                       break;\r
+               case slang_asm_float_arctan:\r
+                       stack[mach->sp]._float = _mesa_atanf (stack[mach->sp]._float);\r
+                       break;\r
+               case slang_asm_float_power:\r
+                       stack[mach->sp + 1]._float =\r
+                               (GLfloat) _mesa_pow (stack[mach->sp + 1]._float, stack[mach->sp]._float);\r
+                       mach->sp++;\r
+                       break;\r
+               case slang_asm_float_log2:\r
+                       stack[mach->sp]._float = LOG2 (stack[mach->sp]._float);\r
+                       break;\r
+               case slang_asm_float_floor:\r
+                       stack[mach->sp]._float = FLOORF (stack[mach->sp]._float);\r
+                       break;\r
+               case slang_asm_float_ceil:\r
+                       stack[mach->sp]._float = CEILF (stack[mach->sp]._float);\r
                        break;\r
                case slang_asm_int_to_float:\r
                        break;\r
                case slang_asm_int_to_addr:\r
-                       mach.stack[mach.sp]._addr = (GLuint) (GLint) mach.stack[mach.sp]._float;\r
+                       stack[mach->sp]._addr = (GLuint) (GLint) stack[mach->sp]._float;\r
                        break;\r
                case slang_asm_addr_copy:\r
-                       mach.mem[mach.stack[mach.sp + 1]._addr]._addr = mach.stack[mach.sp]._addr;\r
-                       mach.sp++;\r
+                       mach->mem[stack[mach->sp + 1]._addr / 4]._addr = stack[mach->sp]._addr;\r
+                       mach->sp++;\r
                        break;\r
                case slang_asm_addr_push:\r
-                       mach.sp--;\r
-                       mach.stack[mach.sp]._addr = a->param[0];\r
+                       mach->sp--;\r
+                       stack[mach->sp]._addr = a->param[0];\r
                        break;\r
                case slang_asm_addr_deref:\r
-                       mach.stack[mach.sp]._addr = mach.mem[mach.stack[mach.sp]._addr]._addr;\r
+                       stack[mach->sp]._addr = mach->mem[stack[mach->sp]._addr / 4]._addr;\r
                        break;\r
                case slang_asm_addr_add:\r
-                       mach.stack[mach.sp + 1]._addr += mach.stack[mach.sp]._addr;\r
-                       mach.sp++;\r
+                       stack[mach->sp + 1]._addr += stack[mach->sp]._addr;\r
+                       mach->sp++;\r
                        break;\r
                case slang_asm_addr_multiply:\r
-                       mach.stack[mach.sp + 1]._addr *= mach.stack[mach.sp]._addr;\r
-                       mach.sp++;\r
+                       stack[mach->sp + 1]._addr *= stack[mach->sp]._addr;\r
+                       mach->sp++;\r
                        break;\r
                case slang_asm_jump:\r
-                       mach.ip = a->param[0];\r
+                       mach->ip = a->param[0];\r
                        break;\r
                case slang_asm_jump_if_zero:\r
-                       if (mach.stack[mach.sp]._float == 0.0f)\r
-                               mach.ip = a->param[0];\r
-                       mach.sp++;\r
+                       if (stack[mach->sp]._float == 0.0f)\r
+                               mach->ip = a->param[0];\r
+                       mach->sp++;\r
                        break;\r
                case slang_asm_enter:\r
-                       mach.sp--;\r
-                       mach.stack[mach.sp]._addr = mach.bp;\r
-                       mach.bp = mach.sp + a->param[0] / 4;\r
+                       mach->sp--;\r
+                       stack[mach->sp]._addr = mach->bp;\r
+                       mach->bp = mach->sp + a->param[0] / 4;\r
                        break;\r
                case slang_asm_leave:\r
-                       mach.bp = mach.stack[mach.sp]._addr;\r
-                       mach.sp++;\r
+                       mach->bp = stack[mach->sp]._addr;\r
+                       mach->sp++;\r
                        break;\r
                case slang_asm_local_alloc:\r
-                       mach.sp -= a->param[0] / 4;\r
+                       mach->sp -= a->param[0] / 4;\r
                        break;\r
                case slang_asm_local_free:\r
-                       mach.sp += a->param[0] / 4;\r
+                       mach->sp += a->param[0] / 4;\r
                        break;\r
                case slang_asm_local_addr:\r
-                       mach.sp--;\r
-                       mach.stack[mach.sp]._addr = SLANG_MACHINE_GLOBAL_SIZE * 4 + mach.bp * 4 -\r
+                       mach->sp--;\r
+                       stack[mach->sp]._addr = SLANG_MACHINE_GLOBAL_SIZE * 4 + mach->bp * 4 - \r
                                (a->param[0] + a->param[1]) + 4;\r
                        break;\r
                case slang_asm_call:\r
-                       mach.sp--;\r
-                       mach.stack[mach.sp]._addr = mach.ip;\r
-                       mach.ip = a->param[0];\r
+                       mach->sp--;\r
+                       stack[mach->sp]._addr = mach->ip;\r
+                       mach->ip = a->param[0];\r
                        break;\r
                case slang_asm_return:\r
-                       mach.ip = mach.stack[mach.sp]._addr;\r
-                       mach.sp++;\r
+                       mach->ip = stack[mach->sp]._addr;\r
+                       mach->sp++;\r
                        break;\r
                case slang_asm_discard:\r
-                       mach.kill = 1;\r
+                       mach->kill = 1;\r
                        break;\r
                case slang_asm_exit:\r
-                       mach.exit = 1;\r
+                       mach->exit = 1;\r
+                       break;\r
+               /* mesa-specific extensions */\r
+               case slang_asm_float_print:\r
+                       _mesa_printf ("slang print: %f\n", stack[mach->sp]._float);\r
+                       break;\r
+               case slang_asm_int_print:\r
+                       _mesa_printf ("slang print: %d\n", (GLint) stack[mach->sp]._float);\r
+                       break;\r
+               case slang_asm_bool_print:\r
+                       _mesa_printf ("slang print: %s\n", (GLint) stack[mach->sp]._float ? "true" : "false");\r
                        break;\r
                }\r
        }\r
@@ -362,6 +450,6 @@ int _slang_execute (const slang_assembly_file *file)
                fclose (f);\r
 #endif\r
 \r
-       return 0;\r
+       return 1;\r
 }\r
 \r
index f911574..a3b326f 100644 (file)
@@ -1,8 +1,8 @@
 /*\r
  * Mesa 3-D graphics library\r
- * Version:  6.3\r
+ * Version:  6.5\r
  *\r
- * Copyright (C) 2005  Brian Paul   All Rights Reserved.\r
+ * Copyright (C) 2005-2006  Brian Paul   All Rights Reserved.\r
  *\r
  * Permission is hereby granted, free of charge, to any person obtaining a\r
  * copy of this software and associated documentation files (the "Software"),\r
@@ -47,11 +47,12 @@ typedef struct slang_machine_
        GLuint kill;                            /* discard the fragment */\r
        GLuint exit;                            /* terminate the shader */\r
        slang_machine_slot mem[SLANG_MACHINE_MEMORY_SIZE];\r
-       slang_machine_slot *global;\r
-       slang_machine_slot *stack;\r
 } slang_machine;\r
 \r
+void slang_machine_init (slang_machine *);\r
+\r
 int _slang_execute (const slang_assembly_file *);\r
+int _slang_execute2 (const slang_assembly_file *, slang_machine *);\r
 \r
 #ifdef __cplusplus\r
 }\r
index b1f62de..3601a38 100644 (file)
@@ -1,8 +1,8 @@
 /*\r
  * Mesa 3-D graphics library\r
- * Version:  6.3\r
+ * Version:  6.5\r
  *\r
- * Copyright (C) 2005  Brian Paul   All Rights Reserved.\r
+ * Copyright (C) 2005-2006  Brian Paul   All Rights Reserved.\r
  *\r
  * Permission is hereby granted, free of charge, to any person obtaining a\r
  * copy of this software and associated documentation files (the "Software"),\r
@@ -30,6 +30,7 @@
 \r
 #include "imports.h"\r
 #include "grammar_mesa.h"\r
+#include "slang_utility.h"\r
 #include "slang_compile.h"\r
 #include "slang_preprocess.h"\r
 \r
index 8a608c4..a2d1ab9 100644 (file)
 #include "imports.h"
 #include "slang_utility.h"
 #include "slang_storage.h"
-#include "slang_assemble.h"
+#include "slang_assemble.h"\r
+#include "slang_execute.h"
 
 /* slang_storage_array */
 
-void slang_storage_array_construct (slang_storage_array *arr)
+int slang_storage_array_construct (slang_storage_array *arr)
 {
        arr->type = slang_stor_aggregate;
        arr->aggregate = NULL;
-       arr->length = 0;
+       arr->length = 0;\r
+       return 1;
 }
 
 void slang_storage_array_destruct (slang_storage_array *arr)
@@ -53,15 +55,17 @@ void slang_storage_array_destruct (slang_storage_array *arr)
 
 /* slang_storage_aggregate */
 
-void slang_storage_aggregate_construct (slang_storage_aggregate *agg)
+int slang_storage_aggregate_construct (slang_storage_aggregate *agg)
 {
        agg->arrays = NULL;
-       agg->count = 0;
+       agg->count = 0;\r
+       return 1;
 }
 
 void slang_storage_aggregate_destruct (slang_storage_aggregate *agg)
 {
-       unsigned int i;
+       unsigned int i;\r
+
        for (i = 0; i < agg->count; i++)
                slang_storage_array_destruct (agg->arrays + i);
        slang_alloc_free (agg->arrays);
@@ -75,7 +79,8 @@ static slang_storage_array *slang_storage_aggregate_push_new (slang_storage_aggr
        if (agg->arrays != NULL)
        {
                arr = agg->arrays + agg->count;
-               slang_storage_array_construct (arr);
+               if (!slang_storage_array_construct (arr))\r
+                       return NULL;
                agg->count++;
        }
        return arr;
@@ -97,7 +102,7 @@ static int aggregate_vector (slang_storage_aggregate *agg, slang_storage_type ba
 static int aggregate_matrix (slang_storage_aggregate *agg, slang_storage_type basic_type,
        unsigned int dimension)
 {
-       slang_storage_array *arr = slang_storage_aggregate_push_new (agg);
+       slang_storage_array *arr = slang_storage_aggregate_push_new (agg);\r
        if (arr == NULL)
                return 0;
        arr->type = slang_stor_aggregate;
@@ -106,26 +111,80 @@ static int aggregate_matrix (slang_storage_aggregate *agg, slang_storage_type ba
                slang_storage_aggregate));
        if (arr->aggregate == NULL)
                return 0;
-       slang_storage_aggregate_construct (arr->aggregate);
+       if (!slang_storage_aggregate_construct (arr->aggregate))\r
+       {\r
+               slang_alloc_free (arr->aggregate);\r
+               arr->aggregate = NULL;\r
+               return 0;\r
+       }
        if (!aggregate_vector (arr->aggregate, basic_type, dimension))
                return 0;
        return 1;
 }
 
 static int aggregate_variables (slang_storage_aggregate *agg, slang_variable_scope *vars,
-       slang_function_scope *funcs, slang_struct_scope *structs, slang_variable_scope *globals)
+       slang_function_scope *funcs, slang_struct_scope *structs, slang_variable_scope *globals,\r
+       slang_machine *mach, slang_assembly_file *file, slang_atom_pool *atoms)
 {
        unsigned int i;
        for (i = 0; i < vars->num_variables; i++)
                if (!_slang_aggregate_variable (agg, &vars->variables[i].type.specifier,
-                               vars->variables[i].array_size, funcs, structs, globals))
+                               vars->variables[i].array_size, funcs, structs, globals, mach, file, atoms))
                        return 0;
        return 1;
 }
+\r
+static int eval_array_size (slang_assembly_file *file, slang_machine *pmach,\r
+       slang_assembly_name_space *space, slang_operation *array_size, GLuint *plength,\r
+       slang_atom_pool *atoms)\r
+{\r
+       slang_assembly_file_restore_point point;\r
+       slang_assembly_local_info info;\r
+       slang_assembly_flow_control flow;\r
+       slang_assembly_stack_info stk;\r
+       slang_machine mach;\r
+\r
+       /* save the current assembly */\r
+       if (!slang_assembly_file_restore_point_save (file, &point))\r
+               return 0;\r
+\r
+       /* setup the machine */\r
+       mach = *pmach;\r
+       mach.ip = file->count;\r
+\r
+       /* allocate local storage for expression */\r
+       info.ret_size = 0;\r
+       info.addr_tmp = 0;\r
+       info.swizzle_tmp = 4;\r
+       if (!slang_assembly_file_push_label (file, slang_asm_local_alloc, 20))\r
+               return 0;\r
+       if (!slang_assembly_file_push_label (file, slang_asm_enter, 20))\r
+               return 0;\r
+\r
+       /* insert the actual expression */\r
+       if (!_slang_assemble_operation (file, array_size, 0, &flow, space, &info, &stk, pmach, atoms))\r
+               return 0;\r
+       if (!slang_assembly_file_push (file, slang_asm_exit))\r
+               return 0;\r
+\r
+       /* execute the expression */\r
+       if (!_slang_execute2 (file, &mach))\r
+               return 0;\r
+\r
+       /* the evaluated expression is on top of the stack */\r
+       *plength = (GLuint) mach.mem[mach.sp + SLANG_MACHINE_GLOBAL_SIZE]._float;\r
+       /* TODO: check if 0 < arr->length <= 65535 */\r
+\r
+       /* restore the old assembly */\r
+       if (!slang_assembly_file_restore_point_load (file, &point))\r
+               return 0;\r
+       return 1;\r
+}\r
 
 int _slang_aggregate_variable (slang_storage_aggregate *agg, slang_type_specifier *spec,
        slang_operation *array_size, slang_function_scope *funcs, slang_struct_scope *structs,
-       slang_variable_scope *vars)
+       slang_variable_scope *vars, slang_machine *mach, slang_assembly_file *file,\r
+       slang_atom_pool *atoms)
 {
        switch (spec->type)
        {
@@ -167,15 +226,12 @@ int _slang_aggregate_variable (slang_storage_aggregate *agg, slang_type_specifie
        case slang_spec_sampler2DShadow:
                return aggregate_vector (agg, slang_stor_int, 1);
        case slang_spec_struct:
-               return aggregate_variables (agg, spec->_struct->fields, funcs, structs, vars);
+               return aggregate_variables (agg, spec->_struct->fields, funcs, structs, vars, mach,\r
+                       file, atoms);
        case slang_spec_array:
                {
-                       slang_storage_array *arr;
-                       slang_assembly_file file;
-                       slang_assembly_flow_control flow;
+                       slang_storage_array *arr;\r
                        slang_assembly_name_space space;
-                       slang_assembly_local_info info;
-                       slang_assembly_stack_info stk;
 
                        arr = slang_storage_aggregate_push_new (agg);
                        if (arr == NULL)
@@ -185,21 +241,20 @@ int _slang_aggregate_variable (slang_storage_aggregate *agg, slang_type_specifie
                                slang_storage_aggregate));
                        if (arr->aggregate == NULL)
                                return 0;
-                       slang_storage_aggregate_construct (arr->aggregate);
-                       if (!_slang_aggregate_variable (arr->aggregate, spec->_array, NULL, funcs, structs, vars))
-                               return 0;
-                       slang_assembly_file_construct (&file);
-                       space.funcs = funcs;
-                       space.structs = structs;
-                       space.vars = vars;
-                       if (!_slang_assemble_operation (&file, array_size, 0, &flow, &space, &info, &stk))
-                       {
-                               slang_assembly_file_destruct (&file);
-                               return 0;
+                       if (!slang_storage_aggregate_construct (arr->aggregate))\r
+                       {\r
+                               slang_alloc_free (arr->aggregate);\r
+                               arr->aggregate = NULL;\r
+                               return 0;\r
                        }
-                       /* TODO: evaluate array size */
-                       slang_assembly_file_destruct (&file);
-                       arr->length = 256;
+                       if (!_slang_aggregate_variable (arr->aggregate, spec->_array, NULL, funcs, structs,\r
+                                       vars, mach, file, atoms))
+                               return 0;\r
+                       space.funcs = funcs;\r
+                       space.structs = structs;\r
+                       space.vars = vars;\r
+                       if (!eval_array_size (file, mach, &space, array_size, &arr->length, atoms))\r
+                               return 0;
                }
                return 1;
        default:
@@ -211,10 +266,12 @@ int _slang_aggregate_variable (slang_storage_aggregate *agg, slang_type_specifie
 
 unsigned int _slang_sizeof_aggregate (const slang_storage_aggregate *agg)
 {
-       unsigned int i, size = 0;
+       unsigned int i, size = 0;\r
+
        for (i = 0; i < agg->count; i++)
        {
-               unsigned int element_size;
+               unsigned int element_size;\r
+
                if (agg->arrays[i].type == slang_stor_aggregate)
                        element_size = _slang_sizeof_aggregate (agg->arrays[i].aggregate);
                else
@@ -228,10 +285,12 @@ unsigned int _slang_sizeof_aggregate (const slang_storage_aggregate *agg)
 
 int _slang_flatten_aggregate (slang_storage_aggregate *flat, const slang_storage_aggregate *agg)
 {
-       unsigned int i;
+       unsigned int i;\r
+
        for (i = 0; i < agg->count; i++)
        {
-               unsigned int j;
+               unsigned int j;\r
+
                for (j = 0; j < agg->arrays[i].length; j++)
                {
                        if (agg->arrays[i].type == slang_stor_aggregate)
@@ -241,7 +300,8 @@ int _slang_flatten_aggregate (slang_storage_aggregate *flat, const slang_storage
                        }
                        else
                        {
-                               slang_storage_array *arr;
+                               slang_storage_array *arr;\r
+
                                arr = slang_storage_aggregate_push_new (flat);
                                if (arr == NULL)
                                        return 0;
index b875ce6..a99f38f 100644 (file)
@@ -66,7 +66,7 @@ typedef struct slang_storage_array_
        unsigned int length;
 } slang_storage_array;
 
-void slang_storage_array_construct (slang_storage_array *);
+int slang_storage_array_construct (slang_storage_array *);
 void slang_storage_array_destruct (slang_storage_array *);
 
 /*
@@ -81,12 +81,13 @@ typedef struct slang_storage_aggregate_
        unsigned int count;
 } slang_storage_aggregate;
 
-void slang_storage_aggregate_construct (slang_storage_aggregate *);
+int slang_storage_aggregate_construct (slang_storage_aggregate *);
 void slang_storage_aggregate_destruct (slang_storage_aggregate *);
 
 int _slang_aggregate_variable (slang_storage_aggregate *, struct slang_type_specifier_ *,
        struct slang_operation_ *, struct slang_function_scope_ *, slang_struct_scope *,
-       slang_variable_scope *);
+       slang_variable_scope *, struct slang_machine_ *, struct slang_assembly_file_ *,\r
+       slang_atom_pool *);
 
 /*
        returns total size (in machine units) of the given aggregate
index c07e161..5075832 100644 (file)
@@ -1,8 +1,8 @@
 /*\r
  * Mesa 3-D graphics library\r
- * Version:  6.3\r
+ * Version:  6.5\r
  *\r
- * Copyright (C) 2005  Brian Paul   All Rights Reserved.\r
+ * Copyright (C) 2005-2006  Brian Paul   All Rights Reserved.\r
  *\r
  * Permission is hereby granted, free of charge, to any person obtaining a\r
  * copy of this software and associated documentation files (the "Software"),\r
 #include "imports.h"\r
 #include "slang_utility.h"\r
 \r
-void slang_alloc_free (void *ptr)\r
+char *slang_string_concat (char *dst, const char *src)\r
 {\r
-       _mesa_free (ptr);\r
+       return _mesa_strcpy (dst + _mesa_strlen (dst), src);\r
 }\r
 \r
-void *slang_alloc_malloc (unsigned int size)\r
-{\r
-       return _mesa_malloc (size);\r
-}\r
+/* slang_atom_pool */\r
 \r
-void *slang_alloc_realloc (void *ptr, unsigned int old_size, unsigned int size)\r
+void slang_atom_pool_construct (slang_atom_pool *pool)\r
 {\r
-       return _mesa_realloc (ptr, old_size, size);\r
-}\r
+       GLuint i;\r
 \r
-int slang_string_compare (const char *str1, const char *str2)\r
-{\r
-       return _mesa_strcmp (str1, str2);\r
+       for (i = 0; i < SLANG_ATOM_POOL_SIZE; i++)\r
+               pool->entries[i] = NULL;\r
 }\r
 \r
-char *slang_string_copy (char *dst, const char *src)\r
+void slang_atom_pool_destruct (slang_atom_pool *pool)\r
 {\r
-       return _mesa_strcpy (dst, src);\r
-}\r
+       GLuint i;\r
 \r
-char *slang_string_concat (char *dst, const char *src)\r
-{\r
-       return _mesa_strcpy (dst + _mesa_strlen (dst), src);\r
+       for (i = 0; i < SLANG_ATOM_POOL_SIZE; i++)\r
+       {\r
+               slang_atom_entry *entry;\r
+               \r
+               entry = pool->entries[i];\r
+               while (entry != NULL)\r
+               {\r
+                       slang_atom_entry *next;\r
+\r
+                       next = entry->next;\r
+                       slang_alloc_free (entry->id);\r
+                       slang_alloc_free (entry);\r
+                       entry = next;\r
+               }\r
+       }\r
 }\r
 \r
-char *slang_string_duplicate (const char *src)\r
+slang_atom slang_atom_pool_atom (slang_atom_pool *pool, const char *id)\r
 {\r
-       return _mesa_strdup (src);\r
+       GLuint hash;\r
+       const char *p = id;\r
+       slang_atom_entry **entry;\r
+\r
+       hash = 0;\r
+       while (*p != '\0')\r
+       {\r
+               GLuint g;\r
+\r
+               hash = (hash << 4) + (GLuint) *p++;\r
+               g = hash & 0xf0000000;\r
+               if (g != 0)\r
+                       hash ^= g >> 24;\r
+               hash &= ~g;\r
+       }\r
+       hash %= SLANG_ATOM_POOL_SIZE;\r
+\r
+       entry = &pool->entries[hash];\r
+       while (*entry != NULL)\r
+       {\r
+               if (slang_string_compare ((**entry).id, id) == 0)\r
+                       return (slang_atom) (**entry).id;\r
+               entry = &(**entry).next;\r
+       }\r
+\r
+       *entry = (slang_atom_entry *) slang_alloc_malloc (sizeof (slang_atom_entry));\r
+       if (*entry == NULL)\r
+               return SLANG_ATOM_NULL;\r
+\r
+       (**entry).next = NULL;\r
+       (**entry).id = slang_string_duplicate (id);\r
+       if ((**entry).id == NULL)\r
+               return SLANG_ATOM_NULL;\r
+       return (slang_atom) (**entry).id;\r
 }\r
 \r
-unsigned int slang_string_length (const char *str)\r
+const char *slang_atom_pool_id (slang_atom_pool *pool, slang_atom atom)\r
 {\r
-       return _mesa_strlen (str);\r
+       return (const char *) atom;\r
 }\r
 \r
index 2b040a4..2d2ac8e 100644 (file)
@@ -1,8 +1,8 @@
 /*\r
  * Mesa 3-D graphics library\r
- * Version:  6.3\r
+ * Version:  6.5\r
  *\r
- * Copyright (C) 2005  Brian Paul   All Rights Reserved.\r
+ * Copyright (C) 2005-2006  Brian Paul   All Rights Reserved.\r
  *\r
  * Permission is hereby granted, free of charge, to any person obtaining a\r
  * copy of this software and associated documentation files (the "Software"),\r
@@ -34,14 +34,37 @@ extern "C" {
  */\r
 #define static_assert(expr) do { int _array[(expr) ? 1 : -1]; _array[0]; } while (0)\r
 \r
-void slang_alloc_free (void *);\r
-void *slang_alloc_malloc (unsigned int);\r
-void *slang_alloc_realloc (void *, unsigned int, unsigned int);\r
-int slang_string_compare (const char *, const char *);\r
-char *slang_string_copy (char *, const char *);\r
+#define slang_alloc_free(ptr) _mesa_free (ptr)\r
+#define slang_alloc_malloc(size) _mesa_malloc (size)\r
+#define slang_alloc_realloc(ptr, old_size, size) _mesa_realloc (ptr, old_size, size)\r
+#define slang_string_compare(str1, str2) _mesa_strcmp (str1, str2)\r
+#define slang_string_copy(dst, src) _mesa_strcpy (dst, src)\r
+#define slang_string_duplicate(src) _mesa_strdup (src)\r
+#define slang_string_length(str) _mesa_strlen (str)\r
+\r
 char *slang_string_concat (char *, const char *);\r
-char *slang_string_duplicate (const char *);\r
-unsigned int slang_string_length (const char *);\r
+\r
+typedef GLvoid *slang_atom;\r
+\r
+#define SLANG_ATOM_NULL ((slang_atom) 0)\r
+\r
+typedef struct slang_atom_entry_\r
+{\r
+       char *id;\r
+       struct slang_atom_entry_ *next;\r
+} slang_atom_entry;\r
+\r
+#define SLANG_ATOM_POOL_SIZE 1023\r
+\r
+typedef struct slang_atom_pool_\r
+{\r
+       slang_atom_entry *entries[SLANG_ATOM_POOL_SIZE];\r
+} slang_atom_pool;\r
+\r
+void slang_atom_pool_construct (slang_atom_pool *);\r
+void slang_atom_pool_destruct (slang_atom_pool *);\r
+slang_atom slang_atom_pool_atom (slang_atom_pool *, const char *);\r
+const char *slang_atom_pool_id (slang_atom_pool *, slang_atom);\r
 \r
 #ifdef __cplusplus\r
 }\r