Commit 4e33fd4b authored by Mike Gabriel's avatar Mike Gabriel

Mesa: Convert some files with MSDOS EOL style to Unix EOL style.

parent 4146d1aa
......@@ -109,18 +109,18 @@ _mesa_Hint( GLenum target, GLenum mode )
return;
FLUSH_VERTICES(ctx, _NEW_HINT);
ctx->Hint.GenerateMipmap = mode;
break;
/* GL_ARB_fragment_shader */
case GL_FRAGMENT_SHADER_DERIVATIVE_HINT_ARB:
if (!ctx->Extensions.ARB_fragment_shader) {
_mesa_error(ctx, GL_INVALID_ENUM, "glHint(target)");
return;
}
if (ctx->Hint.FragmentShaderDerivative == mode)
return;
FLUSH_VERTICES(ctx, _NEW_HINT);
ctx->Hint.FragmentShaderDerivative = mode;
break;
/* GL_ARB_fragment_shader */
case GL_FRAGMENT_SHADER_DERIVATIVE_HINT_ARB:
if (!ctx->Extensions.ARB_fragment_shader) {
_mesa_error(ctx, GL_INVALID_ENUM, "glHint(target)");
return;
}
if (ctx->Hint.FragmentShaderDerivative == mode)
return;
FLUSH_VERTICES(ctx, _NEW_HINT);
ctx->Hint.FragmentShaderDerivative = mode;
break;
default:
......@@ -148,6 +148,6 @@ void _mesa_init_hint( GLcontext * ctx )
ctx->Hint.Fog = GL_DONT_CARE;
ctx->Hint.ClipVolumeClipping = GL_DONT_CARE;
ctx->Hint.TextureCompression = GL_DONT_CARE;
ctx->Hint.GenerateMipmap = GL_DONT_CARE;
ctx->Hint.GenerateMipmap = GL_DONT_CARE;
ctx->Hint.FragmentShaderDerivative = GL_DONT_CARE;
}
......@@ -155,14 +155,14 @@ extern void GLAPIENTRY
_mesa_GetActiveAttribARB (GLhandleARB, GLuint, GLsizei, GLsizei *, GLint *, GLenum *, GLcharARB *);
extern GLint GLAPIENTRY
_mesa_GetAttribLocationARB (GLhandleARB, const GLcharARB *);
_mesa_GetAttribLocationARB (GLhandleARB, const GLcharARB *);
#endif
extern void
extern void
_mesa_init_shaderobjects (GLcontext *ctx);
#endif
#endif
/*
* Mesa 3-D graphics library
* Version: 6.3
*
* Copyright (C) 2005 Brian Paul All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
/**
* \file shaderobjects_3dlabs.c
* shader objects definitions for 3dlabs compiler
* \author Michal Krol
*/
/* Set this to 1 when we are ready to use 3dlabs' front-end */
#define USE_3DLABS_FRONTEND 0
#include "glheader.h"
#include "shaderobjects.h"
#include "shaderobjects_3dlabs.h"
#include "context.h"
#include "macros.h"
#include "hash.h"
#if USE_3DLABS_FRONTEND
#include "slang_mesa.h"
#include "Public/ShaderLang.h"
#else
#include "slang_compile.h"
#endif
struct gl2_unknown_obj
{
GLuint reference_count;
void (* _destructor) (struct gl2_unknown_intf **);
};
struct gl2_unknown_impl
{
struct gl2_unknown_intf *_vftbl;
struct gl2_unknown_obj _obj;
};
static void
_unknown_destructor (struct gl2_unknown_intf **intf)
{
}
static void
_unknown_AddRef (struct gl2_unknown_intf **intf)
{
struct gl2_unknown_impl *impl = (struct gl2_unknown_impl *) intf;
impl->_obj.reference_count++;
}
static void
_unknown_Release (struct gl2_unknown_intf **intf)
{
struct gl2_unknown_impl *impl = (struct gl2_unknown_impl *) intf;
impl->_obj.reference_count--;
if (impl->_obj.reference_count == 0)
{
impl->_obj._destructor (intf);
_mesa_free ((void *) intf);
}
}
static struct gl2_unknown_intf **
_unknown_QueryInterface (struct gl2_unknown_intf **intf, enum gl2_uiid uiid)
{
if (uiid == UIID_UNKNOWN)
{
(**intf).AddRef (intf);
return intf;
}
return NULL;
}
static struct gl2_unknown_intf _unknown_vftbl = {
_unknown_AddRef,
_unknown_Release,
_unknown_QueryInterface
};
static void
_unknown_constructor (struct gl2_unknown_impl *impl)
{
impl->_vftbl = &_unknown_vftbl;
impl->_obj.reference_count = 1;
impl->_obj._destructor = _unknown_destructor;
}
struct gl2_unkinner_obj
{
struct gl2_unknown_intf **unkouter;
};
struct gl2_unkinner_impl
{
struct gl2_unknown_intf *_vftbl;
struct gl2_unkinner_obj _obj;
};
static void
_unkinner_destructor (struct gl2_unknown_intf **intf)
{
}
static void
_unkinner_AddRef (struct gl2_unknown_intf **intf)
{
struct gl2_unkinner_impl *impl = (struct gl2_unkinner_impl *) intf;
(**impl->_obj.unkouter).AddRef (impl->_obj.unkouter);
}
static void
_unkinner_Release (struct gl2_unknown_intf **intf)
{
struct gl2_unkinner_impl *impl = (struct gl2_unkinner_impl *) intf;
(**impl->_obj.unkouter).Release (impl->_obj.unkouter);
}
static struct gl2_unknown_intf **
_unkinner_QueryInterface (struct gl2_unknown_intf **intf, enum gl2_uiid uiid)
{
struct gl2_unkinner_impl *impl = (struct gl2_unkinner_impl *) intf;
return (**impl->_obj.unkouter).QueryInterface (impl->_obj.unkouter, uiid);
}
static struct gl2_unknown_intf _unkinner_vftbl = {
_unkinner_AddRef,
_unkinner_Release,
_unkinner_QueryInterface
};
static void
_unkinner_constructor (struct gl2_unkinner_impl *impl, struct gl2_unknown_intf **outer)
{
impl->_vftbl = &_unkinner_vftbl;
impl->_obj.unkouter = outer;
}
struct gl2_generic_obj
{
struct gl2_unknown_obj _unknown;
GLhandleARB name;
GLboolean delete_status;
GLcharARB *info_log;
};
struct gl2_generic_impl
{
struct gl2_generic_intf *_vftbl;
struct gl2_generic_obj _obj;
};
static void
_generic_destructor (struct gl2_unknown_intf **intf)
{
GET_CURRENT_CONTEXT(ctx);
struct gl2_generic_impl *impl = (struct gl2_generic_impl *) intf;
_mesa_free ((void *) impl->_obj.info_log);
_glthread_LOCK_MUTEX (ctx->Shared->Mutex);
_mesa_HashRemove (ctx->Shared->GL2Objects, impl->_obj.name);
_glthread_UNLOCK_MUTEX (ctx->Shared->Mutex);
_unknown_destructor (intf);
}
static struct gl2_unknown_intf **
_generic_QueryInterface (struct gl2_unknown_intf **intf, enum gl2_uiid uiid)
{
if (uiid == UIID_GENERIC)
{
(**intf).AddRef (intf);
return intf;
}
return _unknown_QueryInterface (intf, uiid);
}
static void
_generic_Delete (struct gl2_generic_intf **intf)
{
struct gl2_generic_impl *impl = (struct gl2_generic_impl *) intf;
if (impl->_obj.delete_status == GL_FALSE)
{
impl->_obj.delete_status = GL_TRUE;
(**intf)._unknown.Release ((struct gl2_unknown_intf **) intf);
}
}
static GLhandleARB
_generic_GetName (struct gl2_generic_intf **intf)
{
struct gl2_generic_impl *impl = (struct gl2_generic_impl *) intf;
return impl->_obj.name;
}
static GLboolean
_generic_GetDeleteStatus (struct gl2_generic_intf **intf)
{
struct gl2_generic_impl *impl = (struct gl2_generic_impl *) intf;
return impl->_obj.delete_status;
}
static const GLcharARB *
_generic_GetInfoLog (struct gl2_generic_intf **intf)
{
struct gl2_generic_impl *impl = (struct gl2_generic_impl *) intf;
return impl->_obj.info_log;
}
static struct gl2_generic_intf _generic_vftbl = {
{
_unknown_AddRef,
_unknown_Release,
_generic_QueryInterface
},
_generic_Delete,
NULL, /* abstract GetType */
_generic_GetName,
_generic_GetDeleteStatus,
_generic_GetInfoLog
};
static void
_generic_constructor (struct gl2_generic_impl *impl)
{
GET_CURRENT_CONTEXT(ctx);
_unknown_constructor ((struct gl2_unknown_impl *) impl);
impl->_vftbl = &_generic_vftbl;
impl->_obj._unknown._destructor = _generic_destructor;
impl->_obj.delete_status = GL_FALSE;
impl->_obj.info_log = NULL;
_glthread_LOCK_MUTEX (ctx->Shared->Mutex);
impl->_obj.name = _mesa_HashFindFreeKeyBlock (ctx->Shared->GL2Objects, 1);
_mesa_HashInsert (ctx->Shared->GL2Objects, impl->_obj.name, (void *) impl);
_glthread_UNLOCK_MUTEX (ctx->Shared->Mutex);
}
struct gl2_container_obj
{
struct gl2_generic_obj _generic;
struct gl2_generic_intf ***attached;
GLuint attached_count;
};
struct gl2_container_impl
{
struct gl2_container_intf *_vftbl;
struct gl2_container_obj _obj;
};
static void
_container_destructor (struct gl2_unknown_intf **intf)
{
struct gl2_container_impl *impl = (struct gl2_container_impl *) intf;
GLuint i;
for (i = 0; i < impl->_obj.attached_count; i++)
{
struct gl2_generic_intf **x = impl->_obj.attached[i];
(**x)._unknown.Release ((struct gl2_unknown_intf **) x);
}
_generic_destructor (intf);
}
static struct gl2_unknown_intf **
_container_QueryInterface (struct gl2_unknown_intf **intf, enum gl2_uiid uiid)
{
if (uiid == UIID_CONTAINER)
{
(**intf).AddRef (intf);
return intf;
}
return _generic_QueryInterface (intf, uiid);
}
static GLboolean
_container_Attach (struct gl2_container_intf **intf, struct gl2_generic_intf **att)
{
GET_CURRENT_CONTEXT(ctx);
struct gl2_container_impl *impl = (struct gl2_container_impl *) intf;
GLuint i;
for (i = 0; i < impl->_obj.attached_count; i++)
if (impl->_obj.attached[i] == att)
{
_mesa_error (ctx, GL_INVALID_OPERATION, "_container_Attach");
return GL_FALSE;
}
impl->_obj.attached = (struct gl2_generic_intf ***) _mesa_realloc (impl->_obj.attached,
impl->_obj.attached_count * sizeof (*impl->_obj.attached), (impl->_obj.attached_count + 1) *
sizeof (*impl->_obj.attached));
if (impl->_obj.attached == NULL)
return GL_FALSE;
impl->_obj.attached[impl->_obj.attached_count] = att;
impl->_obj.attached_count++;
(**att)._unknown.AddRef ((struct gl2_unknown_intf **) att);
return GL_TRUE;
}
static GLboolean
_container_Detach (struct gl2_container_intf **intf, struct gl2_generic_intf **att)
{
GET_CURRENT_CONTEXT(ctx);
struct gl2_container_impl *impl = (struct gl2_container_impl *) intf;
GLuint i, j;
for (i = 0; i < impl->_obj.attached_count; i++)
if (impl->_obj.attached[i] == att)
{
for (j = i; j < impl->_obj.attached_count - 1; j++)
impl->_obj.attached[j] = impl->_obj.attached[j + 1];
impl->_obj.attached = (struct gl2_generic_intf ***) _mesa_realloc (impl->_obj.attached,
impl->_obj.attached_count * sizeof (*impl->_obj.attached),
(impl->_obj.attached_count - 1) * sizeof (*impl->_obj.attached));
impl->_obj.attached_count--;
(**att)._unknown.Release ((struct gl2_unknown_intf **) att);
return GL_TRUE;
}
_mesa_error (ctx, GL_INVALID_OPERATION, "_container_Detach");
return GL_FALSE;
}
static GLsizei
_container_GetAttachedCount (struct gl2_container_intf **intf)
{
struct gl2_container_impl *impl = (struct gl2_container_impl *) intf;
return impl->_obj.attached_count;
}
static struct gl2_generic_intf **
_container_GetAttached (struct gl2_container_intf **intf, GLuint index)
{
struct gl2_container_impl *impl = (struct gl2_container_impl *) intf;
(**impl->_obj.attached[index])._unknown.AddRef (
(struct gl2_unknown_intf **)impl->_obj.attached[index]);
return impl->_obj.attached[index];
}
static struct gl2_container_intf _container_vftbl = {
{
{
_unknown_AddRef,
_unknown_Release,
_container_QueryInterface
},
_generic_Delete,
NULL, /* abstract GetType */
_generic_GetName,
_generic_GetDeleteStatus,
_generic_GetInfoLog
},
_container_Attach,
_container_Detach,
_container_GetAttachedCount,
_container_GetAttached
};
static void
_container_constructor (struct gl2_container_impl *impl)
{
_generic_constructor ((struct gl2_generic_impl *) impl);
impl->_vftbl = &_container_vftbl;
impl->_obj._generic._unknown._destructor = _container_destructor;
impl->_obj.attached = NULL;
impl->_obj.attached_count = 0;
}
struct gl2_3dlabs_shhandle_obj
{
struct gl2_unkinner_obj _unknown;
#if USE_3DLABS_FRONTEND
ShHandle handle;
#endif
};
struct gl2_3dlabs_shhandle_impl
{
struct gl2_3dlabs_shhandle_intf *_vftbl;
struct gl2_3dlabs_shhandle_obj _obj;
};
static void
_3dlabs_shhandle_destructor (struct gl2_unknown_intf **intf)
{
#if USE_3DLABS_FRONTEND
struct gl2_3dlabs_shhandle_impl *impl = (struct gl2_3dlabs_shhandle_impl *) intf;
ShDestruct (impl->_obj.handle);
#endif
_unkinner_destructor (intf);
}
static GLvoid *
_3dlabs_shhandle_GetShHandle (struct gl2_3dlabs_shhandle_intf **intf)
{
#if USE_3DLABS_FRONTEND
struct gl2_3dlabs_shhandle_impl *impl = (struct gl2_3dlabs_shhandle_impl *) intf;
return impl->_obj.handle;
#else
return NULL;
#endif
}
static struct gl2_3dlabs_shhandle_intf _3dlabs_shhandle_vftbl = {
{
_unkinner_AddRef,
_unkinner_Release,
_unkinner_QueryInterface
},
_3dlabs_shhandle_GetShHandle
};
static void
_3dlabs_shhandle_constructor (struct gl2_3dlabs_shhandle_impl *impl, struct gl2_unknown_intf **outer)
{
_unkinner_constructor ((struct gl2_unkinner_impl *) impl, outer);
impl->_vftbl = &_3dlabs_shhandle_vftbl;
#if USE_3DLABS_FRONTEND
impl->_obj.handle = NULL;
#endif
}
struct gl2_shader_obj
{
struct gl2_generic_obj _generic;
struct gl2_3dlabs_shhandle_impl _3dlabs_shhandle;
GLboolean compile_status;
GLcharARB *source;
GLint *offsets;
GLsizei offset_count;
};
struct gl2_shader_impl
{
struct gl2_shader_intf *_vftbl;
struct gl2_shader_obj _obj;
};
static void
_shader_destructor (struct gl2_unknown_intf **intf)
{
struct gl2_shader_impl *impl = (struct gl2_shader_impl *) intf;
_mesa_free ((void *) impl->_obj.source);
_mesa_free ((void *) impl->_obj.offsets);
_3dlabs_shhandle_destructor ((struct gl2_unknown_intf **) &impl->_obj._3dlabs_shhandle._vftbl);
_generic_destructor (intf);
}
static struct gl2_unknown_intf **
_shader_QueryInterface (struct gl2_unknown_intf **intf, enum gl2_uiid uiid)
{
#if USE_3DLABS_FRONTEND
struct gl2_shader_impl *impl = (struct gl2_shader_impl *) intf;
#endif
if (uiid == UIID_SHADER)
{
(**intf).AddRef (intf);
return intf;
}
#if USE_3DLABS_FRONTEND
if (uiid == UIID_3DLABS_SHHANDLE)
{
(**intf).AddRef (intf);
return (struct gl2_unknown_intf **) &impl->_obj._3dlabs_shhandle._vftbl;
}
#endif
return _generic_QueryInterface (intf, uiid);
}
static GLenum
_shader_GetType (struct gl2_generic_intf **intf)
{
return GL_SHADER_OBJECT_ARB;
}
static GLboolean
_shader_GetCompileStatus (struct gl2_shader_intf **intf)
{
struct gl2_shader_impl *impl = (struct gl2_shader_impl *) intf;
return impl->_obj.compile_status;
}
static GLvoid
_shader_SetSource (struct gl2_shader_intf **intf, GLcharARB *src, GLint *off, GLsizei cnt)
{
struct gl2_shader_impl *impl = (struct gl2_shader_impl *) intf;
_mesa_free ((void *) impl->_obj.source);
impl->_obj.source = src;
_mesa_free ((void *) impl->_obj.offsets);
impl->_obj.offsets = off;
impl->_obj.offset_count = cnt;
}
static const GLcharARB *
_shader_GetSource (struct gl2_shader_intf **intf)
{
struct gl2_shader_impl *impl = (struct gl2_shader_impl *) intf;
return impl->_obj.source;
}
static GLvoid
_shader_Compile (struct gl2_shader_intf **intf)
{
struct gl2_shader_impl *impl = (struct gl2_shader_impl *) intf;
#if USE_3DLABS_FRONTEND
char **strings;
TBuiltInResource res;
#else
slang_translation_unit unit;
slang_unit_type type;
slang_info_log info_log;
#endif
impl->_obj.compile_status = GL_FALSE;
_mesa_free ((void *) impl->_obj._generic.info_log);
impl->_obj._generic.info_log = NULL;
#if USE_3DLABS_FRONTEND
/* 3dlabs compiler expects us to feed it with null-terminated string array,
we've got only one big string with offsets, so we must split it; but when
there's only one string to deal with, we pass its address directly */
if (impl->_obj.offset_count <= 1)
strings = &impl->_obj.source;
else
{
GLsizei i, offset = 0;
strings = (char **) _mesa_malloc (impl->_obj.offset_count * sizeof (char *));
if (strings == NULL)
return;
for (i = 0; i < impl->_obj.offset_count; i++)
{
GLsizei size = impl->_obj.offsets[i] - offset;
strings[i] = (char *) _mesa_malloc ((size + 1) * sizeof (char));
if (strings[i] == NULL)
{
GLsizei j;
for (j = 0; j < i; j++)
_mesa_free (strings[j]);
_mesa_free (strings);
return;
}
_mesa_memcpy (strings[i], impl->_obj.source + offset, size * sizeof (char));
strings[i][size] = '\0';
offset = impl->_obj.offsets[i];
}
}
/* TODO set these fields to some REAL numbers */
res.maxLights = 8;
res.maxClipPlanes = 6;
res.maxTextureUnits = 2;
res.maxTextureCoords = 2;
res.maxVertexAttribs = 8;
res.maxVertexUniformComponents = 64;
res.maxVaryingFloats = 8;
res.maxVertexTextureImageUnits = 2;
res.maxCombinedTextureImageUnits = 2;
res.maxTextureImageUnits = 2;
res.maxFragmentUniformComponents = 64;
res.maxDrawBuffers = 1;
if (ShCompile (impl->_obj._3dlabs_shhandle._obj.handle, strings, impl->_obj.offset_count,
EShOptFull, &res, 0))
impl->_obj.compile_status = GL_TRUE;
if (impl->_obj.offset_count > 1)
{
GLsizei i;
for (i = 0; i < impl->_obj.offset_count; i++)
_mesa_free (strings[i]);
_mesa_free (strings);
}
impl->_obj._generic.info_log = _mesa_strdup (ShGetInfoLog (
impl->_obj._3dlabs_shhandle._obj.handle));
#else
if (impl->_vftbl->GetSubType (intf) == GL_FRAGMENT_SHADER)
type = slang_unit_fragment_shader;
else
type = slang_unit_vertex_shader;
slang_info_log_construct (&info_log);
if (_slang_compile (impl->_obj.source, &unit, type, &info_log))
{
impl->_obj.compile_status = GL_TRUE;
}
if (info_log.text != NULL)
impl->_obj._generic.info_log = _mesa_strdup (info_log.text);
else
impl->_obj._generic.info_log = _mesa_strdup ("");
slang_info_log_destruct (&info_log);
#endif
}
static struct gl2_shader_intf _shader_vftbl = {
{
{
_unknown_AddRef,
_unknown_Release,
_shader_QueryInterface
},
_generic_Delete,
_shader_GetType,
_generic_GetName,
_generic_GetDeleteStatus,
_generic_GetInfoLog
},
NULL, /* abstract GetSubType */
_shader_GetCompileStatus,
_shader_SetSource,
_shader_GetSource,
_shader_Compile
};
static void
_shader_constructor (struct gl2_shader_impl *impl)
{
_generic_constructor ((struct gl2_generic_impl *) impl);
_3dlabs_shhandle_constructor (&impl->_obj._3dlabs_shhandle, (struct gl2_unknown_intf **)
&impl->_vftbl);
impl->_vftbl = &_shader_vftbl;
impl->_obj._generic._unknown._destructor = _shader_destructor;
impl->_obj.compile_status = GL_FALSE;
impl->_obj.source = NULL;
impl->_obj.offsets = NULL;
impl->_obj.offset_count = 0;
}
struct gl2_program_obj
{
struct gl2_container_obj _container;
GLboolean link_status;
GLboolean validate_status;
#if USE_3DLABS_FRONTEND
ShHandle linker;
ShHandle uniforms;
#endif
};
struct gl2_program_impl
{
struct gl2_program_intf *_vftbl;
struct gl2_program_obj _obj;
};
static void
_program_destructor (struct gl2_unknown_intf **intf)
{
#if USE_3DLABS_FRONTEND
struct gl2_program_impl *impl = (struct gl2_program_impl *) intf;
ShDestruct (impl->_obj.linker);
ShDestruct (impl->_obj.uniforms);
#endif
_container_destructor (intf);
}
static struct gl2_unknown_intf **
_program_QueryInterface (struct gl2_unknown_intf **intf, enum gl2_uiid uiid)
{
if (uiid == UIID_PROGRAM)
{
(**intf).AddRef (intf);
return intf;
}
return _container_QueryInterface (intf, uiid);
}
static GLenum
_program_GetType (struct gl2_generic_intf **intf)
{
return GL_PROGRAM_OBJECT_ARB;
}
static GLboolean
_program_Attach (struct gl2_container_intf **intf, struct gl2_generic_intf **att)
{
GET_CURRENT_CONTEXT(ctx);
struct gl2_unknown_intf **sha;
sha = (**att)._unknown.QueryInterface ((struct gl2_unknown_intf **) att, UIID_SHADER);
if (sha == NULL)
{
_mesa_error (ctx, GL_INVALID_OPERATION, "_program_Attach");
return GL_FALSE;
}
(**sha).Release (sha);
return _container_Attach (intf, att);
}
static GLboolean
_program_GetLinkStatus (struct gl2_program_intf **intf)
{
struct gl2_program_impl *impl = (struct gl2_program_impl *) intf;
return impl->_obj.link_status;
}
static GLboolean
_program_GetValidateStatus (struct gl2_program_intf **intf)
{
struct gl2_program_impl *impl = (struct gl2_program_impl *) intf;
return impl->_obj.validate_status;
}
static GLvoid
_program_Link (struct gl2_program_intf **intf)
{
struct gl2_program_impl *impl = (struct gl2_program_impl *) intf;
#if USE_3DLABS_FRONTEND
ShHandle *handles;
GLuint i;
#endif
impl->_obj.link_status = GL_FALSE;
_mesa_free ((void *) impl->_obj._container._generic.info_log);
impl->_obj._container._generic.info_log = NULL;
#if USE_3DLABS_FRONTEND
handles = (ShHandle *) _mesa_malloc (impl->_obj._container.attached_count * sizeof (ShHandle));
if (handles == NULL)
return;
for (i = 0; i < impl->_obj._container.attached_count; i++)
{
struct gl2_generic_intf **gen = impl->_obj._container.attached[i];
struct gl2_3dlabs_shhandle_intf **sh;
sh = (struct gl2_3dlabs_shhandle_intf **) (**gen)._unknown.QueryInterface (
(struct gl2_unknown_intf **) gen, UIID_3DLABS_SHHANDLE);
if (sh != NULL)
{
handles[i] = (**sh).GetShHandle (sh);
(**sh)._unknown.Release ((struct gl2_unknown_intf **) sh);
}
else
{
_mesa_free (handles);
return;
}
}
if (ShLink (impl->_obj.linker, handles, impl->_obj._container.attached_count,
impl->_obj.uniforms, NULL, NULL))
impl->_obj.link_status = GL_TRUE;
impl->_obj._container._generic.info_log = _mesa_strdup (ShGetInfoLog (impl->_obj.linker));
#endif
}
static GLvoid
_program_Validate (struct gl2_program_intf **intf)
{
struct gl2_program_impl *impl = (struct gl2_program_impl *) intf;
impl->_obj.validate_status = GL_FALSE;
_mesa_free ((void *) impl->_obj._container._generic.info_log);
impl->_obj._container._generic.info_log = NULL;
/* TODO validate */
}
static struct gl2_program_intf _program_vftbl = {
{
{
{
_unknown_AddRef,
_unknown_Release,
_program_QueryInterface
},
_generic_Delete,
_program_GetType,
_generic_GetName,
_generic_GetDeleteStatus,
_generic_GetInfoLog
},
_program_Attach,
_container_Detach,
_container_GetAttachedCount,
_container_GetAttached
},
_program_GetLinkStatus,
_program_GetValidateStatus,
_program_Link,
_program_Validate
};
static void
_program_constructor (struct gl2_program_impl *impl)
{
_container_constructor ((struct gl2_container_impl *) impl);
impl->_vftbl = &_program_vftbl;
impl->_obj._container._generic._unknown._destructor = _program_destructor;
impl->_obj.link_status = GL_FALSE;
impl->_obj.validate_status = GL_FALSE;
#if USE_3DLABS_FRONTEND
impl->_obj.linker = ShConstructLinker (EShExVertexFragment, 0);
impl->_obj.uniforms = ShConstructUniformMap ();
#endif
}
struct gl2_fragment_shader_obj
{
struct gl2_shader_obj _shader;
};
struct gl2_fragment_shader_impl
{
struct gl2_fragment_shader_intf *_vftbl;
struct gl2_fragment_shader_obj _obj;
};
static void
_fragment_shader_destructor (struct gl2_unknown_intf **intf)
{
struct gl2_fragment_shader_impl *impl = (struct gl2_fragment_shader_impl *) intf;
(void) impl;
/* TODO free fragment shader data */
_shader_destructor (intf);
}
static struct gl2_unknown_intf **
_fragment_shader_QueryInterface (struct gl2_unknown_intf **intf, enum gl2_uiid uiid)
{
if (uiid == UIID_FRAGMENT_SHADER)
{
(**intf).AddRef (intf);
return intf;
}
return _shader_QueryInterface (intf, uiid);
}
static GLenum
_fragment_shader_GetSubType (struct gl2_shader_intf **intf)
{
return GL_FRAGMENT_SHADER_ARB;
}
static struct gl2_fragment_shader_intf _fragment_shader_vftbl = {
{
{
{
_unknown_AddRef,
_unknown_Release,
_fragment_shader_QueryInterface
},
_generic_Delete,
_shader_GetType,
_generic_GetName,
_generic_GetDeleteStatus,
_generic_GetInfoLog
},
_fragment_shader_GetSubType,
_shader_GetCompileStatus,
_shader_SetSource,
_shader_GetSource,
_shader_Compile
}
};
static void
_fragment_shader_constructor (struct gl2_fragment_shader_impl *impl)
{
_shader_constructor ((struct gl2_shader_impl *) impl);
impl->_vftbl = &_fragment_shader_vftbl;
impl->_obj._shader._generic._unknown._destructor = _fragment_shader_destructor;
#if USE_3DLABS_FRONTEND
impl->_obj._shader._3dlabs_shhandle._obj.handle = ShConstructCompiler (EShLangFragment, 0);
#endif
}
struct gl2_vertex_shader_obj
{
struct gl2_shader_obj _shader;
};
struct gl2_vertex_shader_impl
{
struct gl2_vertex_shader_intf *_vftbl;
struct gl2_vertex_shader_obj _obj;
};
static void
_vertex_shader_destructor (struct gl2_unknown_intf **intf)
{
struct gl2_vertex_shader_impl *impl = (struct gl2_vertex_shader_impl *) intf;
(void) impl;
/* TODO free vertex shader data */
_shader_destructor (intf);
}
static struct gl2_unknown_intf **
_vertex_shader_QueryInterface (struct gl2_unknown_intf **intf, enum gl2_uiid uiid)
{
if (uiid == UIID_VERTEX_SHADER)
{
(**intf).AddRef (intf);
return intf;
}
return _shader_QueryInterface (intf, uiid);
}
static GLenum
_vertex_shader_GetSubType (struct gl2_shader_intf **intf)
{
return GL_VERTEX_SHADER_ARB;
}
static struct gl2_vertex_shader_intf _vertex_shader_vftbl = {
{
{
{
_unknown_AddRef,
_unknown_Release,
_vertex_shader_QueryInterface
},
_generic_Delete,
_shader_GetType,
_generic_GetName,
_generic_GetDeleteStatus,
_generic_GetInfoLog
},
_vertex_shader_GetSubType,
_shader_GetCompileStatus,
_shader_SetSource,
_shader_GetSource,
_shader_Compile
}
};
static void
_vertex_shader_constructor (struct gl2_vertex_shader_impl *impl)
{
_shader_constructor ((struct gl2_shader_impl *) impl);
impl->_vftbl = &_vertex_shader_vftbl;
impl->_obj._shader._generic._unknown._destructor = _vertex_shader_destructor;
#if USE_3DLABS_FRONTEND
impl->_obj._shader._3dlabs_shhandle._obj.handle = ShConstructCompiler (EShLangVertex, 0);
#endif
}
GLhandleARB
_mesa_3dlabs_create_shader_object (GLenum shaderType)
{
switch (shaderType)
{
case GL_FRAGMENT_SHADER_ARB:
{
struct gl2_fragment_shader_impl *x = (struct gl2_fragment_shader_impl *)
_mesa_malloc (sizeof (struct gl2_fragment_shader_impl));
if (x != NULL)
{
_fragment_shader_constructor (x);
return x->_obj._shader._generic.name;
}
}
break;
case GL_VERTEX_SHADER_ARB:
{
struct gl2_vertex_shader_impl *x = (struct gl2_vertex_shader_impl *)
_mesa_malloc (sizeof (struct gl2_vertex_shader_impl));
if (x != NULL)
{
_vertex_shader_constructor (x);
return x->_obj._shader._generic.name;
}
}
break;
}
return 0;
}
GLhandleARB
_mesa_3dlabs_create_program_object (void)
{
struct gl2_program_impl *x = (struct gl2_program_impl *)
_mesa_malloc (sizeof (struct gl2_program_impl));
if (x != NULL)
{
_program_constructor (x);
return x->_obj._container._generic.name;
}
return 0;
}
void
_mesa_init_shaderobjects_3dlabs (GLcontext *ctx)
{
#if USE_3DLABS_FRONTEND
_glslang_3dlabs_InitProcess ();
_glslang_3dlabs_ShInitialize ();
#endif
}
/*
* Mesa 3-D graphics library
* Version: 6.3
*
* Copyright (C) 2005 Brian Paul All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
/**
* \file shaderobjects_3dlabs.c
* shader objects definitions for 3dlabs compiler
* \author Michal Krol
*/
/* Set this to 1 when we are ready to use 3dlabs' front-end */
#define USE_3DLABS_FRONTEND 0
#include "glheader.h"
#include "shaderobjects.h"
#include "shaderobjects_3dlabs.h"
#include "context.h"
#include "macros.h"
#include "hash.h"
#if USE_3DLABS_FRONTEND
#include "slang_mesa.h"
#include "Public/ShaderLang.h"
#else
#include "slang_compile.h"
#endif
struct gl2_unknown_obj
{
GLuint reference_count;
void (* _destructor) (struct gl2_unknown_intf **);
};
struct gl2_unknown_impl
{
struct gl2_unknown_intf *_vftbl;
struct gl2_unknown_obj _obj;
};
static void
_unknown_destructor (struct gl2_unknown_intf **intf)
{
}
static void
_unknown_AddRef (struct gl2_unknown_intf **intf)
{
struct gl2_unknown_impl *impl = (struct gl2_unknown_impl *) intf;
impl->_obj.reference_count++;
}
static void
_unknown_Release (struct gl2_unknown_intf **intf)
{
struct gl2_unknown_impl *impl = (struct gl2_unknown_impl *) intf;
impl->_obj.reference_count--;
if (impl->_obj.reference_count == 0)
{
impl->_obj._destructor (intf);
_mesa_free ((void *) intf);
}
}
static struct gl2_unknown_intf **
_unknown_QueryInterface (struct gl2_unknown_intf **intf, enum gl2_uiid uiid)
{
if (uiid == UIID_UNKNOWN)
{
(**intf).AddRef (intf);
return intf;
}
return NULL;
}
static struct gl2_unknown_intf _unknown_vftbl = {
_unknown_AddRef,
_unknown_Release,
_unknown_QueryInterface
};
static void
_unknown_constructor (struct gl2_unknown_impl *impl)
{
impl->_vftbl = &_unknown_vftbl;
impl->_obj.reference_count = 1;
impl->_obj._destructor = _unknown_destructor;
}
struct gl2_unkinner_obj
{
struct gl2_unknown_intf **unkouter;
};
struct gl2_unkinner_impl
{
struct gl2_unknown_intf *_vftbl;
struct gl2_unkinner_obj _obj;
};
static void
_unkinner_destructor (struct gl2_unknown_intf **intf)
{
}
static void
_unkinner_AddRef (struct gl2_unknown_intf **intf)
{
struct gl2_unkinner_impl *impl = (struct gl2_unkinner_impl *) intf;
(**impl->_obj.unkouter).AddRef (impl->_obj.unkouter);
}
static void
_unkinner_Release (struct gl2_unknown_intf **intf)
{
struct gl2_unkinner_impl *impl = (struct gl2_unkinner_impl *) intf;
(**impl->_obj.unkouter).Release (impl->_obj.unkouter);
}
static struct gl2_unknown_intf **
_unkinner_QueryInterface (struct gl2_unknown_intf **intf, enum gl2_uiid uiid)
{
struct gl2_unkinner_impl *impl = (struct gl2_unkinner_impl *) intf;
return (**impl->_obj.unkouter).QueryInterface (impl->_obj.unkouter, uiid);
}
static struct gl2_unknown_intf _unkinner_vftbl = {
_unkinner_AddRef,
_unkinner_Release,
_unkinner_QueryInterface
};
static void
_unkinner_constructor (struct gl2_unkinner_impl *impl, struct gl2_unknown_intf **outer)
{
impl->_vftbl = &_unkinner_vftbl;
impl->_obj.unkouter = outer;
}
struct gl2_generic_obj
{
struct gl2_unknown_obj _unknown;
GLhandleARB name;
GLboolean delete_status;
GLcharARB *info_log;
};
struct gl2_generic_impl
{
struct gl2_generic_intf *_vftbl;
struct gl2_generic_obj _obj;
};
static void
_generic_destructor (struct gl2_unknown_intf **intf)
{
GET_CURRENT_CONTEXT(ctx);
struct gl2_generic_impl *impl = (struct gl2_generic_impl *) intf;
_mesa_free ((void *) impl->_obj.info_log);
_glthread_LOCK_MUTEX (ctx->Shared->Mutex);
_mesa_HashRemove (ctx->Shared->GL2Objects, impl->_obj.name);
_glthread_UNLOCK_MUTEX (ctx->Shared->Mutex);
_unknown_destructor (intf);
}
static struct gl2_unknown_intf **
_generic_QueryInterface (struct gl2_unknown_intf **intf, enum gl2_uiid uiid)
{
if (uiid == UIID_GENERIC)
{
(**intf).AddRef (intf);
return intf;
}
return _unknown_QueryInterface (intf, uiid);
}
static void
_generic_Delete (struct gl2_generic_intf **intf)
{
struct gl2_generic_impl *impl = (struct gl2_generic_impl *) intf;
if (impl->_obj.delete_status == GL_FALSE)
{
impl->_obj.delete_status = GL_TRUE;
(**intf)._unknown.Release ((struct gl2_unknown_intf **) intf);
}
}
static GLhandleARB
_generic_GetName (struct gl2_generic_intf **intf)
{
struct gl2_generic_impl *impl = (struct gl2_generic_impl *) intf;
return impl->_obj.name;
}
static GLboolean
_generic_GetDeleteStatus (struct gl2_generic_intf **intf)
{
struct gl2_generic_impl *impl = (struct gl2_generic_impl *) intf;
return impl->_obj.delete_status;
}
static const GLcharARB *
_generic_GetInfoLog (struct gl2_generic_intf **intf)
{
struct gl2_generic_impl *impl = (struct gl2_generic_impl *) intf;
return impl->_obj.info_log;
}
static struct gl2_generic_intf _generic_vftbl = {
{
_unknown_AddRef,
_unknown_Release,
_generic_QueryInterface
},
_generic_Delete,
NULL, /* abstract GetType */
_generic_GetName,
_generic_GetDeleteStatus,
_generic_GetInfoLog
};
static void
_generic_constructor (struct gl2_generic_impl *impl)
{
GET_CURRENT_CONTEXT(ctx);
_unknown_constructor ((struct gl2_unknown_impl *) impl);
impl->_vftbl = &_generic_vftbl;
impl->_obj._unknown._destructor = _generic_destructor;
impl->_obj.delete_status = GL_FALSE;
impl->_obj.info_log = NULL;
_glthread_LOCK_MUTEX (ctx->Shared->Mutex);
impl->_obj.name = _mesa_HashFindFreeKeyBlock (ctx->Shared->GL2Objects, 1);
_mesa_HashInsert (ctx->Shared->GL2Objects, impl->_obj.name, (void *) impl);
_glthread_UNLOCK_MUTEX (ctx->Shared->Mutex);
}
struct gl2_container_obj
{
struct gl2_generic_obj _generic;
struct gl2_generic_intf ***attached;
GLuint attached_count;
};
struct gl2_container_impl
{
struct gl2_container_intf *_vftbl;
struct gl2_container_obj _obj;
};
static void
_container_destructor (struct gl2_unknown_intf **intf)
{
struct gl2_container_impl *impl = (struct gl2_container_impl *) intf;
GLuint i;
for (i = 0; i < impl->_obj.attached_count; i++)
{
struct gl2_generic_intf **x = impl->_obj.attached[i];
(**x)._unknown.Release ((struct gl2_unknown_intf **) x);
}
_generic_destructor (intf);
}
static struct gl2_unknown_intf **
_container_QueryInterface (struct gl2_unknown_intf **intf, enum gl2_uiid uiid)
{
if (uiid == UIID_CONTAINER)
{
(**intf).AddRef (intf);
return intf;
}
return _generic_QueryInterface (intf, uiid);
}
static GLboolean
_container_Attach (struct gl2_container_intf **intf, struct gl2_generic_intf **att)
{
GET_CURRENT_CONTEXT(ctx);
struct gl2_container_impl *impl = (struct gl2_container_impl *) intf;
GLuint i;
for (i = 0; i < impl->_obj.attached_count; i++)
if (impl->_obj.attached[i] == att)
{
_mesa_error (ctx, GL_INVALID_OPERATION, "_container_Attach");
return GL_FALSE;
}
impl->_obj.attached = (struct gl2_generic_intf ***) _mesa_realloc (impl->_obj.attached,
impl->_obj.attached_count * sizeof (*impl->_obj.attached), (impl->_obj.attached_count + 1) *
sizeof (*impl->_obj.attached));
if (impl->_obj.attached == NULL)
return GL_FALSE;
impl->_obj.attached[impl->_obj.attached_count] = att;
impl->_obj.attached_count++;
(**att)._unknown.AddRef ((struct gl2_unknown_intf **) att);
return GL_TRUE;
}
static GLboolean
_container_Detach (struct gl2_container_intf **intf, struct gl2_generic_intf **att)
{
GET_CURRENT_CONTEXT(ctx);
struct gl2_container_impl *impl = (struct gl2_container_impl *) intf;
GLuint i, j;
for (i = 0; i < impl->_obj.attached_count; i++)
if (impl->_obj.attached[i] == att)
{
for (j = i; j < impl->_obj.attached_count - 1; j++)
impl->_obj.attached[j] = impl->_obj.attached[j + 1];
impl->_obj.attached = (struct gl2_generic_intf ***) _mesa_realloc (impl->_obj.attached,
impl->_obj.attached_count * sizeof (*impl->_obj.attached),
(impl->_obj.attached_count - 1) * sizeof (*impl->_obj.attached));
impl->_obj.attached_count--;
(**att)._unknown.Release ((struct gl2_unknown_intf **) att);
return GL_TRUE;
}
_mesa_error (ctx, GL_INVALID_OPERATION, "_container_Detach");
return GL_FALSE;
}
static GLsizei
_container_GetAttachedCount (struct gl2_container_intf **intf)
{
struct gl2_container_impl *impl = (struct gl2_container_impl *) intf;
return impl->_obj.attached_count;
}
static struct gl2_generic_intf **
_container_GetAttached (struct gl2_container_intf **intf, GLuint index)
{
struct gl2_container_impl *impl = (struct gl2_container_impl *) intf;
(**impl->_obj.attached[index])._unknown.AddRef (
(struct gl2_unknown_intf **)impl->_obj.attached[index]);
return impl->_obj.attached[index];
}
static struct gl2_container_intf _container_vftbl = {
{
{
_unknown_AddRef,
_unknown_Release,
_container_QueryInterface
},
_generic_Delete,
NULL, /* abstract GetType */
_generic_GetName,
_generic_GetDeleteStatus,
_generic_GetInfoLog
},
_container_Attach,
_container_Detach,
_container_GetAttachedCount,
_container_GetAttached
};
static void
_container_constructor (struct gl2_container_impl *impl)
{
_generic_constructor ((struct gl2_generic_impl *) impl);
impl->_vftbl = &_container_vftbl;
impl->_obj._generic._unknown._destructor = _container_destructor;
impl->_obj.attached = NULL;
impl->_obj.attached_count = 0;
}
struct gl2_3dlabs_shhandle_obj
{
struct gl2_unkinner_obj _unknown;
#if USE_3DLABS_FRONTEND
ShHandle handle;
#endif
};
struct gl2_3dlabs_shhandle_impl
{
struct gl2_3dlabs_shhandle_intf *_vftbl;
struct gl2_3dlabs_shhandle_obj _obj;
};
static void
_3dlabs_shhandle_destructor (struct gl2_unknown_intf **intf)
{
#if USE_3DLABS_FRONTEND
struct gl2_3dlabs_shhandle_impl *impl = (struct gl2_3dlabs_shhandle_impl *) intf;
ShDestruct (impl->_obj.handle);
#endif
_unkinner_destructor (intf);
}
static GLvoid *
_3dlabs_shhandle_GetShHandle (struct gl2_3dlabs_shhandle_intf **intf)
{
#if USE_3DLABS_FRONTEND
struct gl2_3dlabs_shhandle_impl *impl = (struct gl2_3dlabs_shhandle_impl *) intf;
return impl->_obj.handle;
#else
return NULL;
#endif
}
static struct gl2_3dlabs_shhandle_intf _3dlabs_shhandle_vftbl = {
{
_unkinner_AddRef,
_unkinner_Release,
_unkinner_QueryInterface
},
_3dlabs_shhandle_GetShHandle
};
static void
_3dlabs_shhandle_constructor (struct gl2_3dlabs_shhandle_impl *impl, struct gl2_unknown_intf **outer)
{
_unkinner_constructor ((struct gl2_unkinner_impl *) impl, outer);
impl->_vftbl = &_3dlabs_shhandle_vftbl;
#if USE_3DLABS_FRONTEND
impl->_obj.handle = NULL;
#endif
}
struct gl2_shader_obj
{
struct gl2_generic_obj _generic;
struct gl2_3dlabs_shhandle_impl _3dlabs_shhandle;
GLboolean compile_status;
GLcharARB *source;
GLint *offsets;
GLsizei offset_count;
};
struct gl2_shader_impl
{
struct gl2_shader_intf *_vftbl;
struct gl2_shader_obj _obj;
};
static void
_shader_destructor (struct gl2_unknown_intf **intf)
{
struct gl2_shader_impl *impl = (struct gl2_shader_impl *) intf;
_mesa_free ((void *) impl->_obj.source);
_mesa_free ((void *) impl->_obj.offsets);
_3dlabs_shhandle_destructor ((struct gl2_unknown_intf **) &impl->_obj._3dlabs_shhandle._vftbl);
_generic_destructor (intf);
}
static struct gl2_unknown_intf **
_shader_QueryInterface (struct gl2_unknown_intf **intf, enum gl2_uiid uiid)
{
#if USE_3DLABS_FRONTEND
struct gl2_shader_impl *impl = (struct gl2_shader_impl *) intf;
#endif
if (uiid == UIID_SHADER)
{
(**intf).AddRef (intf);
return intf;
}
#if USE_3DLABS_FRONTEND
if (uiid == UIID_3DLABS_SHHANDLE)
{
(**intf).AddRef (intf);
return (struct gl2_unknown_intf **) &impl->_obj._3dlabs_shhandle._vftbl;
}
#endif
return _generic_QueryInterface (intf, uiid);
}
static GLenum
_shader_GetType (struct gl2_generic_intf **intf)
{
return GL_SHADER_OBJECT_ARB;
}
static GLboolean
_shader_GetCompileStatus (struct gl2_shader_intf **intf)
{
struct gl2_shader_impl *impl = (struct gl2_shader_impl *) intf;
return impl->_obj.compile_status;
}
static GLvoid
_shader_SetSource (struct gl2_shader_intf **intf, GLcharARB *src, GLint *off, GLsizei cnt)
{
struct gl2_shader_impl *impl = (struct gl2_shader_impl *) intf;
_mesa_free ((void *) impl->_obj.source);
impl->_obj.source = src;
_mesa_free ((void *) impl->_obj.offsets);
impl->_obj.offsets = off;
impl->_obj.offset_count = cnt;
}
static const GLcharARB *
_shader_GetSource (struct gl2_shader_intf **intf)
{
struct gl2_shader_impl *impl = (struct gl2_shader_impl *) intf;
return impl->_obj.source;
}
static GLvoid
_shader_Compile (struct gl2_shader_intf **intf)
{
struct gl2_shader_impl *impl = (struct gl2_shader_impl *) intf;
#if USE_3DLABS_FRONTEND
char **strings;
TBuiltInResource res;
#else
slang_translation_unit unit;
slang_unit_type type;
slang_info_log info_log;
#endif
impl->_obj.compile_status = GL_FALSE;
_mesa_free ((void *) impl->_obj._generic.info_log);
impl->_obj._generic.info_log = NULL;
#if USE_3DLABS_FRONTEND
/* 3dlabs compiler expects us to feed it with null-terminated string array,
we've got only one big string with offsets, so we must split it; but when
there's only one string to deal with, we pass its address directly */
if (impl->_obj.offset_count <= 1)
strings = &impl->_obj.source;
else
{
GLsizei i, offset = 0;
strings = (char **) _mesa_malloc (impl->_obj.offset_count * sizeof (char *));
if (strings == NULL)
return;
for (i = 0; i < impl->_obj.offset_count; i++)
{
GLsizei size = impl->_obj.offsets[i] - offset;
strings[i] = (char *) _mesa_malloc ((size + 1) * sizeof (char));
if (strings[i] == NULL)
{
GLsizei j;
for (j = 0; j < i; j++)
_mesa_free (strings[j]);
_mesa_free (strings);
return;
}
_mesa_memcpy (strings[i], impl->_obj.source + offset, size * sizeof (char));
strings[i][size] = '\0';
offset = impl->_obj.offsets[i];
}
}
/* TODO set these fields to some REAL numbers */
res.maxLights = 8;
res.maxClipPlanes = 6;
res.maxTextureUnits = 2;
res.maxTextureCoords = 2;
res.maxVertexAttribs = 8;
res.maxVertexUniformComponents = 64;
res.maxVaryingFloats = 8;
res.maxVertexTextureImageUnits = 2;
res.maxCombinedTextureImageUnits = 2;
res.maxTextureImageUnits = 2;
res.maxFragmentUniformComponents = 64;
res.maxDrawBuffers = 1;
if (ShCompile (impl->_obj._3dlabs_shhandle._obj.handle, strings, impl->_obj.offset_count,
EShOptFull, &res, 0))
impl->_obj.compile_status = GL_TRUE;
if (impl->_obj.offset_count > 1)
{
GLsizei i;
for (i = 0; i < impl->_obj.offset_count; i++)
_mesa_free (strings[i]);
_mesa_free (strings);
}
impl->_obj._generic.info_log = _mesa_strdup (ShGetInfoLog (
impl->_obj._3dlabs_shhandle._obj.handle));
#else
if (impl->_vftbl->GetSubType (intf) == GL_FRAGMENT_SHADER)
type = slang_unit_fragment_shader;
else
type = slang_unit_vertex_shader;
slang_info_log_construct (&info_log);
if (_slang_compile (impl->_obj.source, &unit, type, &info_log))
{
impl->_obj.compile_status = GL_TRUE;
}
if (info_log.text != NULL)
impl->_obj._generic.info_log = _mesa_strdup (info_log.text);
else
impl->_obj._generic.info_log = _mesa_strdup ("");
slang_info_log_destruct (&info_log);
#endif
}
static struct gl2_shader_intf _shader_vftbl = {
{
{
_unknown_AddRef,
_unknown_Release,
_shader_QueryInterface
},
_generic_Delete,
_shader_GetType,
_generic_GetName,
_generic_GetDeleteStatus,
_generic_GetInfoLog
},
NULL, /* abstract GetSubType */
_shader_GetCompileStatus,
_shader_SetSource,
_shader_GetSource,
_shader_Compile
};
static void
_shader_constructor (struct gl2_shader_impl *impl)
{
_generic_constructor ((struct gl2_generic_impl *) impl);
_3dlabs_shhandle_constructor (&impl->_obj._3dlabs_shhandle, (struct gl2_unknown_intf **)
&impl->_vftbl);
impl->_vftbl = &_shader_vftbl;
impl->_obj._generic._unknown._destructor = _shader_destructor;
impl->_obj.compile_status = GL_FALSE;
impl->_obj.source = NULL;
impl->_obj.offsets = NULL;
impl->_obj.offset_count = 0;
}
struct gl2_program_obj
{
struct gl2_container_obj _container;
GLboolean link_status;
GLboolean validate_status;
#if USE_3DLABS_FRONTEND
ShHandle linker;
ShHandle uniforms;
#endif
};
struct gl2_program_impl
{
struct gl2_program_intf *_vftbl;
struct gl2_program_obj _obj;
};
static void
_program_destructor (struct gl2_unknown_intf **intf)
{
#if USE_3DLABS_FRONTEND
struct gl2_program_impl *impl = (struct gl2_program_impl *) intf;
ShDestruct (impl->_obj.linker);
ShDestruct (impl->_obj.uniforms);
#endif
_container_destructor (intf);
}
static struct gl2_unknown_intf **
_program_QueryInterface (struct gl2_unknown_intf **intf, enum gl2_uiid uiid)
{
if (uiid == UIID_PROGRAM)
{
(**intf).AddRef (intf);
return intf;
}
return _container_QueryInterface (intf, uiid);
}
static GLenum
_program_GetType (struct gl2_generic_intf **intf)
{
return GL_PROGRAM_OBJECT_ARB;
}
static GLboolean
_program_Attach (struct gl2_container_intf **intf, struct gl2_generic_intf **att)
{
GET_CURRENT_CONTEXT(ctx);
struct gl2_unknown_intf **sha;
sha = (**att)._unknown.QueryInterface ((struct gl2_unknown_intf **) att, UIID_SHADER);
if (sha == NULL)
{
_mesa_error (ctx, GL_INVALID_OPERATION, "_program_Attach");
return GL_FALSE;
}
(**sha).Release (sha);
return _container_Attach (intf, att);
}
static GLboolean
_program_GetLinkStatus (struct gl2_program_intf **intf)
{
struct gl2_program_impl *impl = (struct gl2_program_impl *) intf;
return impl->_obj.link_status;
}
static GLboolean
_program_GetValidateStatus (struct gl2_program_intf **intf)
{
struct gl2_program_impl *impl = (struct gl2_program_impl *) intf;
return impl->_obj.validate_status;
}
static GLvoid
_program_Link (struct gl2_program_intf **intf)
{
struct gl2_program_impl *impl = (struct gl2_program_impl *) intf;
#if USE_3DLABS_FRONTEND
ShHandle *handles;
GLuint i;
#endif
impl->_obj.link_status = GL_FALSE;
_mesa_free ((void *) impl->_obj._container._generic.info_log);
impl->_obj._container._generic.info_log = NULL;
#if USE_3DLABS_FRONTEND
handles = (ShHandle *) _mesa_malloc (impl->_obj._container.attached_count * sizeof (ShHandle));
if (handles == NULL)
return;
for (i = 0; i < impl->_obj._container.attached_count; i++)
{
struct gl2_generic_intf **gen = impl->_obj._container.attached[i];
struct gl2_3dlabs_shhandle_intf **sh;
sh = (struct gl2_3dlabs_shhandle_intf **) (**gen)._unknown.QueryInterface (
(struct gl2_unknown_intf **) gen, UIID_3DLABS_SHHANDLE);
if (sh != NULL)
{
handles[i] = (**sh).GetShHandle (sh);
(**sh)._unknown.Release ((struct gl2_unknown_intf **) sh);
}
else
{
_mesa_free (handles);
return;
}
}
if (ShLink (impl->_obj.linker, handles, impl->_obj._container.attached_count,
impl->_obj.uniforms, NULL, NULL))
impl->_obj.link_status = GL_TRUE;
impl->_obj._container._generic.info_log = _mesa_strdup (ShGetInfoLog (impl->_obj.linker));
#endif
}
static GLvoid
_program_Validate (struct gl2_program_intf **intf)
{
struct gl2_program_impl *impl = (struct gl2_program_impl *) intf;
impl->_obj.validate_status = GL_FALSE;
_mesa_free ((void *) impl->_obj._container._generic.info_log);
impl->_obj._container._generic.info_log = NULL;
/* TODO validate */
}
static struct gl2_program_intf _program_vftbl = {
{
{
{
_unknown_AddRef,
_unknown_Release,
_program_QueryInterface
},
_generic_Delete,
_program_GetType,
_generic_GetName,
_generic_GetDeleteStatus,
_generic_GetInfoLog
},
_program_Attach,
_container_Detach,
_container_GetAttachedCount,
_container_GetAttached
},
_program_GetLinkStatus,
_program_GetValidateStatus,
_program_Link,
_program_Validate
};
static void
_program_constructor (struct gl2_program_impl *impl)
{
_container_constructor ((struct gl2_container_impl *) impl);
impl->_vftbl = &_program_vftbl;
impl->_obj._container._generic._unknown._destructor = _program_destructor;
impl->_obj.link_status = GL_FALSE;
impl->_obj.validate_status = GL_FALSE;
#if USE_3DLABS_FRONTEND
impl->_obj.linker = ShConstructLinker (EShExVertexFragment, 0);
impl->_obj.uniforms = ShConstructUniformMap ();
#endif
}
struct gl2_fragment_shader_obj
{
struct gl2_shader_obj _shader;
};
struct gl2_fragment_shader_impl
{
struct gl2_fragment_shader_intf *_vftbl;
struct gl2_fragment_shader_obj _obj;
};
static void
_fragment_shader_destructor (struct gl2_unknown_intf **intf)
{
struct gl2_fragment_shader_impl *impl = (struct gl2_fragment_shader_impl *) intf;
(void) impl;
/* TODO free fragment shader data */
_shader_destructor (intf);
}
static struct gl2_unknown_intf **
_fragment_shader_QueryInterface (struct gl2_unknown_intf **intf, enum gl2_uiid uiid)
{
if (uiid == UIID_FRAGMENT_SHADER)
{
(**intf).AddRef (intf);
return intf;
}
return _shader_QueryInterface (intf, uiid);
}
static GLenum
_fragment_shader_GetSubType (struct gl2_shader_intf **intf)
{
return GL_FRAGMENT_SHADER_ARB;
}
static struct gl2_fragment_shader_intf _fragment_shader_vftbl = {
{
{
{
_unknown_AddRef,
_unknown_Release,
_fragment_shader_QueryInterface
},
_generic_Delete,
_shader_GetType,
_generic_GetName,
_generic_GetDeleteStatus,
_generic_GetInfoLog
},
_fragment_shader_GetSubType,
_shader_GetCompileStatus,
_shader_SetSource,
_shader_GetSource,
_shader_Compile
}
};
static void
_fragment_shader_constructor (struct gl2_fragment_shader_impl *impl)
{
_shader_constructor ((struct gl2_shader_impl *) impl);
impl->_vftbl = &_fragment_shader_vftbl;
impl->_obj._shader._generic._unknown._destructor = _fragment_shader_destructor;
#if USE_3DLABS_FRONTEND
impl->_obj._shader._3dlabs_shhandle._obj.handle = ShConstructCompiler (EShLangFragment, 0);
#endif
}
struct gl2_vertex_shader_obj
{
struct gl2_shader_obj _shader;
};
struct gl2_vertex_shader_impl
{
struct gl2_vertex_shader_intf *_vftbl;
struct gl2_vertex_shader_obj _obj;
};
static void
_vertex_shader_destructor (struct gl2_unknown_intf **intf)
{
struct gl2_vertex_shader_impl *impl = (struct gl2_vertex_shader_impl *) intf;
(void) impl;
/* TODO free vertex shader data */
_shader_destructor (intf);
}
static struct gl2_unknown_intf **
_vertex_shader_QueryInterface (struct gl2_unknown_intf **intf, enum gl2_uiid uiid)
{
if (uiid == UIID_VERTEX_SHADER)
{
(**intf).AddRef (intf);
return intf;
}
return _shader_QueryInterface (intf, uiid);
}
static GLenum
_vertex_shader_GetSubType (struct gl2_shader_intf **intf)
{
return GL_VERTEX_SHADER_ARB;
}
static struct gl2_vertex_shader_intf _vertex_shader_vftbl = {
{
{
{
_unknown_AddRef,
_unknown_Release,
_vertex_shader_QueryInterface
},
_generic_Delete,
_shader_GetType,
_generic_GetName,
_generic_GetDeleteStatus,
_generic_GetInfoLog
},
_vertex_shader_GetSubType,
_shader_GetCompileStatus,
_shader_SetSource,
_shader_GetSource,
_shader_Compile
}
};
static void
_vertex_shader_constructor (struct gl2_vertex_shader_impl *impl)
{
_shader_constructor ((struct gl2_shader_impl *) impl);
impl->_vftbl = &_vertex_shader_vftbl;
impl->_obj._shader._generic._unknown._destructor = _vertex_shader_destructor;
#if USE_3DLABS_FRONTEND
impl->_obj._shader._3dlabs_shhandle._obj.handle = ShConstructCompiler (EShLangVertex, 0);
#endif
}
GLhandleARB
_mesa_3dlabs_create_shader_object (GLenum shaderType)
{
switch (shaderType)
{
case GL_FRAGMENT_SHADER_ARB:
{
struct gl2_fragment_shader_impl *x = (struct gl2_fragment_shader_impl *)
_mesa_malloc (sizeof (struct gl2_fragment_shader_impl));
if (x != NULL)
{
_fragment_shader_constructor (x);
return x->_obj._shader._generic.name;
}
}
break;
case GL_VERTEX_SHADER_ARB:
{
struct gl2_vertex_shader_impl *x = (struct gl2_vertex_shader_impl *)
_mesa_malloc (sizeof (struct gl2_vertex_shader_impl));
if (x != NULL)
{
_vertex_shader_constructor (x);
return x->_obj._shader._generic.name;
}
}
break;
}
return 0;
}
GLhandleARB
_mesa_3dlabs_create_program_object (void)
{
struct gl2_program_impl *x = (struct gl2_program_impl *)
_mesa_malloc (sizeof (struct gl2_program_impl));
if (x != NULL)
{
_program_constructor (x);
return x->_obj._container._generic.name;
}
return 0;
}
void
_mesa_init_shaderobjects_3dlabs (GLcontext *ctx)
{
#if USE_3DLABS_FRONTEND
_glslang_3dlabs_InitProcess ();
_glslang_3dlabs_ShInitialize ();
#endif
}
/*
* Mesa 3-D graphics library
* Version: 6.3
*
* Copyright (C) 2005 Brian Paul All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#ifndef SHADEROBJECTS_3DLABS_H
#define SHADEROBJECTS_3DLABS_H
#include "mtypes.h"
extern GLhandleARB
_mesa_3dlabs_create_shader_object (GLenum);
extern GLhandleARB
_mesa_3dlabs_create_program_object (void);
extern void
_mesa_init_shaderobjects_3dlabs (GLcontext *ctx);
#endif
/*
* Mesa 3-D graphics library
* Version: 6.3
*
* Copyright (C) 2005 Brian Paul All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#ifndef SHADEROBJECTS_3DLABS_H
#define SHADEROBJECTS_3DLABS_H
#include "mtypes.h"
extern GLhandleARB
_mesa_3dlabs_create_shader_object (GLenum);
extern GLhandleARB
_mesa_3dlabs_create_program_object (void);
extern void
_mesa_init_shaderobjects_3dlabs (GLcontext *ctx);
#endif
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"int __constructor (const float _f) {\n"
" int _i;\n"
" __asm float_to_int _i, _f;\n"
" return _i;\n"
"}\n"
"\n"
"bool __constructor (const int _i) {\n"
" return _i != 0;\n"
"}\n"
"\n"
"bool __constructor (const float _f) {\n"
" return _f != 0.0;\n"
"}\n"
"\n"
"int __constructor (const bool _b) {\n"
" return _b ? 1 : 0;\n"
"}\n"
"\n"
"float __constructor (const bool _b) {\n"
" return _b ? 1.0 : 0.0;\n"
"}\n"
"\n"
"float __constructor (const int _i) {\n"
" float _f;\n"
" __asm int_to_float _f, _i;\n"
" return _f;\n"
"}\n"
"\n"
"bool __constructor (const bool _b) {\n"
" return _b;\n"
"}\n"
"\n"
"int __constructor (const int _i) {\n"
" return _i;\n"
"}\n"
"\n"
"float __constructor (const float _f) {\n"
" return _f;\n"
"}\n"
"\n"
"vec2 __constructor (const float _f) {\n"
" return vec2 (_f, _f);\n"
"}\n"
"\n"
"vec2 __constructor (const int _i) {\n"
" return vec2 (_i, _i);\n"
"}\n"
"\n"
"vec2 __constructor (const bool _b) {\n"
" return vec2 (_b, _b);\n"
"}\n"
"\n"
"vec3 __constructor (const float _f) {\n"
" return vec3 (_f, _f, _f);\n"
"}\n"
"\n"
"vec3 __constructor (const int _i) {\n"
" return vec3 (_i, _i, _i);\n"
"}\n"
"\n"
"vec3 __constructor (const bool _b) {\n"
" return vec3 (_b, _b, _b);\n"
"}\n"
"\n"
"vec4 __constructor (const float _f) {\n"
" return vec4 (_f, _f, _f, _f);\n"
"}\n"
"\n"
"vec4 __constructor (const int _i) {\n"
" return vec4 (_i, _i, _i, _i);\n"
"}\n"
"\n"
"vec4 __constructor (const bool _b) {\n"
" return vec4 (_b, _b, _b, _b);\n"
"}\n"
"\n"
"ivec2 __constructor (const int _i) {\n"
" return ivec2 (_i, _i);\n"
"}\n"
"\n"
"ivec2 __constructor (const float _f) {\n"
" return ivec2 (_f, _f);\n"
"}\n"
"\n"
"ivec2 __constructor (const bool _b) {\n"
" return ivec2 (_b, _b);\n"
"}\n"
"\n"
"ivec3 __constructor (const int _i) {\n"
" return ivec3 (_i, _i, _i);\n"
"}\n"
"\n"
"ivec3 __constructor (const float _f) {\n"
" return ivec3 (_f, _f, _f);\n"
"}\n"
"\n"
"ivec3 __constructor (const bool _b) {\n"
" return ivec3 (_b, _b, _b);\n"
"}\n"
"\n"
"ivec4 __constructor (const int _i) {\n"
" return ivec4 (_i, _i, _i, _i);\n"
"}\n"
"\n"
"ivec4 __constructor (const float _f) {\n"
" return ivec4 (_f, _f, _f, _f);\n"
"}\n"
"\n"
"ivec4 __constructor (const bool _b) {\n"
" return ivec4 (_b, _b, _b, _b);\n"
"}\n"
"\n"
"bvec2 __constructor (const bool _b) {\n"
" return bvec2 (_b, _b);\n"
"}\n"
"\n"
"bvec2 __constructor (const float _f) {\n"
" return bvec2 (_f, _f);\n"
"}\n"
"\n"
"bvec2 __constructor (const int _i) {\n"
" return bvec2 (_i, _i);\n"
"}\n"
"\n"
"bvec3 __constructor (const bool _b) {\n"
" return bvec3 (_b, _b, _b);\n"
"}\n"
"\n"
"bvec3 __constructor (const float _f) {\n"
" return bvec3 (_f, _f, _f);\n"
"}\n"
"\n"
"bvec3 __constructor (const int _i) {\n"
" return bvec3 (_i, _i, _i);\n"
"}\n"
"\n"
"bvec4 __constructor (const bool _b) {\n"
" return bvec4 (_b, _b, _b, _b);\n"
"}\n"
"\n"
"bvec4 __constructor (const float _f) {\n"
" return bvec4 (_f, _f, _f, _f);\n"
"}\n"
"\n"
"bvec4 __constructor (const int _i) {\n"
" return bvec4 (_i, _i, _i, _i);\n"
"}\n"
"\n"
"mat2 __constructor (const float _f) {\n"
" return mat2 (\n"
" _f, .0,\n"
" .0, _f\n"
" );\n"
"}\n"
"\n"
"mat2 __constructor (const int _i) {\n"
" return mat2 (\n"
" _i, .0,\n"
" .0, _i\n"
" );\n"
"}\n"
"\n"
"mat2 __constructor (const bool _b) {\n"
" return mat2 (\n"
" _b, .0,\n"
" .0, _b\n"
" );\n"
"}\n"
"\n"
"mat3 __constructor (const float _f) {\n"
" return mat3 (\n"
" _f, .0, .0,\n"
" .0, _f, .0,\n"
" .0, .0, _f\n"
" );\n"
"}\n"
"\n"
"mat3 __constructor (const int _i) {\n"
" return mat3 (\n"
" _i, .0, .0,\n"
" .0, _i, .0,\n"
" .0, .0, _i\n"
" );\n"
"}\n"
"\n"
"mat3 __constructor (const bool _b) {\n"
" return mat3 (\n"
" _b, .0, .0,\n"
" .0, _b, .0,\n"
" .0, .0, _b\n"
" );\n"
"}\n"
"\n"
"mat4 __constructor (const float _f) {\n"
" return mat4 (\n"
" _f, .0, .0, .0,\n"
" .0, _f, .0, .0,\n"
" .0, .0, _f, .0,\n"
" .0, .0, .0, _f\n"
" );\n"
"}\n"
"\n"
"mat4 __constructor (const int _i) {\n"
" return mat4 (\n"
" _i, .0, .0, .0,\n"
" .0, _i, .0, .0,\n"
" .0, .0, _i, .0,\n"
" .0, .0, .0, _i\n"
" );\n"
"}\n"
"\n"
"mat4 __constructor (const bool _b) {\n"
" return mat4 (\n"
" _b, .0, .0, .0,\n"
" .0, _b, .0, .0,\n"
" .0, .0, _b, .0,\n"
" .0, .0, .0, _b\n"
" );\n"
"}\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"void __operator += (inout float a, const float b) {\n"
" __asm float_add a, a, b;\n"
"}\n"
"\n"
"float __operator - (const float a) {\n"
" float c;\n"
" __asm float_negate c, a;\n"
" return c;\n"
"}\n"
"\n"
"void __operator -= (inout float a, const float b) {\n"
" a += -b;\n"
"}\n"
"\n"
"void __operator *= (inout float a, const float b) {\n"
" __asm float_multiply a, a, b;\n"
"}\n"
"\n"
"void __operator /= (inout float a, const float b) {\n"
" __asm float_divide a, a, b;\n"
"}\n"
"\n"
"float __operator + (const float a, const float b) {\n"
" float c;\n"
" c = a;\n"
" return c += b;\n"
"}\n"
"\n"
"void __operator += (inout int a, const int b) {\n"
" a = int (float (a) + float (b));\n"
"}\n"
"\n"
"int __operator - (const int a) {\n"
" return int (-float (a));\n"
"}\n"
"\n"
"void __operator -= (inout int a, const int b) {\n"
" a += -b;\n"
"}\n"
"\n"
"float __operator * (const float a, const float b) {\n"
" float c;\n"
" c = a;\n"
" return c *= b;\n"
"}\n"
"\n"
"void __operator *= (inout int a, const int b) {\n"
" a = int (float (a) * float (b));\n"
"}\n"
"\n"
"float __operator / (const float a, const float b) {\n"
" float c;\n"
" c = a;\n"
" return c /= b;\n"
"}\n"
"\n"
"void __operator /= (inout int a, const int b) {\n"
" a = int (float (a) / float (b));\n"
"}\n"
"\n"
"void __operator += (inout vec2 v, const vec2 u) {\n"
" v.x += u.x, v.y += u.y;\n"
"}\n"
"\n"
"void __operator -= (inout vec2 v, const vec2 u) {\n"
" v.x -= u.x, v.y -= u.y;\n"
"}\n"
"\n"
"void __operator *= (inout vec2 v, const vec2 u) {\n"
" v.x *= u.x, v.y *= u.y;\n"
"}\n"
"\n"
"void __operator /= (inout vec2 v, const vec2 u) {\n"
" v.x /= u.x, v.y /= u.y;\n"
"}\n"
"\n"
"void __operator += (inout vec3 v, const vec3 u) {\n"
" v.x += u.x, v.y += u.y, v.z += u.z;\n"
"}\n"
"\n"
"void __operator -= (inout vec3 v, const vec3 u) {\n"
" v.x -= u.x, v.y -= u.y, v.z -= u.z;\n"
"}\n"
"\n"
"void __operator *= (inout vec3 v, const vec3 u) {\n"
" v.x *= u.x, v.y *= u.y, v.z *= u.z;\n"
"}\n"
"\n"
"void __operator /= (inout vec3 v, const vec3 u) {\n"
" v.x /= u.x, v.y /= u.y, v.z /= u.z;\n"
"}\n"
"\n"
"void __operator += (inout vec4 v, const vec4 u) {\n"
" v.x += u.x, v.y += u.y, v.z += u.z, v.w += u.w;\n"
"}\n"
"\n"
"void __operator -= (inout vec4 v, const vec4 u) {\n"
" v.x -= u.x, v.y -= u.y, v.z -= u.z, v.w -= u.w;\n"
"}\n"
"\n"
"void __operator *= (inout vec4 v, const vec4 u) {\n"
" v.x *= u.x, v.y *= u.y, v.z *= u.z, v.w *= u.w;\n"
"}\n"
"\n"
"void __operator /= (inout vec4 v, const vec4 u) {\n"
" v.x /= u.x, v.y /= u.y, v.z /= u.z, v.w /= u.w;\n"
"}\n"
"\n"
"void __operator += (inout ivec2 v, const ivec2 u) {\n"
" v.x += u.x, v.y += u.y;\n"
"}\n"
"\n"
"void __operator -= (inout ivec2 v, const ivec2 u) {\n"
" v.x -= u.x, v.y -= u.y;\n"
"}\n"
"\n"
"void __operator *= (inout ivec2 v, const ivec2 u) {\n"
" v.x *= u.x, v.y *= u.y;\n"
"}\n"
"\n"
"void __operator /= (inout ivec2 v, const ivec2 u) {\n"
" v.x /= u.x, v.y /= u.y;\n"
"}\n"
"\n"
"void __operator += (inout ivec3 v, const ivec3 u) {\n"
" v.x += u.x, v.y += u.y, v.z += u.z;\n"
"}\n"
"\n"
"void __operator -= (inout ivec3 v, const ivec3 u) {\n"
" v.x -= u.x, v.y -= u.y, v.z -= u.z;\n"
"}\n"
"\n"
"void __operator *= (inout ivec3 v, const ivec3 u) {\n"
" v.x *= u.x, v.y *= u.y, v.z *= u.z;\n"
"}\n"
"\n"
"void __operator /= (inout ivec3 v, const ivec3 u) {\n"
" v.x /= u.x, v.y /= u.y, v.z /= u.z;\n"
"}\n"
"\n"
"void __operator += (inout ivec4 v, const ivec4 u) {\n"
" v.x += u.x, v.y += u.y, v.z += u.z, v.w += u.w;\n"
"}\n"
"\n"
"void __operator -= (inout ivec4 v, const ivec4 u) {\n"
" v.x -= u.x, v.y -= u.y, v.z -= u.z, v.w -= u.w;\n"
"}\n"
"\n"
"void __operator *= (inout ivec4 v, const ivec4 u) {\n"
" v.x *= u.x, v.y *= u.y, v.z *= u.z, v.w *= u.w;\n"
"}\n"
"\n"
"void __operator /= (inout ivec4 v, const ivec4 u) {\n"
" v.x /= u.x, v.y /= u.y, v.z /= u.z, v.w /= u.w;\n"
"}\n"
"\n"
"void __operator += (inout mat2 m, const mat2 n) {\n"
" m[0] += n[0], m[1] += n[1];\n"
"}\n"
"\n"
"void __operator -= (inout mat2 m, const mat2 n) {\n"
" m[0] -= n[0], m[1] -= n[1];\n"
"}\n"
"\n"
"vec2 __operator * (const mat2 m, const vec2 v) {\n"
" return vec2 (\n"
" v.x * m[0].x + v.y * m[1].x,\n"
" v.x * m[0].y + v.y * m[1].y\n"
" );\n"
"}\n"
"\n"
"mat2 __operator * (const mat2 m, const mat2 n) {\n"
" return mat2 (m * n[0], m * n[1]);\n"
"}\n"
"\n"
"void __operator *= (inout mat2 m, const mat2 n) {\n"
" m = m * n;\n"
"}\n"
"\n"
"void __operator /= (inout mat2 m, const mat2 n) {\n"
" m[0] /= n[0], m[1] /= n[1];\n"
"}\n"
"\n"
"void __operator += (inout mat3 m, const mat3 n) {\n"
" m[0] += n[0], m[1] += n[1], m[2] += n[2];\n"
"}\n"
"\n"
"void __operator -= (inout mat3 m, const mat3 n) {\n"
" m[0] -= n[0], m[1] -= n[1], m[2] -= n[2];\n"
"}\n"
"\n"
"vec3 __operator * (const mat3 m, const vec3 v) {\n"
" return vec3 (\n"
" v.x * m[0].x + v.y * m[1].x + v.z * m[2].x,\n"
" v.x * m[0].y + v.y * m[1].y + v.z * m[2].y,\n"
" v.x * m[0].z + v.y * m[1].z + v.z * m[2].z\n"
" );\n"
"}\n"
"\n"
"mat3 __operator * (const mat3 m, const mat3 n) {\n"
" return mat3 (m * n[0], m * n[1], m * n[2]);\n"
"}\n"
"\n"
"void __operator *= (inout mat3 m, const mat3 n) {\n"
" m = m * n;\n"
"}\n"
"\n"
"void __operator /= (inout mat3 m, const mat3 n) {\n"
" m[0] /= n[0], m[1] /= n[1], m[2] /= n[2];\n"
"}\n"
"\n"
"void __operator += (inout mat4 m, const mat4 n) {\n"
" m[0] += n[0], m[1] += n[1], m[2] += n[2], m[3] += n[3];\n"
"}\n"
"\n"
"void __operator -= (inout mat4 m, const mat4 n) {\n"
" m[0] -= n[0], m[1] -= n[1], m[2] -= n[2], m[3] -= n[3];\n"
"}\n"
"\n"
"vec4 __operator * (const mat4 m, const vec4 v) {\n"
" return vec4 (\n"
" v.x * m[0].x + v.y * m[1].x + v.z * m[2].x + v.w * m[3].x,\n"
" v.x * m[0].y + v.y * m[1].y + v.z * m[2].y + v.w * m[3].y,\n"
" v.x * m[0].z + v.y * m[1].z + v.z * m[2].z + v.w * m[3].z,\n"
" v.x * m[0].w + v.y * m[1].w + v.z * m[2].w + v.w * m[3].w\n"
" );\n"
"}\n"
"\n"
"mat4 __operator * (const mat4 m, const mat4 n) {\n"
" return mat4 (m * n[0], m * n[1], m * n[2], m * n[3]);\n"
"}\n"
"\n"
"void __operator *= (inout mat4 m, const mat4 n) {\n"
" m = m * n;\n"
"}\n"
"\n"
"void __operator /= (inout mat4 m, const mat4 n) {\n"
" m[0] /= n[0], m[1] /= n[1], m[2] /= n[2], m[3] /= n[3];\n"
"}\n"
"\n"
"void __operator += (inout vec2 v, const float a) {\n"
" v.x += a, v.y += a;\n"
"}\n"
"\n"
"void __operator -= (inout vec2 v, const float a) {\n"
" v.x -= a, v.y -= a;\n"
"}\n"
"\n"
"void __operator *= (inout vec2 v, const float a) {\n"
" v.x *= a, v.y *= a;\n"
"}\n"
"\n"
"void __operator /= (inout vec2 v, const float a) {\n"
" v.x /= a, v.y /= a;\n"
"}\n"
"\n"
"void __operator += (inout vec3 v, const float a) {\n"
" v.x += a, v.y += a, v.z += a;\n"
"}\n"
"\n"
"void __operator -= (inout vec3 v, const float a) {\n"
" v.x -= a, v.y -= a, v.z -= a;\n"
"}\n"
"\n"
"void __operator *= (inout vec3 v, const float a) {\n"
" v.x *= a, v.y *= a, v.z *= a;\n"
"}\n"
"\n"
"void __operator /= (inout vec3 v, const float a) {\n"
" v.x /= a, v.y /= a, v.z /= a;\n"
"}\n"
"\n"
"void __operator += (inout vec4 v, const float a) {\n"
" v.x += a, v.y += a, v.z += a, v.w += a;\n"
"}\n"
"\n"
"void __operator -= (inout vec4 v, const float a) {\n"
" v.x -= a, v.y -= a, v.z -= a, v.w -= a;\n"
"}\n"
"\n"
"void __operator *= (inout vec4 v, const float a) {\n"
" v.x *= a, v.y *= a, v.z *= a, v.w *= a;\n"
"}\n"
"\n"
"void __operator /= (inout vec4 v, const float a) {\n"
" v.x /= a, v.y /= a, v.z /= a, v.w /= a;\n"
"}\n"
"\n"
"void __operator += (inout mat2 m, const float a) {\n"
" m[0] += a, m[1] += a;\n"
"}\n"
"\n"
"void __operator -= (inout mat2 m, const float a) {\n"
" m[0] -= a, m[1] -= a;\n"
"}\n"
"\n"
"void __operator *= (inout mat2 m, const float a) {\n"
" m[0] *= a, m[1] *= a;\n"
"}\n"
"\n"
"void __operator /= (inout mat2 m, const float a) {\n"
" m[0] /= a, m[1] /= a;\n"
"}\n"
"\n"
"void __operator += (inout mat3 m, const float a) {\n"
" m[0] += a, m[1] += a, m[2] += a;\n"
"}\n"
"\n"
"void __operator -= (inout mat3 m, const float a) {\n"
" m[0] -= a, m[1] -= a, m[2] -= a;\n"
"}\n"
"\n"
"void __operator *= (inout mat3 m, const float a) {\n"
" m[0] *= a, m[1] *= a, m[2] *= a;\n"
"}\n"
"\n"
"void __operator /= (inout mat3 m, const float a) {\n"
" m[0] /= a, m[1] /= a, m[2] /= a;\n"
"}\n"
"\n"
"void __operator += (inout mat4 m, const float a) {\n"
" m[0] += a, m[1] += a, m[2] += a, m[3] += a;\n"
"}\n"
"\n"
"void __operator -= (inout mat4 m, const float a) {\n"
" m[0] -= a, m[1] -= a, m[2] -= a, m[3] -= a;\n"
"}\n"
"\n"
"void __operator *= (inout mat4 m, const float a) {\n"
" m[0] *= a, m[1] *= a, m[2] *= a, m[3] *= a;\n"
"}\n"
"\n"
"void __operator /= (inout mat4 m, const float a) {\n"
" m[0] /= a, m[1] /= a, m[2] /= a, m[3] /= a;\n"
"}\n"
"\n"
"vec2 __operator * (const vec2 v, const mat2 m) {\n"
" return vec2 (\n"
" v.x * m[0].x + v.y * m[0].y,\n"
" v.x * m[1].x + v.y * m[1].y\n"
" );\n"
"}\n"
"\n"
"void __operator *= (inout vec2 v, const mat2 m) {\n"
" v = v * m;\n"
"}\n"
"\n"
"vec3 __operator * (const vec3 v, const mat3 m) {\n"
" return vec3 (\n"
" v.x * m[0].x + v.y * m[0].y + v.z * m[0].z,\n"
" v.x * m[1].x + v.y * m[1].y + v.z * m[1].z,\n"
" v.x * m[2].x + v.y * m[2].y + v.z * m[2].z\n"
" );\n"
"}\n"
"\n"
"void __operator *= (inout vec3 v, const mat3 m) {\n"
" v = v * m;\n"
"}\n"
"\n"
"vec4 __operator * (const vec4 v, const mat4 m) {\n"
" return vec4 (\n"
" v.x * m[0].x + v.y * m[0].y + v.z * m[0].z + v.w * m[0].w,\n"
" v.x * m[1].x + v.y * m[1].y + v.z * m[1].z + v.w * m[1].w,\n"
" v.x * m[2].x + v.y * m[2].y + v.z * m[2].z + v.w * m[2].w,\n"
" v.x * m[3].x + v.y * m[3].y + v.z * m[3].z + v.w * m[3].w\n"
" );\n"
"}\n"
"\n"
"void __operator *= (inout vec4 v, const mat4 m) {\n"
" v = v * m;\n"
"}\n"
"\n"
"float __operator - (const float a, const float b) {\n"
" return a + -b;\n"
"}\n"
"\n"
"int __operator + (const int a, const int b) {\n"
" int c;\n"
" c = a;\n"
" return c += b;\n"
"}\n"
"\n"
"int __operator - (const int a, const int b) {\n"
" return a + -b;\n"
"}\n"
"\n"
"int __operator * (const int a, const int b) {\n"
" int c;\n"
" return (c = a) *= b;\n"
"}\n"
"\n"
"int __operator / (const int a, const int b) {\n"
" int c;\n"
" return (c = a) /= b;\n"
"}\n"
"\n"
"vec2 __operator + (const vec2 v, const vec2 u) {\n"
" return vec2 (v.x + u.x, v.y + u.y);\n"
"}\n"
"\n"
"vec2 __operator - (const vec2 v, const vec2 u) {\n"
" return vec2 (v.x - u.x, v.y - u.y);\n"
"}\n"
"\n"
"vec3 __operator + (const vec3 v, const vec3 u) {\n"
" return vec3 (v.x + u.x, v.y + u.y, v.z + u.z);\n"
"}\n"
"\n"
"vec3 __operator - (const vec3 v, const vec3 u) {\n"
" return vec3 (v.x - u.x, v.y - u.y, v.z - u.z);\n"
"}\n"
"\n"
"vec4 __operator + (const vec4 v, const vec4 u) {\n"
" return vec4 (v.x + u.x, v.y + u.y, v.z + u.z, v.w + u.w);\n"
"}\n"
"\n"
"vec4 __operator - (const vec4 v, const vec4 u) {\n"
" return vec4 (v.x - u.x, v.y - u.y, v.z - u.z, v.w - u.w);\n"
"}\n"
"\n"
"ivec2 __operator + (const ivec2 v, const ivec2 u) {\n"
" return ivec2 (v.x + u.x, v.y + u.y);\n"
"}\n"
"\n"
"ivec2 __operator - (const ivec2 v, const ivec2 u) {\n"
" return ivec2 (v.x - u.x, v.y - u.y);\n"
"}\n"
"\n"
"ivec3 __operator + (const ivec3 v, const ivec3 u) {\n"
" return ivec3 (v.x + u.x, v.y + u.y, v.z + u.z);\n"
"}\n"
"\n"
"ivec3 __operator - (const ivec3 v, const ivec3 u) {\n"
" return ivec3 (v.x - u.x, v.y - u.y, v.z - u.z);\n"
"}\n"
"\n"
"ivec4 __operator + (const ivec4 v, const ivec4 u) {\n"
" return ivec4 (v.x + u.x, v.y + u.y, v.z + u.z, v.w + u.w);\n"
"}\n"
"\n"
"ivec4 __operator - (const ivec4 v, const ivec4 u) {\n"
" return ivec4 (v.x - u.x, v.y - u.y, v.z - u.z, v.w - u.w);\n"
"}\n"
"\n"
"mat2 __operator + (const mat2 m, const mat2 n) {\n"
" return mat2 (m[0] + n[0], m[1] + n[1]);\n"
"}\n"
"\n"
"mat2 __operator - (const mat2 m, const mat2 n) {\n"
" return mat2 (m[0] - n[0], m[1] - n[1]);\n"
"}\n"
"\n"
"mat3 __operator + (const mat3 m, const mat3 n) {\n"
" return mat3 (m[0] + n[0], m[1] + n[1], m[2] + n[2]);\n"
"}\n"
"\n"
"mat3 __operator - (const mat3 m, const mat3 n) {\n"
" return mat3 (m[0] - n[0], m[1] - n[1], m[2] - n[2]);\n"
"}\n"
"\n"
"mat4 __operator + (const mat4 m, const mat4 n) {\n"
" return mat4 (m[0] + n[0], m[1] + n[1], m[2] + n[2], m[3] + n[3]);\n"
"}\n"
"\n"
"mat4 __operator - (const mat4 m, const mat4 n) {\n"
" return mat4 (m[0] - n[0], m[1] - n[1], m[2] - n[2], m[3] - n[3]);\n"
"}\n"
"\n"
"vec2 __operator + (const float a, const vec2 u) {\n"
" return vec2 (a + u.x, a + u.y);\n"
"}\n"
"\n"
"vec2 __operator + (const vec2 v, const float b) {\n"
" return vec2 (v.x + b, v.y + b);\n"
"}\n"
"\n"
"vec2 __operator - (const float a, const vec2 u) {\n"
" return vec2 (a - u.x, a - u.y);\n"
"}\n"
"\n"
"vec2 __operator - (const vec2 v, const float b) {\n"
" return vec2 (v.x - b, v.y - b);\n"
"}\n"
"\n"
"vec2 __operator * (const float a, const vec2 u) {\n"
" return vec2 (a * u.x, a * u.y);\n"
"}\n"
"\n"
"vec2 __operator * (const vec2 v, const float b) {\n"
" return vec2 (v.x * b, v.y * b);\n"
"}\n"
"\n"
"vec2 __operator / (const float a, const vec2 u) {\n"
" return vec2 (a / u.x, a / u.y);\n"
"}\n"
"\n"
"vec2 __operator / (const vec2 v, const float b) {\n"
" return vec2 (v.x / b, v.y / b);\n"
"}\n"
"\n"
"vec3 __operator + (const float a, const vec3 u) {\n"
" return vec3 (a + u.x, a + u.y, a + u.z);\n"
"}\n"
"\n"
"vec3 __operator + (const vec3 v, const float b) {\n"
" return vec3 (v.x + b, v.y + b, v.z + b);\n"
"}\n"
"\n"
"vec3 __operator - (const float a, const vec3 u) {\n"
" return vec3 (a - u.x, a - u.y, a - u.z);\n"
"}\n"
"\n"
"vec3 __operator - (const vec3 v, const float b) {\n"
" return vec3 (v.x - b, v.y - b, v.z - b);\n"
"}\n"
"\n"
"vec3 __operator * (const float a, const vec3 u) {\n"
" return vec3 (a * u.x, a * u.y, a * u.z);\n"
"}\n"
"\n"
"vec3 __operator * (const vec3 v, const float b) {\n"
" return vec3 (v.x * b, v.y * b, v.z * b);\n"
"}\n"
"\n"
"vec3 __operator / (const float a, const vec3 u) {\n"
" return vec3 (a / u.x, a / u.y, a / u.z);\n"
"}\n"
"\n"
"vec3 __operator / (const vec3 v, const float b) {\n"
" return vec3 (v.x / b, v.y / b, v.z / b);\n"
"}\n"
"\n"
"vec4 __operator + (const float a, const vec4 u) {\n"
" return vec4 (a + u.x, a + u.y, a + u.z, a + u.w);\n"
"}\n"
"\n"
"vec4 __operator + (const vec4 v, const float b) {\n"
" return vec4 (v.x + b, v.y + b, v.z + b, v.w + b);\n"
"}\n"
"\n"
"vec4 __operator - (const float a, const vec4 u) {\n"
" return vec4 (a - u.x, a - u.y, a - u.z, a - u.w);\n"
"}\n"
"\n"
"vec4 __operator - (const vec4 v, const float b) {\n"
" return vec4 (v.x - b, v.y - b, v.z - b, v.w - b);\n"
"}\n"
"\n"
"vec4 __operator * (const float a, const vec4 u) {\n"
" return vec4 (a * u.x, a * u.y, a * u.z, a * u.w);\n"
"}\n"
"\n"
"vec4 __operator * (const vec4 v, const float b) {\n"
" return vec4 (v.x * b, v.y * b, v.z * b, v.w * b);\n"
"}\n"
"\n"
"vec4 __operator / (const float a, const vec4 u) {\n"
" return vec4 (a / u.x, a / u.y, a / u.z, a / u.w);\n"
"}\n"
"\n"
"vec4 __operator / (const vec4 v, const float b) {\n"
" return vec4 (v.x / b, v.y / b, v.z / b, v.w / b);\n"
"}\n"
"\n"
"mat2 __operator + (const float a, const mat2 n) {\n"
" return mat2 (a + n[0], a + n[1]);\n"
"}\n"
"\n"
"mat2 __operator + (const mat2 m, const float b) {\n"
" return mat2 (m[0] + b, m[1] + b);\n"
"}\n"
"\n"
"mat2 __operator - (const float a, const mat2 n) {\n"
" return mat2 (a - n[0], a - n[1]);\n"
"}\n"
"\n"
"mat2 __operator - (const mat2 m, const float b) {\n"
" return mat2 (m[0] - b, m[1] - b);\n"
"}\n"
"\n"
"mat2 __operator * (const float a, const mat2 n) {\n"
" return mat2 (a * n[0], a * n[1]);\n"
"}\n"
"\n"
"mat2 __operator * (const mat2 m, const float b) {\n"
" return mat2 (m[0] * b, m[1] * b);\n"
"}\n"
"\n"
"mat2 __operator / (const float a, const mat2 n) {\n"
" return mat2 (a / n[0], a / n[1]);\n"
"}\n"
"\n"
"mat2 __operator / (const mat2 m, const float b) {\n"
" return mat2 (m[0] / b, m[1] / b);\n"
"}\n"
"\n"
"mat3 __operator + (const float a, const mat3 n) {\n"
" return mat3 (a + n[0], a + n[1], a + n[2]);\n"
"}\n"
"\n"
"mat3 __operator + (const mat3 m, const float b) {\n"
" return mat3 (m[0] + b, m[1] + b, m[2] + b);\n"
"}\n"
"\n"
"mat3 __operator - (const float a, const mat3 n) {\n"
" return mat3 (a - n[0], a - n[1], a - n[2]);\n"
"}\n"
"\n"
"mat3 __operator - (const mat3 m, const float b) {\n"
" return mat3 (m[0] - b, m[1] - b, m[2] - b);\n"
"}\n"
"\n"
"mat3 __operator * (const float a, const mat3 n) {\n"
" return mat3 (a * n[0], a * n[1], a * n[2]);\n"
"}\n"
"\n"
"mat3 __operator * (const mat3 m, const float b) {\n"
" return mat3 (m[0] * b, m[1] * b, m[2] * b);\n"
"}\n"
"\n"
"mat3 __operator / (const float a, const mat3 n) {\n"
" return mat3 (a / n[0], a / n[1], a / n[2]);\n"
"}\n"
"\n"
"mat3 __operator / (const mat3 m, const float b) {\n"
" return mat3 (m[0] / b, m[1] / b, m[2] / b);\n"
"}\n"
"\n"
"mat4 __operator + (const float a, const mat4 n) {\n"
" return mat4 (a + n[0], a + n[1], a + n[2], a + n[3]);\n"
"}\n"
"\n"
"mat4 __operator + (const mat4 m, const float b) {\n"
" return mat4 (m[0] + b, m[1] + b, m[2] + b, m[3] + b);\n"
"}\n"
"\n"
"mat4 __operator - (const float a, const mat4 n) {\n"
" return mat4 (a - n[0], a - n[1], a - n[2], a - n[3]);\n"
"}\n"
"\n"
"mat4 __operator - (const mat4 m, const float b) {\n"
" return mat4 (m[0] - b, m[1] - b, m[2] - b, m[3] - b);\n"
"}\n"
"\n"
"mat4 __operator * (const float a, const mat4 n) {\n"
" return mat4 (a * n[0], a * n[1], a * n[2], a * n[3]);\n"
"}\n"
"\n"
"mat4 __operator * (const mat4 m, const float b) {\n"
" return mat4 (m[0] * b, m[1] * b, m[2] * b, m[3] * b);\n"
"}\n"
"\n"
"mat4 __operator / (const float a, const mat4 n) {\n"
" return mat4 (a / n[0], a / n[1], a / n[2], a / n[3]);\n"
"}\n"
"\n"
"mat4 __operator / (const mat4 m, const float b) {\n"
" return mat4 (m[0] / b, m[1] / b, m[2] / b, m[3] / b);\n"
"}\n"
"\n"
"ivec2 __operator + (const int a, const ivec2 u) {\n"
" return ivec2 (a + u.x, a + u.y);\n"
"}\n"
"\n"
"ivec2 __operator + (const ivec2 v, const int b) {\n"
" return ivec2 (v.x + b, v.y + b);\n"
"}\n"
"\n"
"ivec2 __operator - (const int a, const ivec2 u) {\n"
" return ivec2 (a - u.x, a - u.y);\n"
"}\n"
"\n"
"ivec2 __operator - (const ivec2 v, const int b) {\n"
" return ivec2 (v.x - b, v.y - b);\n"
"}\n"
"\n"
"ivec2 __operator * (const int a, const ivec2 u) {\n"
" return ivec2 (a * u.x, a * u.y);\n"
"}\n"
"\n"
"ivec2 __operator * (const ivec2 v, const int b) {\n"
" return ivec2 (v.x * b, v.y * b);\n"
"}\n"
"\n"
"ivec2 __operator / (const int a, const ivec2 u) {\n"
" return ivec2 (a / u.x, a / u.y);\n"
"}\n"
"\n"
"ivec2 __operator / (const ivec2 v, const int b) {\n"
" return ivec2 (v.x / b, v.y / b);\n"
"}\n"
"\n"
"ivec3 __operator + (const int a, const ivec3 u) {\n"
" return ivec3 (a + u.x, a + u.y, a + u.z);\n"
"}\n"
"\n"
"ivec3 __operator + (const ivec3 v, const int b) {\n"
" return ivec3 (v.x + b, v.y + b, v.z + b);\n"
"}\n"
"\n"
"ivec3 __operator - (const int a, const ivec3 u) {\n"
" return ivec3 (a - u.x, a - u.y, a - u.z);\n"
"}\n"
"\n"
"ivec3 __operator - (const ivec3 v, const int b) {\n"
" return ivec3 (v.x - b, v.y - b, v.z - b);\n"
"}\n"
"\n"
"ivec3 __operator * (const int a, const ivec3 u) {\n"
" return ivec3 (a * u.x, a * u.y, a * u.z);\n"
"}\n"
"\n"
"ivec3 __operator * (const ivec3 v, const int b) {\n"
" return ivec3 (v.x * b, v.y * b, v.z * b);\n"
"}\n"
"\n"
"ivec3 __operator / (const int a, const ivec3 u) {\n"
" return ivec3 (a / u.x, a / u.y, a / u.z);\n"
"}\n"
"\n"
"ivec3 __operator / (const ivec3 v, const int b) {\n"
" return ivec3 (v.x / b, v.y / b, v.z / b);\n"
"}\n"
"\n"
"ivec4 __operator + (const int a, const ivec4 u) {\n"
" return ivec4 (a + u.x, a + u.y, a + u.z, a + u.w);\n"
"}\n"
"\n"
"ivec4 __operator + (const ivec4 v, const int b) {\n"
" return ivec4 (v.x + b, v.y + b, v.z + b, v.w + b);\n"
"}\n"
"\n"
"ivec4 __operator - (const int a, const ivec4 u) {\n"
" return ivec4 (a - u.x, a - u.y, a - u.z, a - u.w);\n"
"}\n"
"\n"
"ivec4 __operator - (const ivec4 v, const int b) {\n"
" return ivec4 (v.x - b, v.y - b, v.z - b, v.w - b);\n"
"}\n"
"\n"
"ivec4 __operator * (const int a, const ivec4 u) {\n"
" return ivec4 (a * u.x, a * u.y, a * u.z, a * u.w);\n"
"}\n"
"\n"
"ivec4 __operator * (const ivec4 v, const int b) {\n"
" return ivec4 (v.x * b, v.y * b, v.z * b, v.w * b);\n"
"}\n"
"\n"
"ivec4 __operator / (const int a, const ivec4 u) {\n"
" return ivec4 (a / u.x, a / u.y, a / u.z, a / u.w);\n"
"}\n"
"\n"
"ivec4 __operator / (const ivec4 v, const int b) {\n"
" return ivec4 (v.x / b, v.y / b, v.z / b, v.w / b);\n"
"}\n"
"\n"
"vec2 __operator * (const vec2 v, const vec2 u) {\n"
" return vec2 (v.x * u.x, v.y * u.y);\n"
"}\n"
"\n"
"vec3 __operator * (const vec3 v, const vec3 u) {\n"
" return vec3 (v.x * u.x, v.y * u.y, v.z * u.z);\n"
"}\n"
"\n"
"vec4 __operator * (const vec4 v, const vec4 u) {\n"
" return vec4 (v.x * u.x, v.y * u.y, v.z * u.z, v.w * u.w);\n"
"}\n"
"\n"
"ivec2 __operator * (const ivec2 v, const ivec2 u) {\n"
" return ivec2 (v.x * u.x, v.y * u.y);\n"
"}\n"
"\n"
"ivec3 __operator * (const ivec3 v, const ivec3 u) {\n"
" return ivec3 (v.x * u.x, v.y * u.y, v.z * u.z);\n"
"}\n"
"\n"
"ivec4 __operator * (const ivec4 v, const ivec4 u) {\n"
" return ivec4 (v.x * u.x, v.y * u.y, v.z * u.z, v.w * u.w);\n"
"}\n"
"\n"
"vec2 __operator / (const vec2 v, const vec2 u) {\n"
" return vec2 (v.x / u.x, v.y / u.y);\n"
"}\n"
"\n"
"vec3 __operator / (const vec3 v, const vec3 u) {\n"
" return vec3 (v.x / u.x, v.y / u.y, v.z / u.z);\n"
"}\n"
"\n"
"vec4 __operator / (const vec4 v, const vec4 u) {\n"
" return vec4 (v.x / u.x, v.y / u.y, v.z / u.z, v.w / u.w);\n"
"}\n"
"\n"
"ivec2 __operator / (const ivec2 v, const ivec2 u) {\n"
" return ivec2 (v.x / u.x, v.y / u.y);\n"
"}\n"
"\n"
"ivec3 __operator / (const ivec3 v, const ivec3 u) {\n"
" return ivec3 (v.x / u.x, v.y / u.y, v.z / u.z);\n"
"}\n"
"\n"
"ivec4 __operator / (const ivec4 v, const ivec4 u) {\n"
" return ivec4 (v.x / u.x, v.y / u.y, v.z / u.z, v.w / u.w);\n"
"}\n"
"\n"
"mat2 __operator / (const mat2 m, const mat2 n) {\n"
" return mat2 (m[0] / n[0], m[1] / n[1]);\n"
"}\n"
"\n"
"mat3 __operator / (const mat3 m, const mat3 n) {\n"
" return mat3 (m[0] / n[0], m[1] / n[1], m[2] / n[2]);\n"
"}\n"
"\n"
"mat4 __operator / (const mat4 m, const mat4 n) {\n"
" return mat4 (m[0] / n[0], m[1] / n[1], m[2] / n[2], m[3] / n[3]);\n"
"}\n"
"\n"
"vec2 __operator - (const vec2 v) {\n"
" return vec2 (-v.x, -v.y);\n"
"}\n"
"\n"
"vec3 __operator - (const vec3 v) {\n"
" return vec3 (-v.x, -v.y, -v.z);\n"
"}\n"
"\n"
"vec4 __operator - (const vec4 v) {\n"
" return vec4 (-v.x, -v.y, -v.z, -v.w);\n"
"}\n"
"\n"
"ivec2 __operator - (const ivec2 v) {\n"
" return ivec2 (-v.x, -v.y);\n"
"}\n"
"\n"
"ivec3 __operator - (const ivec3 v) {\n"
" return ivec3 (-v.x, -v.y, -v.z);\n"
"}\n"
"\n"
"ivec4 __operator - (const ivec4 v) {\n"
" return ivec4 (-v.x, -v.y, -v.z, -v.w);\n"
"}\n"
"\n"
"mat2 __operator - (const mat2 m) {\n"
" return mat2 (-m[0], -m[1]);\n"
"}\n"
"\n"
"mat3 __operator - (const mat3 m) {\n"
" return mat3 (-m[0], -m[1], -m[2]);\n"
"}\n"
"\n"
"mat4 __operator - (const mat4 m) {\n"
" return mat4 (-m[0], -m[1], -m[2], -m[3]);\n"
"}\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"void __operator -- (inout float a) {\n"
" a -= 1.0;\n"
"}\n"
"\n"
"void __operator -- (inout int a) {\n"
" a -= 1;\n"
"}\n"
"\n"
"void __operator -- (inout vec2 v) {\n"
" --v.x, --v.y;\n"
"}\n"
"\n"
"void __operator -- (inout vec3 v) {\n"
" --v.x, --v.y, --v.z;\n"
"}\n"
"\n"
"void __operator -- (inout vec4 v) {\n"
" --v.x, --v.y, --v.z, --v.w;\n"
"}\n"
"\n"
"void __operator -- (inout ivec2 v) {\n"
" --v.x, --v.y;\n"
"}\n"
"\n"
"void __operator -- (inout ivec3 v) {\n"
" --v.x, --v.y, --v.z;\n"
"}\n"
"\n"
"void __operator -- (inout ivec4 v) {\n"
" --v.x, --v.y, --v.z, --v.w;\n"
"}\n"
"\n"
"void __operator -- (inout mat2 m) {\n"
" --m[0], --m[1];\n"
"}\n"
"\n"
"void __operator -- (inout mat3 m) {\n"
" --m[0], --m[1], --m[2];\n"
"}\n"
"\n"
"void __operator -- (inout mat4 m) {\n"
" --m[0], --m[1], --m[2], --m[3];\n"
"}\n"
"\n"
"void __operator ++ (inout float a) {\n"
" a += 1.0;\n"
"}\n"
"\n"
"void __operator ++ (inout int a) {\n"
" a += 1;\n"
"}\n"
"\n"
"void __operator ++ (inout vec2 v) {\n"
" ++v.x, ++v.y;\n"
"}\n"
"\n"
"void __operator ++ (inout vec3 v) {\n"
" ++v.x, ++v.y, ++v.z;\n"
"}\n"
"\n"
"void __operator ++ (inout vec4 v) {\n"
" ++v.x, ++v.y, ++v.z, ++v.w;\n"
"}\n"
"\n"
"void __operator ++ (inout ivec2 v) {\n"
" ++v.x, ++v.y;\n"
"}\n"
"\n"
"void __operator ++ (inout ivec3 v) {\n"
" ++v.x, ++v.y, ++v.z;\n"
"}\n"
"\n"
"void __operator ++ (inout ivec4 v) {\n"
" ++v.x, ++v.y, ++v.z, ++v.w;\n"
"}\n"
"\n"
"void __operator ++ (inout mat2 m) {\n"
" ++m[0], ++m[1];\n"
"}\n"
"\n"
"void __operator ++ (inout mat3 m) {\n"
" ++m[0], ++m[1], ++m[2];\n"
"}\n"
"\n"
"void __operator ++ (inout mat4 m) {\n"
" ++m[0], ++m[1], ++m[2], ++m[3];\n"
"}\n"
"\n"
"float __operator -- (inout float a, const int) {\n"
" float c;\n"
" c = a;\n"
" --a;\n"
" return c;\n"
"}\n"
"\n"
"int __operator -- (inout int a, const int) {\n"
" int c;\n"
" c = a;\n"
" --a;\n"
" return c;\n"
"}\n"
"\n"
"vec2 __operator -- (inout vec2 v, const int) {\n"
" return vec2 (v.x--, v.y--);\n"
"}\n"
"\n"
"vec3 __operator -- (inout vec3 v, const int) {\n"
" return vec3 (v.x--, v.y--, v.z--);\n"
"}\n"
"\n"
"vec4 __operator -- (inout vec4 v, const int) {\n"
" return vec4 (v.x--, v.y--, v.z--, v.w--);\n"
"}\n"
"\n"
"ivec2 __operator -- (inout ivec2 v, const int) {\n"
" return ivec2 (v.x--, v.y--);\n"
"}\n"
"\n"
"ivec3 __operator -- (inout ivec3 v, const int) {\n"
" return ivec3 (v.x--, v.y--, v.z--);\n"
"}\n"
"\n"
"ivec4 __operator -- (inout ivec4 v, const int) {\n"
" return ivec4 (v.x--, v.y--, v.z--, v.w--);\n"
"}\n"
"\n"
"mat2 __operator -- (inout mat2 m, const int) {\n"
" return mat2 (m[0]--, m[1]--);\n"
"}\n"
"\n"
"mat3 __operator -- (inout mat3 m, const int) {\n"
" return mat3 (m[0]--, m[1]--, m[2]--);\n"
"}\n"
"\n"
"mat4 __operator -- (inout mat4 m, const int) {\n"
" return mat4 (m[0]--, m[1]--, m[2]--, m[3]--);\n"
"}\n"
"\n"
"float __operator ++ (inout float a, const int) {\n"
" float c;\n"
" c = a;\n"
" ++a;\n"
" return c;\n"
"}\n"
"\n"
"int __operator ++ (inout int a, const int) {\n"
" int c;\n"
" c = a;\n"
" ++a;\n"
" return c;\n"
"}\n"
"\n"
"vec2 __operator ++ (inout vec2 v, const int) {\n"
" return vec2 (v.x++, v.y++);\n"
"}\n"
"\n"
"vec3 __operator ++ (inout vec3 v, const int) {\n"
" return vec3 (v.x++, v.y++, v.z++);\n"
"}\n"
"\n"
"vec4 __operator ++ (inout vec4 v, const int) {\n"
" return vec4 (v.x++, v.y++, v.z++, v.w++);\n"
"}\n"
"\n"
"ivec2 __operator ++ (inout ivec2 v, const int) {\n"
" return ivec2 (v.x++, v.y++);\n"
"}\n"
"\n"
"ivec3 __operator ++ (inout ivec3 v, const int) {\n"
" return ivec3 (v.x++, v.y++, v.z++);\n"
"}\n"
"\n"
"ivec4 __operator ++ (inout ivec4 v, const int) {\n"
" return ivec4 (v.x++, v.y++, v.z++, v.w++);\n"
"}\n"
"\n"
"mat2 __operator ++ (inout mat2 m, const int) {\n"
" return mat2 (m[0]++, m[1]++);\n"
"}\n"
"\n"
"mat3 __operator ++ (inout mat3 m, const int) {\n"
" return mat3 (m[0]++, m[1]++, m[2]++);\n"
"}\n"
"\n"
"mat4 __operator ++ (inout mat4 m, const int) {\n"
" return mat4 (m[0]++, m[1]++, m[2]++, m[3]++);\n"
"}\n"
"\n"
"bool __operator < (const float a, const float b) {\n"
" bool c;\n"
" __asm float_less c, a, b;\n"
" return c;\n"
"}\n"
"\n"
"bool __operator < (const int a, const int b) {\n"
" return float (a) < float (b);\n"
"}\n"
"\n"
"bool __operator > (const float a, const float b) {\n"
" return b < a;\n"
"}\n"
"\n"
"bool __operator > (const int a, const int b) {\n"
" return b < a;\n"
"}\n"
"\n"
"bool __operator >= (const float a, const float b) {\n"
" return a > b || a == b;\n"
"}\n"
"\n"
"bool __operator >= (const int a, const int b) {\n"
" return a > b || a == b;\n"
"}\n"
"\n"
"bool __operator <= (const float a, const float b) {\n"
" return a < b || a == b;\n"
"}\n"
"\n"
"bool __operator <= (const int a, const int b) {\n"
" return a < b || a == b;\n"
"}\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"bool __operator ^^ (const bool a, const bool b) {\n"
" return a != b;\n"
"}\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"bool __operator ! (const bool a) {\n"
" return a == false;\n"
"}\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"int __constructor (const float _f) {\n"
" int _i;\n"
" __asm float_to_int _i, _f;\n"
" return _i;\n"
"}\n"
"\n"
"bool __constructor (const int _i) {\n"
" return _i != 0;\n"
"}\n"
"\n"
"bool __constructor (const float _f) {\n"
" return _f != 0.0;\n"
"}\n"
"\n"
"int __constructor (const bool _b) {\n"
" return _b ? 1 : 0;\n"
"}\n"
"\n"
"float __constructor (const bool _b) {\n"
" return _b ? 1.0 : 0.0;\n"
"}\n"
"\n"
"float __constructor (const int _i) {\n"
" float _f;\n"
" __asm int_to_float _f, _i;\n"
" return _f;\n"
"}\n"
"\n"
"bool __constructor (const bool _b) {\n"
" return _b;\n"
"}\n"
"\n"
"int __constructor (const int _i) {\n"
" return _i;\n"
"}\n"
"\n"
"float __constructor (const float _f) {\n"
" return _f;\n"
"}\n"
"\n"
"vec2 __constructor (const float _f) {\n"
" return vec2 (_f, _f);\n"
"}\n"
"\n"
"vec2 __constructor (const int _i) {\n"
" return vec2 (_i, _i);\n"
"}\n"
"\n"
"vec2 __constructor (const bool _b) {\n"
" return vec2 (_b, _b);\n"
"}\n"
"\n"
"vec3 __constructor (const float _f) {\n"
" return vec3 (_f, _f, _f);\n"
"}\n"
"\n"
"vec3 __constructor (const int _i) {\n"
" return vec3 (_i, _i, _i);\n"
"}\n"
"\n"
"vec3 __constructor (const bool _b) {\n"
" return vec3 (_b, _b, _b);\n"
"}\n"
"\n"
"vec4 __constructor (const float _f) {\n"
" return vec4 (_f, _f, _f, _f);\n"
"}\n"
"\n"
"vec4 __constructor (const int _i) {\n"
" return vec4 (_i, _i, _i, _i);\n"
"}\n"
"\n"
"vec4 __constructor (const bool _b) {\n"
" return vec4 (_b, _b, _b, _b);\n"
"}\n"
"\n"
"ivec2 __constructor (const int _i) {\n"
" return ivec2 (_i, _i);\n"
"}\n"
"\n"
"ivec2 __constructor (const float _f) {\n"
" return ivec2 (_f, _f);\n"
"}\n"
"\n"
"ivec2 __constructor (const bool _b) {\n"
" return ivec2 (_b, _b);\n"
"}\n"
"\n"
"ivec3 __constructor (const int _i) {\n"
" return ivec3 (_i, _i, _i);\n"
"}\n"
"\n"
"ivec3 __constructor (const float _f) {\n"
" return ivec3 (_f, _f, _f);\n"
"}\n"
"\n"
"ivec3 __constructor (const bool _b) {\n"
" return ivec3 (_b, _b, _b);\n"
"}\n"
"\n"
"ivec4 __constructor (const int _i) {\n"
" return ivec4 (_i, _i, _i, _i);\n"
"}\n"
"\n"
"ivec4 __constructor (const float _f) {\n"
" return ivec4 (_f, _f, _f, _f);\n"
"}\n"
"\n"
"ivec4 __constructor (const bool _b) {\n"
" return ivec4 (_b, _b, _b, _b);\n"
"}\n"
"\n"
"bvec2 __constructor (const bool _b) {\n"
" return bvec2 (_b, _b);\n"
"}\n"
"\n"
"bvec2 __constructor (const float _f) {\n"
" return bvec2 (_f, _f);\n"
"}\n"
"\n"
"bvec2 __constructor (const int _i) {\n"
" return bvec2 (_i, _i);\n"
"}\n"
"\n"
"bvec3 __constructor (const bool _b) {\n"
" return bvec3 (_b, _b, _b);\n"
"}\n"
"\n"
"bvec3 __constructor (const float _f) {\n"
" return bvec3 (_f, _f, _f);\n"
"}\n"
"\n"
"bvec3 __constructor (const int _i) {\n"
" return bvec3 (_i, _i, _i);\n"
"}\n"
"\n"
"bvec4 __constructor (const bool _b) {\n"
" return bvec4 (_b, _b, _b, _b);\n"
"}\n"
"\n"
"bvec4 __constructor (const float _f) {\n"
" return bvec4 (_f, _f, _f, _f);\n"
"}\n"
"\n"
"bvec4 __constructor (const int _i) {\n"
" return bvec4 (_i, _i, _i, _i);\n"
"}\n"
"\n"
"mat2 __constructor (const float _f) {\n"
" return mat2 (\n"
" _f, .0,\n"
" .0, _f\n"
" );\n"
"}\n"
"\n"
"mat2 __constructor (const int _i) {\n"
" return mat2 (\n"
" _i, .0,\n"
" .0, _i\n"
" );\n"
"}\n"
"\n"
"mat2 __constructor (const bool _b) {\n"
" return mat2 (\n"
" _b, .0,\n"
" .0, _b\n"
" );\n"
"}\n"
"\n"
"mat3 __constructor (const float _f) {\n"
" return mat3 (\n"
" _f, .0, .0,\n"
" .0, _f, .0,\n"
" .0, .0, _f\n"
" );\n"
"}\n"
"\n"
"mat3 __constructor (const int _i) {\n"
" return mat3 (\n"
" _i, .0, .0,\n"
" .0, _i, .0,\n"
" .0, .0, _i\n"
" );\n"
"}\n"
"\n"
"mat3 __constructor (const bool _b) {\n"
" return mat3 (\n"
" _b, .0, .0,\n"
" .0, _b, .0,\n"
" .0, .0, _b\n"
" );\n"
"}\n"
"\n"
"mat4 __constructor (const float _f) {\n"
" return mat4 (\n"
" _f, .0, .0, .0,\n"
" .0, _f, .0, .0,\n"
" .0, .0, _f, .0,\n"
" .0, .0, .0, _f\n"
" );\n"
"}\n"
"\n"
"mat4 __constructor (const int _i) {\n"
" return mat4 (\n"
" _i, .0, .0, .0,\n"
" .0, _i, .0, .0,\n"
" .0, .0, _i, .0,\n"
" .0, .0, .0, _i\n"
" );\n"
"}\n"
"\n"
"mat4 __constructor (const bool _b) {\n"
" return mat4 (\n"
" _b, .0, .0, .0,\n"
" .0, _b, .0, .0,\n"
" .0, .0, _b, .0,\n"
" .0, .0, .0, _b\n"
" );\n"
"}\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"void __operator += (inout float a, const float b) {\n"
" __asm float_add a, a, b;\n"
"}\n"
"\n"
"float __operator - (const float a) {\n"
" float c;\n"
" __asm float_negate c, a;\n"
" return c;\n"
"}\n"
"\n"
"void __operator -= (inout float a, const float b) {\n"
" a += -b;\n"
"}\n"
"\n"
"void __operator *= (inout float a, const float b) {\n"
" __asm float_multiply a, a, b;\n"
"}\n"
"\n"
"void __operator /= (inout float a, const float b) {\n"
" __asm float_divide a, a, b;\n"
"}\n"
"\n"
"float __operator + (const float a, const float b) {\n"
" float c;\n"
" c = a;\n"
" return c += b;\n"
"}\n"
"\n"
"void __operator += (inout int a, const int b) {\n"
" a = int (float (a) + float (b));\n"
"}\n"
"\n"
"int __operator - (const int a) {\n"
" return int (-float (a));\n"
"}\n"
"\n"
"void __operator -= (inout int a, const int b) {\n"
" a += -b;\n"
"}\n"
"\n"
"float __operator * (const float a, const float b) {\n"
" float c;\n"
" c = a;\n"
" return c *= b;\n"
"}\n"
"\n"
"void __operator *= (inout int a, const int b) {\n"
" a = int (float (a) * float (b));\n"
"}\n"
"\n"
"float __operator / (const float a, const float b) {\n"
" float c;\n"
" c = a;\n"
" return c /= b;\n"
"}\n"
"\n"
"void __operator /= (inout int a, const int b) {\n"
" a = int (float (a) / float (b));\n"
"}\n"
"\n"
"void __operator += (inout vec2 v, const vec2 u) {\n"
" v.x += u.x, v.y += u.y;\n"
"}\n"
"\n"
"void __operator -= (inout vec2 v, const vec2 u) {\n"
" v.x -= u.x, v.y -= u.y;\n"
"}\n"
"\n"
"void __operator *= (inout vec2 v, const vec2 u) {\n"
" v.x *= u.x, v.y *= u.y;\n"
"}\n"
"\n"
"void __operator /= (inout vec2 v, const vec2 u) {\n"
" v.x /= u.x, v.y /= u.y;\n"
"}\n"
"\n"
"void __operator += (inout vec3 v, const vec3 u) {\n"
" v.x += u.x, v.y += u.y, v.z += u.z;\n"
"}\n"
"\n"
"void __operator -= (inout vec3 v, const vec3 u) {\n"
" v.x -= u.x, v.y -= u.y, v.z -= u.z;\n"
"}\n"
"\n"
"void __operator *= (inout vec3 v, const vec3 u) {\n"
" v.x *= u.x, v.y *= u.y, v.z *= u.z;\n"
"}\n"
"\n"
"void __operator /= (inout vec3 v, const vec3 u) {\n"
" v.x /= u.x, v.y /= u.y, v.z /= u.z;\n"
"}\n"
"\n"
"void __operator += (inout vec4 v, const vec4 u) {\n"
" v.x += u.x, v.y += u.y, v.z += u.z, v.w += u.w;\n"
"}\n"
"\n"
"void __operator -= (inout vec4 v, const vec4 u) {\n"
" v.x -= u.x, v.y -= u.y, v.z -= u.z, v.w -= u.w;\n"
"}\n"
"\n"
"void __operator *= (inout vec4 v, const vec4 u) {\n"
" v.x *= u.x, v.y *= u.y, v.z *= u.z, v.w *= u.w;\n"
"}\n"
"\n"
"void __operator /= (inout vec4 v, const vec4 u) {\n"
" v.x /= u.x, v.y /= u.y, v.z /= u.z, v.w /= u.w;\n"
"}\n"
"\n"
"void __operator += (inout ivec2 v, const ivec2 u) {\n"
" v.x += u.x, v.y += u.y;\n"
"}\n"
"\n"
"void __operator -= (inout ivec2 v, const ivec2 u) {\n"
" v.x -= u.x, v.y -= u.y;\n"
"}\n"
"\n"
"void __operator *= (inout ivec2 v, const ivec2 u) {\n"
" v.x *= u.x, v.y *= u.y;\n"
"}\n"
"\n"
"void __operator /= (inout ivec2 v, const ivec2 u) {\n"
" v.x /= u.x, v.y /= u.y;\n"
"}\n"
"\n"
"void __operator += (inout ivec3 v, const ivec3 u) {\n"
" v.x += u.x, v.y += u.y, v.z += u.z;\n"
"}\n"
"\n"
"void __operator -= (inout ivec3 v, const ivec3 u) {\n"
" v.x -= u.x, v.y -= u.y, v.z -= u.z;\n"
"}\n"
"\n"
"void __operator *= (inout ivec3 v, const ivec3 u) {\n"
" v.x *= u.x, v.y *= u.y, v.z *= u.z;\n"
"}\n"
"\n"
"void __operator /= (inout ivec3 v, const ivec3 u) {\n"
" v.x /= u.x, v.y /= u.y, v.z /= u.z;\n"
"}\n"
"\n"
"void __operator += (inout ivec4 v, const ivec4 u) {\n"
" v.x += u.x, v.y += u.y, v.z += u.z, v.w += u.w;\n"
"}\n"
"\n"
"void __operator -= (inout ivec4 v, const ivec4 u) {\n"
" v.x -= u.x, v.y -= u.y, v.z -= u.z, v.w -= u.w;\n"
"}\n"
"\n"
"void __operator *= (inout ivec4 v, const ivec4 u) {\n"
" v.x *= u.x, v.y *= u.y, v.z *= u.z, v.w *= u.w;\n"
"}\n"
"\n"
"void __operator /= (inout ivec4 v, const ivec4 u) {\n"
" v.x /= u.x, v.y /= u.y, v.z /= u.z, v.w /= u.w;\n"
"}\n"
"\n"
"void __operator += (inout mat2 m, const mat2 n) {\n"
" m[0] += n[0], m[1] += n[1];\n"
"}\n"
"\n"
"void __operator -= (inout mat2 m, const mat2 n) {\n"
" m[0] -= n[0], m[1] -= n[1];\n"
"}\n"
"\n"
"vec2 __operator * (const mat2 m, const vec2 v) {\n"
" return vec2 (\n"
" v.x * m[0].x + v.y * m[1].x,\n"
" v.x * m[0].y + v.y * m[1].y\n"
" );\n"
"}\n"
"\n"
"mat2 __operator * (const mat2 m, const mat2 n) {\n"
" return mat2 (m * n[0], m * n[1]);\n"
"}\n"
"\n"
"void __operator *= (inout mat2 m, const mat2 n) {\n"
" m = m * n;\n"
"}\n"
"\n"
"void __operator /= (inout mat2 m, const mat2 n) {\n"
" m[0] /= n[0], m[1] /= n[1];\n"
"}\n"
"\n"
"void __operator += (inout mat3 m, const mat3 n) {\n"
" m[0] += n[0], m[1] += n[1], m[2] += n[2];\n"
"}\n"
"\n"
"void __operator -= (inout mat3 m, const mat3 n) {\n"
" m[0] -= n[0], m[1] -= n[1], m[2] -= n[2];\n"
"}\n"
"\n"
"vec3 __operator * (const mat3 m, const vec3 v) {\n"
" return vec3 (\n"
" v.x * m[0].x + v.y * m[1].x + v.z * m[2].x,\n"
" v.x * m[0].y + v.y * m[1].y + v.z * m[2].y,\n"
" v.x * m[0].z + v.y * m[1].z + v.z * m[2].z\n"
" );\n"
"}\n"
"\n"
"mat3 __operator * (const mat3 m, const mat3 n) {\n"
" return mat3 (m * n[0], m * n[1], m * n[2]);\n"
"}\n"
"\n"
"void __operator *= (inout mat3 m, const mat3 n) {\n"
" m = m * n;\n"
"}\n"
"\n"
"void __operator /= (inout mat3 m, const mat3 n) {\n"
" m[0] /= n[0], m[1] /= n[1], m[2] /= n[2];\n"
"}\n"
"\n"
"void __operator += (inout mat4 m, const mat4 n) {\n"
" m[0] += n[0], m[1] += n[1], m[2] += n[2], m[3] += n[3];\n"
"}\n"
"\n"
"void __operator -= (inout mat4 m, const mat4 n) {\n"
" m[0] -= n[0], m[1] -= n[1], m[2] -= n[2], m[3] -= n[3];\n"
"}\n"
"\n"
"vec4 __operator * (const mat4 m, const vec4 v) {\n"
" return vec4 (\n"
" v.x * m[0].x + v.y * m[1].x + v.z * m[2].x + v.w * m[3].x,\n"
" v.x * m[0].y + v.y * m[1].y + v.z * m[2].y + v.w * m[3].y,\n"
" v.x * m[0].z + v.y * m[1].z + v.z * m[2].z + v.w * m[3].z,\n"
" v.x * m[0].w + v.y * m[1].w + v.z * m[2].w + v.w * m[3].w\n"
" );\n"
"}\n"
"\n"
"mat4 __operator * (const mat4 m, const mat4 n) {\n"
" return mat4 (m * n[0], m * n[1], m * n[2], m * n[3]);\n"
"}\n"
"\n"
"void __operator *= (inout mat4 m, const mat4 n) {\n"
" m = m * n;\n"
"}\n"
"\n"
"void __operator /= (inout mat4 m, const mat4 n) {\n"
" m[0] /= n[0], m[1] /= n[1], m[2] /= n[2], m[3] /= n[3];\n"
"}\n"
"\n"
"void __operator += (inout vec2 v, const float a) {\n"
" v.x += a, v.y += a;\n"
"}\n"
"\n"
"void __operator -= (inout vec2 v, const float a) {\n"
" v.x -= a, v.y -= a;\n"
"}\n"
"\n"
"void __operator *= (inout vec2 v, const float a) {\n"
" v.x *= a, v.y *= a;\n"
"}\n"
"\n"
"void __operator /= (inout vec2 v, const float a) {\n"
" v.x /= a, v.y /= a;\n"
"}\n"
"\n"
"void __operator += (inout vec3 v, const float a) {\n"
" v.x += a, v.y += a, v.z += a;\n"
"}\n"
"\n"
"void __operator -= (inout vec3 v, const float a) {\n"
" v.x -= a, v.y -= a, v.z -= a;\n"
"}\n"
"\n"
"void __operator *= (inout vec3 v, const float a) {\n"
" v.x *= a, v.y *= a, v.z *= a;\n"
"}\n"
"\n"
"void __operator /= (inout vec3 v, const float a) {\n"
" v.x /= a, v.y /= a, v.z /= a;\n"
"}\n"
"\n"
"void __operator += (inout vec4 v, const float a) {\n"
" v.x += a, v.y += a, v.z += a, v.w += a;\n"
"}\n"
"\n"
"void __operator -= (inout vec4 v, const float a) {\n"
" v.x -= a, v.y -= a, v.z -= a, v.w -= a;\n"
"}\n"
"\n"
"void __operator *= (inout vec4 v, const float a) {\n"
" v.x *= a, v.y *= a, v.z *= a, v.w *= a;\n"
"}\n"
"\n"
"void __operator /= (inout vec4 v, const float a) {\n"
" v.x /= a, v.y /= a, v.z /= a, v.w /= a;\n"
"}\n"
"\n"
"void __operator += (inout mat2 m, const float a) {\n"
" m[0] += a, m[1] += a;\n"
"}\n"
"\n"
"void __operator -= (inout mat2 m, const float a) {\n"
" m[0] -= a, m[1] -= a;\n"
"}\n"
"\n"
"void __operator *= (inout mat2 m, const float a) {\n"
" m[0] *= a, m[1] *= a;\n"
"}\n"
"\n"
"void __operator /= (inout mat2 m, const float a) {\n"
" m[0] /= a, m[1] /= a;\n"
"}\n"
"\n"
"void __operator += (inout mat3 m, const float a) {\n"
" m[0] += a, m[1] += a, m[2] += a;\n"
"}\n"
"\n"
"void __operator -= (inout mat3 m, const float a) {\n"
" m[0] -= a, m[1] -= a, m[2] -= a;\n"
"}\n"
"\n"
"void __operator *= (inout mat3 m, const float a) {\n"
" m[0] *= a, m[1] *= a, m[2] *= a;\n"
"}\n"
"\n"
"void __operator /= (inout mat3 m, const float a) {\n"
" m[0] /= a, m[1] /= a, m[2] /= a;\n"
"}\n"
"\n"
"void __operator += (inout mat4 m, const float a) {\n"
" m[0] += a, m[1] += a, m[2] += a, m[3] += a;\n"
"}\n"
"\n"
"void __operator -= (inout mat4 m, const float a) {\n"
" m[0] -= a, m[1] -= a, m[2] -= a, m[3] -= a;\n"
"}\n"
"\n"
"void __operator *= (inout mat4 m, const float a) {\n"
" m[0] *= a, m[1] *= a, m[2] *= a, m[3] *= a;\n"
"}\n"
"\n"
"void __operator /= (inout mat4 m, const float a) {\n"
" m[0] /= a, m[1] /= a, m[2] /= a, m[3] /= a;\n"
"}\n"
"\n"
"vec2 __operator * (const vec2 v, const mat2 m) {\n"
" return vec2 (\n"
" v.x * m[0].x + v.y * m[0].y,\n"
" v.x * m[1].x + v.y * m[1].y\n"
" );\n"
"}\n"
"\n"
"void __operator *= (inout vec2 v, const mat2 m) {\n"
" v = v * m;\n"
"}\n"
"\n"
"vec3 __operator * (const vec3 v, const mat3 m) {\n"
" return vec3 (\n"
" v.x * m[0].x + v.y * m[0].y + v.z * m[0].z,\n"
" v.x * m[1].x + v.y * m[1].y + v.z * m[1].z,\n"
" v.x * m[2].x + v.y * m[2].y + v.z * m[2].z\n"
" );\n"
"}\n"
"\n"
"void __operator *= (inout vec3 v, const mat3 m) {\n"
" v = v * m;\n"
"}\n"
"\n"
"vec4 __operator * (const vec4 v, const mat4 m) {\n"
" return vec4 (\n"
" v.x * m[0].x + v.y * m[0].y + v.z * m[0].z + v.w * m[0].w,\n"
" v.x * m[1].x + v.y * m[1].y + v.z * m[1].z + v.w * m[1].w,\n"
" v.x * m[2].x + v.y * m[2].y + v.z * m[2].z + v.w * m[2].w,\n"
" v.x * m[3].x + v.y * m[3].y + v.z * m[3].z + v.w * m[3].w\n"
" );\n"
"}\n"
"\n"
"void __operator *= (inout vec4 v, const mat4 m) {\n"
" v = v * m;\n"
"}\n"
"\n"
"float __operator - (const float a, const float b) {\n"
" return a + -b;\n"
"}\n"
"\n"
"int __operator + (const int a, const int b) {\n"
" int c;\n"
" c = a;\n"
" return c += b;\n"
"}\n"
"\n"
"int __operator - (const int a, const int b) {\n"
" return a + -b;\n"
"}\n"
"\n"
"int __operator * (const int a, const int b) {\n"
" int c;\n"
" return (c = a) *= b;\n"
"}\n"
"\n"
"int __operator / (const int a, const int b) {\n"
" int c;\n"
" return (c = a) /= b;\n"
"}\n"
"\n"
"vec2 __operator + (const vec2 v, const vec2 u) {\n"
" return vec2 (v.x + u.x, v.y + u.y);\n"
"}\n"
"\n"
"vec2 __operator - (const vec2 v, const vec2 u) {\n"
" return vec2 (v.x - u.x, v.y - u.y);\n"
"}\n"
"\n"
"vec3 __operator + (const vec3 v, const vec3 u) {\n"
" return vec3 (v.x + u.x, v.y + u.y, v.z + u.z);\n"
"}\n"
"\n"
"vec3 __operator - (const vec3 v, const vec3 u) {\n"
" return vec3 (v.x - u.x, v.y - u.y, v.z - u.z);\n"
"}\n"
"\n"
"vec4 __operator + (const vec4 v, const vec4 u) {\n"
" return vec4 (v.x + u.x, v.y + u.y, v.z + u.z, v.w + u.w);\n"
"}\n"
"\n"
"vec4 __operator - (const vec4 v, const vec4 u) {\n"
" return vec4 (v.x - u.x, v.y - u.y, v.z - u.z, v.w - u.w);\n"
"}\n"
"\n"
"ivec2 __operator + (const ivec2 v, const ivec2 u) {\n"
" return ivec2 (v.x + u.x, v.y + u.y);\n"
"}\n"
"\n"
"ivec2 __operator - (const ivec2 v, const ivec2 u) {\n"
" return ivec2 (v.x - u.x, v.y - u.y);\n"
"}\n"
"\n"
"ivec3 __operator + (const ivec3 v, const ivec3 u) {\n"
" return ivec3 (v.x + u.x, v.y + u.y, v.z + u.z);\n"
"}\n"
"\n"
"ivec3 __operator - (const ivec3 v, const ivec3 u) {\n"
" return ivec3 (v.x - u.x, v.y - u.y, v.z - u.z);\n"
"}\n"
"\n"
"ivec4 __operator + (const ivec4 v, const ivec4 u) {\n"
" return ivec4 (v.x + u.x, v.y + u.y, v.z + u.z, v.w + u.w);\n"
"}\n"
"\n"
"ivec4 __operator - (const ivec4 v, const ivec4 u) {\n"
" return ivec4 (v.x - u.x, v.y - u.y, v.z - u.z, v.w - u.w);\n"
"}\n"
"\n"
"mat2 __operator + (const mat2 m, const mat2 n) {\n"
" return mat2 (m[0] + n[0], m[1] + n[1]);\n"
"}\n"
"\n"
"mat2 __operator - (const mat2 m, const mat2 n) {\n"
" return mat2 (m[0] - n[0], m[1] - n[1]);\n"
"}\n"
"\n"
"mat3 __operator + (const mat3 m, const mat3 n) {\n"
" return mat3 (m[0] + n[0], m[1] + n[1], m[2] + n[2]);\n"
"}\n"
"\n"
"mat3 __operator - (const mat3 m, const mat3 n) {\n"
" return mat3 (m[0] - n[0], m[1] - n[1], m[2] - n[2]);\n"
"}\n"
"\n"
"mat4 __operator + (const mat4 m, const mat4 n) {\n"
" return mat4 (m[0] + n[0], m[1] + n[1], m[2] + n[2], m[3] + n[3]);\n"
"}\n"
"\n"
"mat4 __operator - (const mat4 m, const mat4 n) {\n"
" return mat4 (m[0] - n[0], m[1] - n[1], m[2] - n[2], m[3] - n[3]);\n"
"}\n"
"\n"
"vec2 __operator + (const float a, const vec2 u) {\n"
" return vec2 (a + u.x, a + u.y);\n"
"}\n"
"\n"
"vec2 __operator + (const vec2 v, const float b) {\n"
" return vec2 (v.x + b, v.y + b);\n"
"}\n"
"\n"
"vec2 __operator - (const float a, const vec2 u) {\n"
" return vec2 (a - u.x, a - u.y);\n"
"}\n"
"\n"
"vec2 __operator - (const vec2 v, const float b) {\n"
" return vec2 (v.x - b, v.y - b);\n"
"}\n"
"\n"
"vec2 __operator * (const float a, const vec2 u) {\n"
" return vec2 (a * u.x, a * u.y);\n"
"}\n"
"\n"
"vec2 __operator * (const vec2 v, const float b) {\n"
" return vec2 (v.x * b, v.y * b);\n"
"}\n"
"\n"
"vec2 __operator / (const float a, const vec2 u) {\n"
" return vec2 (a / u.x, a / u.y);\n"
"}\n"
"\n"
"vec2 __operator / (const vec2 v, const float b) {\n"
" return vec2 (v.x / b, v.y / b);\n"
"}\n"
"\n"
"vec3 __operator + (const float a, const vec3 u) {\n"
" return vec3 (a + u.x, a + u.y, a + u.z);\n"
"}\n"
"\n"
"vec3 __operator + (const vec3 v, const float b) {\n"
" return vec3 (v.x + b, v.y + b, v.z + b);\n"
"}\n"
"\n"
"vec3 __operator - (const float a, const vec3 u) {\n"
" return vec3 (a - u.x, a - u.y, a - u.z);\n"
"}\n"
"\n"
"vec3 __operator - (const vec3 v, const float b) {\n"
" return vec3 (v.x - b, v.y - b, v.z - b);\n"
"}\n"
"\n"
"vec3 __operator * (const float a, const vec3 u) {\n"
" return vec3 (a * u.x, a * u.y, a * u.z);\n"
"}\n"
"\n"
"vec3 __operator * (const vec3 v, const float b) {\n"
" return vec3 (v.x * b, v.y * b, v.z * b);\n"
"}\n"
"\n"
"vec3 __operator / (const float a, const vec3 u) {\n"
" return vec3 (a / u.x, a / u.y, a / u.z);\n"
"}\n"
"\n"
"vec3 __operator / (const vec3 v, const float b) {\n"
" return vec3 (v.x / b, v.y / b, v.z / b);\n"
"}\n"
"\n"
"vec4 __operator + (const float a, const vec4 u) {\n"
" return vec4 (a + u.x, a + u.y, a + u.z, a + u.w);\n"
"}\n"
"\n"
"vec4 __operator + (const vec4 v, const float b) {\n"
" return vec4 (v.x + b, v.y + b, v.z + b, v.w + b);\n"
"}\n"
"\n"
"vec4 __operator - (const float a, const vec4 u) {\n"
" return vec4 (a - u.x, a - u.y, a - u.z, a - u.w);\n"
"}\n"
"\n"
"vec4 __operator - (const vec4 v, const float b) {\n"
" return vec4 (v.x - b, v.y - b, v.z - b, v.w - b);\n"
"}\n"
"\n"
"vec4 __operator * (const float a, const vec4 u) {\n"
" return vec4 (a * u.x, a * u.y, a * u.z, a * u.w);\n"
"}\n"
"\n"
"vec4 __operator * (const vec4 v, const float b) {\n"
" return vec4 (v.x * b, v.y * b, v.z * b, v.w * b);\n"
"}\n"
"\n"
"vec4 __operator / (const float a, const vec4 u) {\n"
" return vec4 (a / u.x, a / u.y, a / u.z, a / u.w);\n"
"}\n"
"\n"
"vec4 __operator / (const vec4 v, const float b) {\n"
" return vec4 (v.x / b, v.y / b, v.z / b, v.w / b);\n"
"}\n"
"\n"
"mat2 __operator + (const float a, const mat2 n) {\n"
" return mat2 (a + n[0], a + n[1]);\n"
"}\n"
"\n"
"mat2 __operator + (const mat2 m, const float b) {\n"
" return mat2 (m[0] + b, m[1] + b);\n"
"}\n"
"\n"
"mat2 __operator - (const float a, const mat2 n) {\n"
" return mat2 (a - n[0], a - n[1]);\n"
"}\n"
"\n"
"mat2 __operator - (const mat2 m, const float b) {\n"
" return mat2 (m[0] - b, m[1] - b);\n"
"}\n"
"\n"
"mat2 __operator * (const float a, const mat2 n) {\n"
" return mat2 (a * n[0], a * n[1]);\n"
"}\n"
"\n"
"mat2 __operator * (const mat2 m, const float b) {\n"
" return mat2 (m[0] * b, m[1] * b);\n"
"}\n"
"\n"
"mat2 __operator / (const float a, const mat2 n) {\n"
" return mat2 (a / n[0], a / n[1]);\n"
"}\n"
"\n"
"mat2 __operator / (const mat2 m, const float b) {\n"
" return mat2 (m[0] / b, m[1] / b);\n"
"}\n"
"\n"
"mat3 __operator + (const float a, const mat3 n) {\n"
" return mat3 (a + n[0], a + n[1], a + n[2]);\n"
"}\n"
"\n"
"mat3 __operator + (const mat3 m, const float b) {\n"
" return mat3 (m[0] + b, m[1] + b, m[2] + b);\n"
"}\n"
"\n"
"mat3 __operator - (const float a, const mat3 n) {\n"
" return mat3 (a - n[0], a - n[1], a - n[2]);\n"
"}\n"
"\n"
"mat3 __operator - (const mat3 m, const float b) {\n"
" return mat3 (m[0] - b, m[1] - b, m[2] - b);\n"
"}\n"
"\n"
"mat3 __operator * (const float a, const mat3 n) {\n"
" return mat3 (a * n[0], a * n[1], a * n[2]);\n"
"}\n"
"\n"
"mat3 __operator * (const mat3 m, const float b) {\n"
" return mat3 (m[0] * b, m[1] * b, m[2] * b);\n"
"}\n"
"\n"
"mat3 __operator / (const float a, const mat3 n) {\n"
" return mat3 (a / n[0], a / n[1], a / n[2]);\n"
"}\n"
"\n"
"mat3 __operator / (const mat3 m, const float b) {\n"
" return mat3 (m[0] / b, m[1] / b, m[2] / b);\n"
"}\n"
"\n"
"mat4 __operator + (const float a, const mat4 n) {\n"
" return mat4 (a + n[0], a + n[1], a + n[2], a + n[3]);\n"
"}\n"
"\n"
"mat4 __operator + (const mat4 m, const float b) {\n"
" return mat4 (m[0] + b, m[1] + b, m[2] + b, m[3] + b);\n"
"}\n"
"\n"
"mat4 __operator - (const float a, const mat4 n) {\n"
" return mat4 (a - n[0], a - n[1], a - n[2], a - n[3]);\n"
"}\n"
"\n"
"mat4 __operator - (const mat4 m, const float b) {\n"
" return mat4 (m[0] - b, m[1] - b, m[2] - b, m[3] - b);\n"
"}\n"
"\n"
"mat4 __operator * (const float a, const mat4 n) {\n"
" return mat4 (a * n[0], a * n[1], a * n[2], a * n[3]);\n"
"}\n"
"\n"
"mat4 __operator * (const mat4 m, const float b) {\n"
" return mat4 (m[0] * b, m[1] * b, m[2] * b, m[3] * b);\n"
"}\n"
"\n"
"mat4 __operator / (const float a, const mat4 n) {\n"
" return mat4 (a / n[0], a / n[1], a / n[2], a / n[3]);\n"
"}\n"
"\n"
"mat4 __operator / (const mat4 m, const float b) {\n"
" return mat4 (m[0] / b, m[1] / b, m[2] / b, m[3] / b);\n"
"}\n"
"\n"
"ivec2 __operator + (const int a, const ivec2 u) {\n"
" return ivec2 (a + u.x, a + u.y);\n"
"}\n"
"\n"
"ivec2 __operator + (const ivec2 v, const int b) {\n"
" return ivec2 (v.x + b, v.y + b);\n"
"}\n"
"\n"
"ivec2 __operator - (const int a, const ivec2 u) {\n"
" return ivec2 (a - u.x, a - u.y);\n"
"}\n"
"\n"
"ivec2 __operator - (const ivec2 v, const int b) {\n"
" return ivec2 (v.x - b, v.y - b);\n"
"}\n"
"\n"
"ivec2 __operator * (const int a, const ivec2 u) {\n"
" return ivec2 (a * u.x, a * u.y);\n"
"}\n"
"\n"
"ivec2 __operator * (const ivec2 v, const int b) {\n"
" return ivec2 (v.x * b, v.y * b);\n"
"}\n"
"\n"
"ivec2 __operator / (const int a, const ivec2 u) {\n"
" return ivec2 (a / u.x, a / u.y);\n"
"}\n"
"\n"
"ivec2 __operator / (const ivec2 v, const int b) {\n"
" return ivec2 (v.x / b, v.y / b);\n"
"}\n"
"\n"
"ivec3 __operator + (const int a, const ivec3 u) {\n"
" return ivec3 (a + u.x, a + u.y, a + u.z);\n"
"}\n"
"\n"
"ivec3 __operator + (const ivec3 v, const int b) {\n"
" return ivec3 (v.x + b, v.y + b, v.z + b);\n"
"}\n"
"\n"
"ivec3 __operator - (const int a, const ivec3 u) {\n"
" return ivec3 (a - u.x, a - u.y, a - u.z);\n"
"}\n"
"\n"
"ivec3 __operator - (const ivec3 v, const int b) {\n"
" return ivec3 (v.x - b, v.y - b, v.z - b);\n"
"}\n"
"\n"
"ivec3 __operator * (const int a, const ivec3 u) {\n"
" return ivec3 (a * u.x, a * u.y, a * u.z);\n"
"}\n"
"\n"
"ivec3 __operator * (const ivec3 v, const int b) {\n"
" return ivec3 (v.x * b, v.y * b, v.z * b);\n"
"}\n"
"\n"
"ivec3 __operator / (const int a, const ivec3 u) {\n"
" return ivec3 (a / u.x, a / u.y, a / u.z);\n"
"}\n"
"\n"
"ivec3 __operator / (const ivec3 v, const int b) {\n"
" return ivec3 (v.x / b, v.y / b, v.z / b);\n"
"}\n"
"\n"
"ivec4 __operator + (const int a, const ivec4 u) {\n"
" return ivec4 (a + u.x, a + u.y, a + u.z, a + u.w);\n"
"}\n"
"\n"
"ivec4 __operator + (const ivec4 v, const int b) {\n"
" return ivec4 (v.x + b, v.y + b, v.z + b, v.w + b);\n"
"}\n"
"\n"
"ivec4 __operator - (const int a, const ivec4 u) {\n"
" return ivec4 (a - u.x, a - u.y, a - u.z, a - u.w);\n"
"}\n"
"\n"
"ivec4 __operator - (const ivec4 v, const int b) {\n"
" return ivec4 (v.x - b, v.y - b, v.z - b, v.w - b);\n"
"}\n"
"\n"
"ivec4 __operator * (const int a, const ivec4 u) {\n"
" return ivec4 (a * u.x, a * u.y, a * u.z, a * u.w);\n"
"}\n"
"\n"
"ivec4 __operator * (const ivec4 v, const int b) {\n"
" return ivec4 (v.x * b, v.y * b, v.z * b, v.w * b);\n"
"}\n"
"\n"
"ivec4 __operator / (const int a, const ivec4 u) {\n"
" return ivec4 (a / u.x, a / u.y, a / u.z, a / u.w);\n"
"}\n"
"\n"
"ivec4 __operator / (const ivec4 v, const int b) {\n"
" return ivec4 (v.x / b, v.y / b, v.z / b, v.w / b);\n"
"}\n"
"\n"
"vec2 __operator * (const vec2 v, const vec2 u) {\n"
" return vec2 (v.x * u.x, v.y * u.y);\n"
"}\n"
"\n"
"vec3 __operator * (const vec3 v, const vec3 u) {\n"
" return vec3 (v.x * u.x, v.y * u.y, v.z * u.z);\n"
"}\n"
"\n"
"vec4 __operator * (const vec4 v, const vec4 u) {\n"
" return vec4 (v.x * u.x, v.y * u.y, v.z * u.z, v.w * u.w);\n"
"}\n"
"\n"
"ivec2 __operator * (const ivec2 v, const ivec2 u) {\n"
" return ivec2 (v.x * u.x, v.y * u.y);\n"
"}\n"
"\n"
"ivec3 __operator * (const ivec3 v, const ivec3 u) {\n"
" return ivec3 (v.x * u.x, v.y * u.y, v.z * u.z);\n"
"}\n"
"\n"
"ivec4 __operator * (const ivec4 v, const ivec4 u) {\n"
" return ivec4 (v.x * u.x, v.y * u.y, v.z * u.z, v.w * u.w);\n"
"}\n"
"\n"
"vec2 __operator / (const vec2 v, const vec2 u) {\n"
" return vec2 (v.x / u.x, v.y / u.y);\n"
"}\n"
"\n"
"vec3 __operator / (const vec3 v, const vec3 u) {\n"
" return vec3 (v.x / u.x, v.y / u.y, v.z / u.z);\n"
"}\n"
"\n"
"vec4 __operator / (const vec4 v, const vec4 u) {\n"
" return vec4 (v.x / u.x, v.y / u.y, v.z / u.z, v.w / u.w);\n"
"}\n"
"\n"
"ivec2 __operator / (const ivec2 v, const ivec2 u) {\n"
" return ivec2 (v.x / u.x, v.y / u.y);\n"
"}\n"
"\n"
"ivec3 __operator / (const ivec3 v, const ivec3 u) {\n"
" return ivec3 (v.x / u.x, v.y / u.y, v.z / u.z);\n"
"}\n"
"\n"
"ivec4 __operator / (const ivec4 v, const ivec4 u) {\n"
" return ivec4 (v.x / u.x, v.y / u.y, v.z / u.z, v.w / u.w);\n"
"}\n"
"\n"
"mat2 __operator / (const mat2 m, const mat2 n) {\n"
" return mat2 (m[0] / n[0], m[1] / n[1]);\n"
"}\n"
"\n"
"mat3 __operator / (const mat3 m, const mat3 n) {\n"
" return mat3 (m[0] / n[0], m[1] / n[1], m[2] / n[2]);\n"
"}\n"
"\n"
"mat4 __operator / (const mat4 m, const mat4 n) {\n"
" return mat4 (m[0] / n[0], m[1] / n[1], m[2] / n[2], m[3] / n[3]);\n"
"}\n"
"\n"
"vec2 __operator - (const vec2 v) {\n"
" return vec2 (-v.x, -v.y);\n"
"}\n"
"\n"
"vec3 __operator - (const vec3 v) {\n"
" return vec3 (-v.x, -v.y, -v.z);\n"
"}\n"
"\n"
"vec4 __operator - (const vec4 v) {\n"
" return vec4 (-v.x, -v.y, -v.z, -v.w);\n"
"}\n"
"\n"
"ivec2 __operator - (const ivec2 v) {\n"
" return ivec2 (-v.x, -v.y);\n"
"}\n"
"\n"
"ivec3 __operator - (const ivec3 v) {\n"
" return ivec3 (-v.x, -v.y, -v.z);\n"
"}\n"
"\n"
"ivec4 __operator - (const ivec4 v) {\n"
" return ivec4 (-v.x, -v.y, -v.z, -v.w);\n"
"}\n"
"\n"
"mat2 __operator - (const mat2 m) {\n"
" return mat2 (-m[0], -m[1]);\n"
"}\n"
"\n"
"mat3 __operator - (const mat3 m) {\n"
" return mat3 (-m[0], -m[1], -m[2]);\n"
"}\n"
"\n"
"mat4 __operator - (const mat4 m) {\n"
" return mat4 (-m[0], -m[1], -m[2], -m[3]);\n"
"}\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"void __operator -- (inout float a) {\n"
" a -= 1.0;\n"
"}\n"
"\n"
"void __operator -- (inout int a) {\n"
" a -= 1;\n"
"}\n"
"\n"
"void __operator -- (inout vec2 v) {\n"
" --v.x, --v.y;\n"
"}\n"
"\n"
"void __operator -- (inout vec3 v) {\n"
" --v.x, --v.y, --v.z;\n"
"}\n"
"\n"
"void __operator -- (inout vec4 v) {\n"
" --v.x, --v.y, --v.z, --v.w;\n"
"}\n"
"\n"
"void __operator -- (inout ivec2 v) {\n"
" --v.x, --v.y;\n"
"}\n"
"\n"
"void __operator -- (inout ivec3 v) {\n"
" --v.x, --v.y, --v.z;\n"
"}\n"
"\n"
"void __operator -- (inout ivec4 v) {\n"
" --v.x, --v.y, --v.z, --v.w;\n"
"}\n"
"\n"
"void __operator -- (inout mat2 m) {\n"
" --m[0], --m[1];\n"
"}\n"
"\n"
"void __operator -- (inout mat3 m) {\n"
" --m[0], --m[1], --m[2];\n"
"}\n"
"\n"
"void __operator -- (inout mat4 m) {\n"
" --m[0], --m[1], --m[2], --m[3];\n"
"}\n"
"\n"
"void __operator ++ (inout float a) {\n"
" a += 1.0;\n"
"}\n"
"\n"
"void __operator ++ (inout int a) {\n"
" a += 1;\n"
"}\n"
"\n"
"void __operator ++ (inout vec2 v) {\n"
" ++v.x, ++v.y;\n"
"}\n"
"\n"
"void __operator ++ (inout vec3 v) {\n"
" ++v.x, ++v.y, ++v.z;\n"
"}\n"
"\n"
"void __operator ++ (inout vec4 v) {\n"
" ++v.x, ++v.y, ++v.z, ++v.w;\n"
"}\n"
"\n"
"void __operator ++ (inout ivec2 v) {\n"
" ++v.x, ++v.y;\n"
"}\n"
"\n"
"void __operator ++ (inout ivec3 v) {\n"
" ++v.x, ++v.y, ++v.z;\n"
"}\n"
"\n"
"void __operator ++ (inout ivec4 v) {\n"
" ++v.x, ++v.y, ++v.z, ++v.w;\n"
"}\n"
"\n"
"void __operator ++ (inout mat2 m) {\n"
" ++m[0], ++m[1];\n"
"}\n"
"\n"
"void __operator ++ (inout mat3 m) {\n"
" ++m[0], ++m[1], ++m[2];\n"
"}\n"
"\n"
"void __operator ++ (inout mat4 m) {\n"
" ++m[0], ++m[1], ++m[2], ++m[3];\n"
"}\n"
"\n"
"float __operator -- (inout float a, const int) {\n"
" float c;\n"
" c = a;\n"
" --a;\n"
" return c;\n"
"}\n"
"\n"
"int __operator -- (inout int a, const int) {\n"
" int c;\n"
" c = a;\n"
" --a;\n"
" return c;\n"
"}\n"
"\n"
"vec2 __operator -- (inout vec2 v, const int) {\n"
" return vec2 (v.x--, v.y--);\n"
"}\n"
"\n"
"vec3 __operator -- (inout vec3 v, const int) {\n"
" return vec3 (v.x--, v.y--, v.z--);\n"
"}\n"
"\n"
"vec4 __operator -- (inout vec4 v, const int) {\n"
" return vec4 (v.x--, v.y--, v.z--, v.w--);\n"
"}\n"
"\n"
"ivec2 __operator -- (inout ivec2 v, const int) {\n"
" return ivec2 (v.x--, v.y--);\n"
"}\n"
"\n"
"ivec3 __operator -- (inout ivec3 v, const int) {\n"
" return ivec3 (v.x--, v.y--, v.z--);\n"
"}\n"
"\n"
"ivec4 __operator -- (inout ivec4 v, const int) {\n"
" return ivec4 (v.x--, v.y--, v.z--, v.w--);\n"
"}\n"
"\n"
"mat2 __operator -- (inout mat2 m, const int) {\n"
" return mat2 (m[0]--, m[1]--);\n"
"}\n"
"\n"
"mat3 __operator -- (inout mat3 m, const int) {\n"
" return mat3 (m[0]--, m[1]--, m[2]--);\n"
"}\n"
"\n"
"mat4 __operator -- (inout mat4 m, const int) {\n"
" return mat4 (m[0]--, m[1]--, m[2]--, m[3]--);\n"
"}\n"
"\n"
"float __operator ++ (inout float a, const int) {\n"
" float c;\n"
" c = a;\n"
" ++a;\n"
" return c;\n"
"}\n"
"\n"
"int __operator ++ (inout int a, const int) {\n"
" int c;\n"
" c = a;\n"
" ++a;\n"
" return c;\n"
"}\n"
"\n"
"vec2 __operator ++ (inout vec2 v, const int) {\n"
" return vec2 (v.x++, v.y++);\n"
"}\n"
"\n"
"vec3 __operator ++ (inout vec3 v, const int) {\n"
" return vec3 (v.x++, v.y++, v.z++);\n"
"}\n"
"\n"
"vec4 __operator ++ (inout vec4 v, const int) {\n"
" return vec4 (v.x++, v.y++, v.z++, v.w++);\n"
"}\n"
"\n"
"ivec2 __operator ++ (inout ivec2 v, const int) {\n"
" return ivec2 (v.x++, v.y++);\n"
"}\n"
"\n"
"ivec3 __operator ++ (inout ivec3 v, const int) {\n"
" return ivec3 (v.x++, v.y++, v.z++);\n"
"}\n"
"\n"
"ivec4 __operator ++ (inout ivec4 v, const int) {\n"
" return ivec4 (v.x++, v.y++, v.z++, v.w++);\n"
"}\n"
"\n"
"mat2 __operator ++ (inout mat2 m, const int) {\n"
" return mat2 (m[0]++, m[1]++);\n"
"}\n"
"\n"
"mat3 __operator ++ (inout mat3 m, const int) {\n"
" return mat3 (m[0]++, m[1]++, m[2]++);\n"
"}\n"
"\n"
"mat4 __operator ++ (inout mat4 m, const int) {\n"
" return mat4 (m[0]++, m[1]++, m[2]++, m[3]++);\n"
"}\n"
"\n"
"bool __operator < (const float a, const float b) {\n"
" bool c;\n"
" __asm float_less c, a, b;\n"
" return c;\n"
"}\n"
"\n"
"bool __operator < (const int a, const int b) {\n"
" return float (a) < float (b);\n"
"}\n"
"\n"
"bool __operator > (const float a, const float b) {\n"
" return b < a;\n"
"}\n"
"\n"
"bool __operator > (const int a, const int b) {\n"
" return b < a;\n"
"}\n"
"\n"
"bool __operator >= (const float a, const float b) {\n"
" return a > b || a == b;\n"
"}\n"
"\n"
"bool __operator >= (const int a, const int b) {\n"
" return a > b || a == b;\n"
"}\n"
"\n"
"bool __operator <= (const float a, const float b) {\n"
" return a < b || a == b;\n"
"}\n"
"\n"
"bool __operator <= (const int a, const int b) {\n"
" return a < b || a == b;\n"
"}\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"bool __operator ^^ (const bool a, const bool b) {\n"
" return a != b;\n"
"}\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"bool __operator ! (const bool a) {\n"
" return a == false;\n"
"}\n"
"\n"
".syntax translation_unit;\n"
".emtcode REVISION 2\n"
".emtcode EXTERNAL_NULL 0\n"
".emtcode EXTERNAL_FUNCTION_DEFINITION 1\n"
".emtcode EXTERNAL_DECLARATION 2\n"
".emtcode DECLARATION_FUNCTION_PROTOTYPE 1\n"
".emtcode DECLARATION_INIT_DECLARATOR_LIST 2\n"
".emtcode FUNCTION_ORDINARY 0\n"
".emtcode FUNCTION_CONSTRUCTOR 1\n"
".emtcode FUNCTION_OPERATOR 2\n"
".emtcode OPERATOR_ASSIGN 1\n"
".emtcode OPERATOR_ADDASSIGN 2\n"
".emtcode OPERATOR_SUBASSIGN 3\n"
".emtcode OPERATOR_MULASSIGN 4\n"
".emtcode OPERATOR_DIVASSIGN 5\n"
".emtcode OPERATOR_LOGICALXOR 12\n"
".emtcode OPERATOR_EQUAL 16\n"
".emtcode OPERATOR_NOTEQUAL 17\n"
".emtcode OPERATOR_LESS 18\n"
".emtcode OPERATOR_GREATER 19\n"
".emtcode OPERATOR_LESSEQUAL 20\n"
".emtcode OPERATOR_GREATEREQUAL 21\n"
".emtcode OPERATOR_MULTIPLY 24\n"
".emtcode OPERATOR_DIVIDE 25\n"
".emtcode OPERATOR_INCREMENT 27\n"
".emtcode OPERATOR_DECREMENT 28\n"
".emtcode OPERATOR_PLUS 29\n"
".emtcode OPERATOR_MINUS 30\n"
".emtcode OPERATOR_NOT 32\n"
".emtcode DECLARATOR_NONE 0\n"
".emtcode DECLARATOR_NEXT 1\n"
".emtcode VARIABLE_NONE 0\n"
".emtcode VARIABLE_IDENTIFIER 1\n"
".emtcode VARIABLE_INITIALIZER 2\n"
".emtcode VARIABLE_ARRAY_EXPLICIT 3\n"
".emtcode VARIABLE_ARRAY_UNKNOWN 4\n"
".emtcode TYPE_QUALIFIER_NONE 0\n"
".emtcode TYPE_QUALIFIER_CONST 1\n"
".emtcode TYPE_QUALIFIER_ATTRIBUTE 2\n"
".emtcode TYPE_QUALIFIER_VARYING 3\n"
".emtcode TYPE_QUALIFIER_UNIFORM 4\n"
".emtcode TYPE_QUALIFIER_FIXEDOUTPUT 5\n"
".emtcode TYPE_QUALIFIER_FIXEDINPUT 6\n"
".emtcode TYPE_SPECIFIER_VOID 0\n"
".emtcode TYPE_SPECIFIER_BOOL 1\n"
".emtcode TYPE_SPECIFIER_BVEC2 2\n"
".emtcode TYPE_SPECIFIER_BVEC3 3\n"
".emtcode TYPE_SPECIFIER_BVEC4 4\n"
".emtcode TYPE_SPECIFIER_INT 5\n"
".emtcode TYPE_SPECIFIER_IVEC2 6\n"
".emtcode TYPE_SPECIFIER_IVEC3 7\n"
".emtcode TYPE_SPECIFIER_IVEC4 8\n"
".emtcode TYPE_SPECIFIER_FLOAT 9\n"
".emtcode TYPE_SPECIFIER_VEC2 10\n"
".emtcode TYPE_SPECIFIER_VEC3 11\n"
".emtcode TYPE_SPECIFIER_VEC4 12\n"
".emtcode TYPE_SPECIFIER_MAT2 13\n"
".emtcode TYPE_SPECIFIER_MAT3 14\n"
".emtcode TYPE_SPECIFIER_MAT4 15\n"
".emtcode TYPE_SPECIFIER_SAMPLER1D 16\n"
".emtcode TYPE_SPECIFIER_SAMPLER2D 17\n"
".emtcode TYPE_SPECIFIER_SAMPLER3D 18\n"
".emtcode TYPE_SPECIFIER_SAMPLERCUBE 19\n"
".emtcode TYPE_SPECIFIER_SAMPLER1DSHADOW 20\n"
".emtcode TYPE_SPECIFIER_SAMPLER2DSHADOW 21\n"
".emtcode TYPE_SPECIFIER_STRUCT 22\n"
".emtcode TYPE_SPECIFIER_TYPENAME 23\n"
".emtcode FIELD_NONE 0\n"
".emtcode FIELD_NEXT 1\n"
".emtcode FIELD_ARRAY 2\n"
".emtcode OP_END 0\n"
".emtcode OP_BLOCK_BEGIN_NO_NEW_SCOPE 1\n"
".emtcode OP_BLOCK_BEGIN_NEW_SCOPE 2\n"
".emtcode OP_DECLARE 3\n"
".emtcode OP_ASM 4\n"
".emtcode OP_BREAK 5\n"
".emtcode OP_CONTINUE 6\n"
".emtcode OP_DISCARD 7\n"
".emtcode OP_RETURN 8\n"
".emtcode OP_EXPRESSION 9\n"
".emtcode OP_IF 10\n"
".emtcode OP_WHILE 11\n"
".emtcode OP_DO 12\n"
".emtcode OP_FOR 13\n"
".emtcode OP_PUSH_VOID 14\n"
".emtcode OP_PUSH_BOOL 15\n"
".emtcode OP_PUSH_INT 16\n"
".emtcode OP_PUSH_FLOAT 17\n"
".emtcode OP_PUSH_IDENTIFIER 18\n"
".emtcode OP_SEQUENCE 19\n"
".emtcode OP_ASSIGN 20\n"
".emtcode OP_ADDASSIGN 21\n"
".emtcode OP_SUBASSIGN 22\n"
".emtcode OP_MULASSIGN 23\n"
".emtcode OP_DIVASSIGN 24\n"
".emtcode OP_SELECT 31\n"
".emtcode OP_LOGICALOR 32\n"
".emtcode OP_LOGICALXOR 33\n"
".emtcode OP_LOGICALAND 34\n"
".emtcode OP_EQUAL 38\n"
".emtcode OP_NOTEQUAL 39\n"
".emtcode OP_LESS 40\n"
".emtcode OP_GREATER 41\n"
".emtcode OP_LESSEQUAL 42\n"
".emtcode OP_GREATEREQUAL 43\n"
".emtcode OP_ADD 46\n"
".emtcode OP_SUBTRACT 47\n"
".emtcode OP_MULTIPLY 48\n"
".emtcode OP_DIVIDE 49\n"
".emtcode OP_PREINCREMENT 51\n"
".emtcode OP_PREDECREMENT 52\n"
".emtcode OP_PLUS 53\n"
".emtcode OP_MINUS 54\n"
".emtcode OP_NOT 56\n"
".emtcode OP_SUBSCRIPT 57\n"
".emtcode OP_CALL 58\n"
".emtcode OP_FIELD 59\n"
".emtcode OP_POSTINCREMENT 60\n"
".emtcode OP_POSTDECREMENT 61\n"
".emtcode PARAM_QUALIFIER_IN 0\n"
".emtcode PARAM_QUALIFIER_OUT 1\n"
".emtcode PARAM_QUALIFIER_INOUT 2\n"
".emtcode PARAMETER_NONE 0\n"
".emtcode PARAMETER_NEXT 1\n"
".emtcode PARAMETER_ARRAY_NOT_PRESENT 0\n"
".emtcode PARAMETER_ARRAY_PRESENT 1\n"
".errtext INVALID_EXTERNAL_DECLARATION \"error 2001: invalid external declaration\"\n"
".errtext INVALID_OPERATOR_OVERRIDE \"error 2002: invalid operator override\"\n"
".errtext LBRACE_EXPECTED \"error 2003: '{' expected but '$err_token$' found\"\n"
".errtext LPAREN_EXPECTED \"error 2004: '(' expected but '$err_token$' found\"\n"
".errtext RPAREN_EXPECTED \"error 2005: ')' expected but '$err_token$' found\"\n"
".regbyte parsing_builtin 0\n"
".regbyte shader_type 0\n"
"variable_identifier\n"
" identifier .emit OP_PUSH_IDENTIFIER;\n"
"primary_expression\n"
" floatconstant .or boolconstant .or intconstant .or variable_identifier .or primary_expression_1;\n"
"primary_expression_1\n"
" lparen .and expression .and rparen;\n"
"postfix_expression\n"
" postfix_expression_1 .and .loop postfix_expression_2;\n"
"postfix_expression_1\n"
" function_call .or primary_expression;\n"
"postfix_expression_2\n"
" postfix_expression_3 .or postfix_expression_4 .or\n"
" plusplus .emit OP_POSTINCREMENT .or\n"
" minusminus .emit OP_POSTDECREMENT;\n"
"postfix_expression_3\n"
" lbracket .and integer_expression .and rbracket .emit OP_SUBSCRIPT;\n"
"postfix_expression_4\n"
" dot .and field_selection .emit OP_FIELD;\n"
"integer_expression\n"
" expression;\n"
"function_call\n"
" function_call_generic .emit OP_CALL .and .true .emit OP_END;\n"
"function_call_generic\n"
" function_call_generic_1 .or function_call_generic_2;\n"
"function_call_generic_1\n"
" function_call_header_with_parameters .and rparen .error RPAREN_EXPECTED;\n"
"function_call_generic_2\n"
" function_call_header_no_parameters .and rparen .error RPAREN_EXPECTED;\n"
"function_call_header_no_parameters\n"
" function_call_header .and function_call_header_no_parameters_1;\n"
"function_call_header_no_parameters_1\n"
" \"void\" .or .true;\n"
"function_call_header_with_parameters\n"
" function_call_header .and assignment_expression .and .true .emit OP_END .and\n"
" .loop function_call_header_with_parameters_1;\n"
"function_call_header_with_parameters_1\n"
" comma .and assignment_expression .and .true .emit OP_END;\n"
"function_call_header\n"
" function_identifier .and lparen;\n"
"function_identifier\n"
" identifier;\n"
"unary_expression\n"
" postfix_expression .or unary_expression_1 .or unary_expression_2 .or unary_expression_3 .or\n"
" unary_expression_4 .or unary_expression_5;\n"
"unary_expression_1\n"
" plusplus .and unary_expression .and .true .emit OP_PREINCREMENT;\n"
"unary_expression_2\n"
" minusminus .and unary_expression .and .true .emit OP_PREDECREMENT;\n"
"unary_expression_3\n"
" plus .and unary_expression .and .true .emit OP_PLUS;\n"
"unary_expression_4\n"
" minus .and unary_expression .and .true .emit OP_MINUS;\n"
"unary_expression_5\n"
" bang .and unary_expression .and .true .emit OP_NOT;\n"
"multiplicative_expression\n"
" unary_expression .and .loop multiplicative_expression_1;\n"
"multiplicative_expression_1\n"
" multiplicative_expression_2 .or multiplicative_expression_3;\n"
"multiplicative_expression_2\n"
" star .and unary_expression .and .true .emit OP_MULTIPLY;\n"
"multiplicative_expression_3\n"
" slash .and unary_expression .and .true .emit OP_DIVIDE;\n"
"additive_expression\n"
" multiplicative_expression .and .loop additive_expression_1;\n"
"additive_expression_1\n"
" additive_expression_2 .or additive_expression_3;\n"
"additive_expression_2\n"
" plus .and multiplicative_expression .and .true .emit OP_ADD;\n"
"additive_expression_3\n"
" minus .and multiplicative_expression .and .true .emit OP_SUBTRACT;\n"
"shift_expression\n"
" additive_expression;\n"
"relational_expression\n"
" shift_expression .and .loop relational_expression_1;\n"
"relational_expression_1\n"
" relational_expression_2 .or relational_expression_3 .or relational_expression_4 .or\n"
" relational_expression_5;\n"
"relational_expression_2\n"
" lessequals .and shift_expression .and .true .emit OP_LESSEQUAL;\n"
"relational_expression_3\n"
" greaterequals .and shift_expression .and .true .emit OP_GREATEREQUAL;\n"
"relational_expression_4\n"
" less .and shift_expression .and .true .emit OP_LESS;\n"
"relational_expression_5\n"
" greater .and shift_expression .and .true .emit OP_GREATER;\n"
"equality_expression\n"
" relational_expression .and .loop equality_expression_1;\n"
"equality_expression_1\n"
" equality_expression_2 .or equality_expression_3;\n"
"equality_expression_2\n"
" equalsequals .and relational_expression .and .true .emit OP_EQUAL;\n"
"equality_expression_3\n"
" bangequals .and relational_expression .and .true .emit OP_NOTEQUAL;\n"
"and_expression\n"
" equality_expression;\n"
"exclusive_or_expression\n"
" and_expression;\n"
"inclusive_or_expression\n"
" exclusive_or_expression;\n"
"logical_and_expression\n"
" inclusive_or_expression .and .loop logical_and_expression_1;\n"
"logical_and_expression_1\n"
" ampersandampersand .and inclusive_or_expression .and .true .emit OP_LOGICALAND;\n"
"logical_xor_expression\n"
" logical_and_expression .and .loop logical_xor_expression_1;\n"
"logical_xor_expression_1\n"
" caretcaret .and logical_and_expression .and .true .emit OP_LOGICALXOR;\n"
"logical_or_expression\n"
" logical_xor_expression .and .loop logical_or_expression_1;\n"
"logical_or_expression_1\n"
" barbar .and logical_xor_expression .and .true .emit OP_LOGICALOR;\n"
"conditional_expression\n"
" logical_or_expression .and .loop conditional_expression_1;\n"
"conditional_expression_1\n"
" question .and expression .and colon .and conditional_expression .and .true .emit OP_SELECT;\n"
"assignment_expression\n"
" assignment_expression_1 .or assignment_expression_2 .or assignment_expression_3 .or\n"
" assignment_expression_4 .or assignment_expression_5 .or conditional_expression;\n"
"assignment_expression_1\n"
" unary_expression .and equals .and assignment_expression .and .true .emit OP_ASSIGN;\n"
"assignment_expression_2\n"
" unary_expression .and starequals .and assignment_expression .and .true .emit OP_MULASSIGN;\n"
"assignment_expression_3\n"
" unary_expression .and slashequals .and assignment_expression .and .true .emit OP_DIVASSIGN;\n"
"assignment_expression_4\n"
" unary_expression .and plusequals .and assignment_expression .and .true .emit OP_ADDASSIGN;\n"
"assignment_expression_5\n"
" unary_expression .and minusequals .and assignment_expression .and .true .emit OP_SUBASSIGN;\n"
"expression\n"
" assignment_expression .and .loop expression_1;\n"
"expression_1\n"
" comma .and assignment_expression .and .true .emit OP_SEQUENCE;\n"
"constant_expression\n"
" conditional_expression .and .true .emit OP_END;\n"
"declaration\n"
" declaration_1 .or declaration_2;\n"
"declaration_1\n"
" function_prototype .emit DECLARATION_FUNCTION_PROTOTYPE .and semicolon;\n"
"declaration_2\n"
" init_declarator_list .emit DECLARATION_INIT_DECLARATOR_LIST .and semicolon;\n"
"function_prototype\n"
" function_declarator .and rparen .error RPAREN_EXPECTED .emit PARAMETER_NONE;\n"
"function_declarator\n"
" function_header_with_parameters .or function_header;\n"
"function_header_with_parameters\n"
" function_header .and parameter_declaration .and .loop function_header_with_parameters_1;\n"
"function_header_with_parameters_1\n"
" comma .and parameter_declaration;\n"
"function_header\n"
" function_header_nospace .or function_header_space;\n"
"function_header_space\n"
" fully_specified_type_space .and space .and function_decl_identifier .and lparen;\n"
"function_header_nospace\n"
" fully_specified_type_nospace .and function_decl_identifier .and lparen;\n"
"function_decl_identifier\n"
" .if (parsing_builtin != 0) __operator .emit FUNCTION_OPERATOR .or\n"
" .if (parsing_builtin != 0) \"__constructor\" .emit FUNCTION_CONSTRUCTOR .or\n"
" identifier .emit FUNCTION_ORDINARY;\n"
"__operator\n"
" \"__operator\" .and overriden_operator .error INVALID_OPERATOR_OVERRIDE;\n"
"overriden_operator\n"
" plusplus .emit OPERATOR_INCREMENT .or\n"
" plusequals .emit OPERATOR_ADDASSIGN .or\n"
" plus .emit OPERATOR_PLUS .or\n"
" minusminus .emit OPERATOR_DECREMENT .or\n"
" minusequals .emit OPERATOR_SUBASSIGN .or\n"
" minus .emit OPERATOR_MINUS .or\n"
" bangequals .emit OPERATOR_NOTEQUAL .or\n"
" bang .emit OPERATOR_NOT .or\n"
" starequals .emit OPERATOR_MULASSIGN .or\n"
" star .emit OPERATOR_MULTIPLY .or\n"
" slashequals .emit OPERATOR_DIVASSIGN .or\n"
" slash .emit OPERATOR_DIVIDE .or\n"
" lessequals .emit OPERATOR_LESSEQUAL .or\n"
" \n"
" \n"
" less .emit OPERATOR_LESS .or\n"
" greaterequals .emit OPERATOR_GREATEREQUAL .or\n"
" \n"
" \n"
" greater .emit OPERATOR_GREATER .or\n"
" equalsequals .emit OPERATOR_EQUAL .or\n"
" equals .emit OPERATOR_ASSIGN .or\n"
" \n"
" \n"
" \n"
" \n"
" \n"
" \n"
" \n"
" \n"
" caretcaret .emit OPERATOR_LOGICALXOR ;\n"
"parameter_declarator\n"
" parameter_declarator_nospace .or parameter_declarator_space;\n"
"parameter_declarator_nospace\n"
" type_specifier_nospace .and identifier .and parameter_declarator_1;\n"
"parameter_declarator_space\n"
" type_specifier_space .and space .and identifier .and parameter_declarator_1;\n"
"parameter_declarator_1\n"
" parameter_declarator_2 .emit PARAMETER_ARRAY_PRESENT .or\n"
" .true .emit PARAMETER_ARRAY_NOT_PRESENT;\n"
"parameter_declarator_2\n"
" lbracket .and constant_expression .and rbracket;\n"
"parameter_declaration\n"
" parameter_declaration_1 .emit PARAMETER_NEXT;\n"
"parameter_declaration_1\n"
" parameter_declaration_2 .or parameter_declaration_3;\n"
"parameter_declaration_2\n"
" type_qualifier .and space .and parameter_qualifier .and parameter_declaration_4;\n"
"parameter_declaration_3\n"
" parameter_qualifier .emit TYPE_QUALIFIER_NONE .and parameter_declaration_4;\n"
"parameter_declaration_4\n"
" parameter_declarator .or parameter_type_specifier;\n"
"parameter_qualifier\n"
" parameter_qualifier_1 .or .true .emit PARAM_QUALIFIER_IN;\n"
"parameter_qualifier_1\n"
" parameter_qualifier_2 .and space;\n"
"parameter_qualifier_2\n"
" \"in\" .emit PARAM_QUALIFIER_IN .or\n"
" \"out\" .emit PARAM_QUALIFIER_OUT .or\n"
" \"inout\" .emit PARAM_QUALIFIER_INOUT;\n"
"parameter_type_specifier\n"
" parameter_type_specifier_1 .and .true .emit '\\0' .and parameter_type_specifier_2;\n"
"parameter_type_specifier_1\n"
" type_specifier_nospace .or type_specifier_space;\n"
"parameter_type_specifier_2\n"
" parameter_type_specifier_3 .emit PARAMETER_ARRAY_PRESENT .or\n"
" .true .emit PARAMETER_ARRAY_NOT_PRESENT;\n"
"parameter_type_specifier_3\n"
" lbracket .and constant_expression .and rbracket;\n"
"init_declarator_list\n"
" single_declaration .and .loop init_declarator_list_1 .emit DECLARATOR_NEXT .and\n"
" .true .emit DECLARATOR_NONE;\n"
"init_declarator_list_1\n"
" comma .and identifier .emit VARIABLE_IDENTIFIER .and init_declarator_list_2;\n"
"init_declarator_list_2\n"
" init_declarator_list_3 .or init_declarator_list_4 .or .true .emit VARIABLE_NONE;\n"
"init_declarator_list_3\n"
" equals .and initializer .emit VARIABLE_INITIALIZER;\n"
"init_declarator_list_4\n"
" lbracket .and init_declarator_list_5 .and rbracket;\n"
"init_declarator_list_5\n"
" constant_expression .emit VARIABLE_ARRAY_EXPLICIT .or .true .emit VARIABLE_ARRAY_UNKNOWN;\n"
"single_declaration\n"
" single_declaration_nospace .or single_declaration_space;\n"
"single_declaration_space\n"
" fully_specified_type_space .and single_declaration_space_1;\n"
"single_declaration_nospace\n"
" fully_specified_type_nospace .and single_declaration_nospace_1;\n"
"single_declaration_space_1\n"
" single_declaration_space_2 .emit VARIABLE_IDENTIFIER .or .true .emit VARIABLE_NONE;\n"
"single_declaration_nospace_1\n"
" single_declaration_nospace_2 .emit VARIABLE_IDENTIFIER .or .true .emit VARIABLE_NONE;\n"
"single_declaration_space_2\n"
" space .and identifier .and single_declaration_3;\n"
"single_declaration_nospace_2\n"
" identifier .and single_declaration_3;\n"
"single_declaration_3\n"
" single_declaration_4 .or single_declaration_5 .or .true .emit VARIABLE_NONE;\n"
"single_declaration_4\n"
" equals .and initializer .emit VARIABLE_INITIALIZER;\n"
"single_declaration_5\n"
" lbracket .and single_declaration_6 .and rbracket;\n"
"single_declaration_6\n"
" constant_expression .emit VARIABLE_ARRAY_EXPLICIT .or .true .emit VARIABLE_ARRAY_UNKNOWN;\n"
"fully_specified_type_space\n"
" fully_specified_type_1 .and type_specifier_space;\n"
"fully_specified_type_nospace\n"
" fully_specified_type_1 .and type_specifier_nospace;\n"
"fully_specified_type_1\n"
" fully_specified_type_2 .or .true .emit TYPE_QUALIFIER_NONE;\n"
"fully_specified_type_2\n"
" type_qualifier .and space;\n"
"type_qualifier\n"
" \"const\" .emit TYPE_QUALIFIER_CONST .or\n"
" .if (shader_type == 2) \"attribute\" .emit TYPE_QUALIFIER_ATTRIBUTE .or\n"
" \"varying\" .emit TYPE_QUALIFIER_VARYING .or\n"
" \"uniform\" .emit TYPE_QUALIFIER_UNIFORM .or\n"
" .if (parsing_builtin != 0) \"__fixed_output\" .emit TYPE_QUALIFIER_FIXEDOUTPUT .or\n"
" .if (parsing_builtin != 0) \"__fixed_input\" .emit TYPE_QUALIFIER_FIXEDINPUT;\n"
"type_specifier_space\n"
" \"void\" .emit TYPE_SPECIFIER_VOID .or\n"
" \"float\" .emit TYPE_SPECIFIER_FLOAT .or\n"
" \"int\" .emit TYPE_SPECIFIER_INT .or\n"
" \"bool\" .emit TYPE_SPECIFIER_BOOL .or\n"
" \"vec2\" .emit TYPE_SPECIFIER_VEC2 .or\n"
" \"vec3\" .emit TYPE_SPECIFIER_VEC3 .or\n"
" \"vec4\" .emit TYPE_SPECIFIER_VEC4 .or\n"
" \"bvec2\" .emit TYPE_SPECIFIER_BVEC2 .or\n"
" \"bvec3\" .emit TYPE_SPECIFIER_BVEC3 .or\n"
" \"bvec4\" .emit TYPE_SPECIFIER_BVEC4 .or\n"
" \"ivec2\" .emit TYPE_SPECIFIER_IVEC2 .or\n"
" \"ivec3\" .emit TYPE_SPECIFIER_IVEC3 .or\n"
" \"ivec4\" .emit TYPE_SPECIFIER_IVEC4 .or\n"
" \"mat2\" .emit TYPE_SPECIFIER_MAT2 .or\n"
" \"mat3\" .emit TYPE_SPECIFIER_MAT3 .or\n"
" \"mat4\" .emit TYPE_SPECIFIER_MAT4 .or\n"
" \"sampler1D\" .emit TYPE_SPECIFIER_SAMPLER1D .or\n"
" \"sampler2D\" .emit TYPE_SPECIFIER_SAMPLER2D .or\n"
" \"sampler3D\" .emit TYPE_SPECIFIER_SAMPLER3D .or\n"
" \"samplerCube\" .emit TYPE_SPECIFIER_SAMPLERCUBE .or\n"
" \"sampler1DShadow\" .emit TYPE_SPECIFIER_SAMPLER1DSHADOW .or\n"
" \"sampler2DShadow\" .emit TYPE_SPECIFIER_SAMPLER2DSHADOW .or\n"
" type_name .emit TYPE_SPECIFIER_TYPENAME;\n"
"type_specifier_nospace\n"
" struct_specifier .emit TYPE_SPECIFIER_STRUCT;\n"
"struct_specifier\n"
" \"struct\" .and struct_specifier_1 .and optional_space .and lbrace .error LBRACE_EXPECTED .and\n"
" struct_declaration_list .and rbrace .emit FIELD_NONE;\n"
"struct_specifier_1\n"
" struct_specifier_2 .or .true .emit '\\0';\n"
"struct_specifier_2\n"
" space .and identifier;\n"
"struct_declaration_list\n"
" struct_declaration .and .loop struct_declaration .emit FIELD_NEXT;\n"
"struct_declaration\n"
" struct_declaration_nospace .or struct_declaration_space;\n"
"struct_declaration_space\n"
" type_specifier_space .and space .and struct_declarator_list .and semicolon .emit FIELD_NONE;\n"
"struct_declaration_nospace\n"
" type_specifier_nospace .and struct_declarator_list .and semicolon .emit FIELD_NONE;\n"
"struct_declarator_list\n"
" struct_declarator .and .loop struct_declarator_list_1 .emit FIELD_NEXT;\n"
"struct_declarator_list_1\n"
" comma .and struct_declarator;\n"
"struct_declarator\n"
" identifier .and struct_declarator_1;\n"
"struct_declarator_1\n"
" struct_declarator_2 .emit FIELD_ARRAY .or .true .emit FIELD_NONE;\n"
"struct_declarator_2\n"
" lbracket .and constant_expression .and rbracket;\n"
"initializer\n"
" assignment_expression .and .true .emit OP_END;\n"
"declaration_statement\n"
" declaration;\n"
"statement\n"
" compound_statement .or simple_statement;\n"
"statement_space\n"
" compound_statement .or statement_space_1;\n"
"statement_space_1\n"
" space .and simple_statement;\n"
"simple_statement\n"
" .if (parsing_builtin != 0) __asm_statement .emit OP_ASM .or\n"
" selection_statement .or\n"
" iteration_statement .or\n"
" jump_statement .or\n"
" expression_statement .emit OP_EXPRESSION .or\n"
" declaration_statement .emit OP_DECLARE;\n"
"compound_statement\n"
" compound_statement_1 .emit OP_BLOCK_BEGIN_NEW_SCOPE .and .true .emit OP_END;\n"
"compound_statement_1\n"
" compound_statement_2 .or compound_statement_3;\n"
"compound_statement_2\n"
" lbrace .and rbrace;\n"
"compound_statement_3\n"
" lbrace .and statement_list .and rbrace;\n"
"statement_no_new_scope\n"
" compound_statement_no_new_scope .or simple_statement;\n"
"compound_statement_no_new_scope\n"
" compound_statement_no_new_scope_1 .emit OP_BLOCK_BEGIN_NO_NEW_SCOPE .and .true .emit OP_END;\n"
"compound_statement_no_new_scope_1\n"
" compound_statement_no_new_scope_2 .or compound_statement_no_new_scope_3;\n"
"compound_statement_no_new_scope_2\n"
" lbrace .and rbrace;\n"
"compound_statement_no_new_scope_3\n"
" lbrace .and statement_list .and rbrace;\n"
"statement_list\n"
" statement .and .loop statement;\n"
"expression_statement\n"
" expression_statement_1 .or expression_statement_2;\n"
"expression_statement_1\n"
" semicolon .emit OP_PUSH_VOID .emit OP_END;\n"
"expression_statement_2\n"
" expression .and semicolon .emit OP_END;\n"
"selection_statement\n"
" \"if\" .emit OP_IF .and lparen .error LPAREN_EXPECTED .and expression .and\n"
" rparen .error RPAREN_EXPECTED .emit OP_END .and selection_rest_statement;\n"
"selection_rest_statement\n"
" statement .and selection_rest_statement_1;\n"
"selection_rest_statement_1\n"
" selection_rest_statement_2 .or .true .emit OP_EXPRESSION .emit OP_PUSH_VOID .emit OP_END;\n"
"selection_rest_statement_2\n"
" \"else\" .and optional_space .and statement;\n"
"condition\n"
" condition_1 .emit OP_DECLARE .emit DECLARATION_INIT_DECLARATOR_LIST .or\n"
" condition_3 .emit OP_EXPRESSION;\n"
"condition_1\n"
" condition_1_nospace .or condition_1_space;\n"
"condition_1_nospace\n"
" fully_specified_type_nospace .and condition_2;\n"
"condition_1_space\n"
" fully_specified_type_space .and space .and condition_2;\n"
"condition_2\n"
" identifier .emit VARIABLE_IDENTIFIER .and equals .emit VARIABLE_INITIALIZER .and\n"
" initializer .and .true .emit DECLARATOR_NONE;\n"
"condition_3\n"
" expression .and .true .emit OP_END;\n"
"iteration_statement\n"
" iteration_statement_1 .or iteration_statement_2 .or iteration_statement_3;\n"
"iteration_statement_1\n"
" \"while\" .emit OP_WHILE .and lparen .error LPAREN_EXPECTED .and condition .and\n"
" rparen .error RPAREN_EXPECTED .and statement_no_new_scope;\n"
"iteration_statement_2\n"
" \"do\" .emit OP_DO .and statement_space .and \"while\" .and lparen .error LPAREN_EXPECTED .and\n"
" expression .and rparen .error RPAREN_EXPECTED .emit OP_END .and semicolon;\n"
"iteration_statement_3\n"
" \"for\" .emit OP_FOR .and lparen .error LPAREN_EXPECTED .and for_init_statement .and\n"
" for_rest_statement .and rparen .error RPAREN_EXPECTED .and statement_no_new_scope;\n"
"for_init_statement\n"
" expression_statement .emit OP_EXPRESSION .or declaration_statement .emit OP_DECLARE;\n"
"conditionopt\n"
" condition .or\n"
" .true .emit OP_EXPRESSION .emit OP_PUSH_BOOL .emit 2 .emit '1' .emit '\\0' .emit OP_END;\n"
"for_rest_statement\n"
" conditionopt .and semicolon .and for_rest_statement_1;\n"
"for_rest_statement_1\n"
" for_rest_statement_2 .or .true .emit OP_PUSH_VOID .emit OP_END;\n"
"for_rest_statement_2\n"
" expression .and .true .emit OP_END;\n"
"jump_statement\n"
" jump_statement_1 .or jump_statement_2 .or jump_statement_3 .or jump_statement_4 .or\n"
" .if (shader_type == 1) jump_statement_5;\n"
"jump_statement_1\n"
" \"continue\" .and semicolon .emit OP_CONTINUE;\n"
"jump_statement_2\n"
" \"break\" .and semicolon .emit OP_BREAK;\n"
"jump_statement_3\n"
" \"return\" .emit OP_RETURN .and optional_space .and expression .and semicolon .emit OP_END;\n"
"jump_statement_4\n"
" \"return\" .emit OP_RETURN .and semicolon .emit OP_PUSH_VOID .emit OP_END;\n"
"jump_statement_5\n"
" \"discard\" .and semicolon .emit OP_DISCARD;\n"
"__asm_statement\n"
" \"__asm\" .and space .and identifier .and space .and asm_arguments .and semicolon .emit OP_END;\n"
"asm_arguments\n"
" variable_identifier .and .true .emit OP_END .and .loop asm_arguments_1;\n"
"asm_arguments_1\n"
" comma .and variable_identifier .and .true .emit OP_END;\n"
"translation_unit\n"
" optional_space .emit REVISION .and external_declaration .error INVALID_EXTERNAL_DECLARATION .and\n"
" .loop external_declaration .and optional_space .and\n"
" '\\0' .error INVALID_EXTERNAL_DECLARATION .emit EXTERNAL_NULL;\n"
"external_declaration\n"
" function_definition .emit EXTERNAL_FUNCTION_DEFINITION .or\n"
" declaration .emit EXTERNAL_DECLARATION;\n"
"function_definition\n"
" function_prototype .and compound_statement_no_new_scope;\n"
"digit_oct\n"
" '0'-'7';\n"
"digit_dec\n"
" '0'-'9';\n"
"digit_hex\n"
" '0'-'9' .or 'A'-'F' .or 'a'-'f';\n"
"id_character_first\n"
" 'a'-'z' .or 'A'-'Z' .or '_';\n"
"id_character_next\n"
" id_character_first .or digit_dec;\n"
"identifier\n"
" id_character_first .emit * .and .loop id_character_next .emit * .and .true .emit '\\0';\n"
"float\n"
" float_1 .or float_2;\n"
"float_1\n"
" float_fractional_constant .and float_optional_exponent_part;\n"
"float_2\n"
" float_digit_sequence .and .true .emit '\\0' .and float_exponent_part;\n"
"float_fractional_constant\n"
" float_fractional_constant_1 .or float_fractional_constant_2 .or float_fractional_constant_3;\n"
"float_fractional_constant_1\n"
" float_digit_sequence .and '.' .and float_digit_sequence;\n"
"float_fractional_constant_2\n"
" float_digit_sequence .and '.' .and .true .emit '\\0';\n"
"float_fractional_constant_3\n"
" '.' .emit '\\0' .and float_digit_sequence;\n"
"float_optional_exponent_part\n"
" float_exponent_part .or .true .emit '\\0';\n"
"float_digit_sequence\n"
" digit_dec .emit * .and .loop digit_dec .emit * .and .true .emit '\\0';\n"
"float_exponent_part\n"
" float_exponent_part_1 .or float_exponent_part_2;\n"
"float_exponent_part_1\n"
" 'e' .and float_optional_sign .and float_digit_sequence;\n"
"float_exponent_part_2\n"
" 'E' .and float_optional_sign .and float_digit_sequence;\n"
"float_optional_sign\n"
" float_sign .or .true;\n"
"float_sign\n"
" '+' .or '-' .emit '-';\n"
"integer\n"
" integer_hex .or integer_oct .or integer_dec;\n"
"integer_hex\n"
" '0' .and integer_hex_1 .emit 0x10 .and digit_hex .emit * .and .loop digit_hex .emit * .and\n"
" .true .emit '\\0';\n"
"integer_hex_1\n"
" 'x' .or 'X';\n"
"integer_oct\n"
" '0' .emit 8 .emit * .and .loop digit_oct .emit * .and .true .emit '\\0';\n"
"integer_dec\n"
" digit_dec .emit 10 .emit * .and .loop digit_dec .emit * .and .true .emit '\\0';\n"
"boolean\n"
" \"true\" .emit 2 .emit '1' .emit '\\0' .or\n"
" \"false\" .emit 2 .emit '0' .emit '\\0';\n"
"type_name\n"
" identifier;\n"
"field_selection\n"
" identifier;\n"
"floatconstant\n"
" float .emit OP_PUSH_FLOAT;\n"
"intconstant\n"
" integer .emit OP_PUSH_INT;\n"
"boolconstant\n"
" boolean .emit OP_PUSH_BOOL;\n"
"optional_space\n"
" .loop single_space;\n"
"space\n"
" single_space .and .loop single_space;\n"
"single_space\n"
" white_char .or c_style_comment_block .or cpp_style_comment_block;\n"
"white_char\n"
" ' ' .or '\\t' .or new_line .or '\\v' .or '\\f';\n"
"new_line\n"
" cr_lf .or lf_cr .or '\\n' .or '\\r';\n"
"cr_lf\n"
" '\\r' .and '\\n';\n"
"lf_cr\n"
" '\\n' .and '\\r';\n"
"c_style_comment_block\n"
" '/' .and '*' .and c_style_comment_rest;\n"
"c_style_comment_rest\n"
" .loop c_style_comment_char_no_star .and c_style_comment_rest_1;\n"
"c_style_comment_rest_1\n"
" c_style_comment_end .or c_style_comment_rest_2;\n"
"c_style_comment_rest_2\n"
" '*' .and c_style_comment_rest;\n"
"c_style_comment_char_no_star\n"
" '\\x2B'-'\\xFF' .or '\\x01'-'\\x29';\n"
"c_style_comment_end\n"
" '*' .and '/';\n"
"cpp_style_comment_block\n"
" '/' .and '/' .and cpp_style_comment_block_1;\n"
"cpp_style_comment_block_1\n"
" cpp_style_comment_block_2 .or cpp_style_comment_block_3;\n"
"cpp_style_comment_block_2\n"
" .loop cpp_style_comment_char .and new_line;\n"
"cpp_style_comment_block_3\n"
" .loop cpp_style_comment_char;\n"
"cpp_style_comment_char\n"
" '\\x0E'-'\\xFF' .or '\\x01'-'\\x09' .or '\\x0B'-'\\x0C';\n"
"ampersandampersand\n"
" optional_space .and '&' .and '&' .and optional_space;\n"
"barbar\n"
" optional_space .and '|' .and '|' .and optional_space;\n"
"bang\n"
" optional_space .and '!' .and optional_space;\n"
"bangequals\n"
" optional_space .and '!' .and '=' .and optional_space;\n"
"caretcaret\n"
" optional_space .and '^' .and '^' .and optional_space;\n"
"colon\n"
" optional_space .and ':' .and optional_space;\n"
"comma\n"
" optional_space .and ',' .and optional_space;\n"
"dot\n"
" optional_space .and '.' .and optional_space;\n"
"equals\n"
" optional_space .and '=' .and optional_space;\n"
"equalsequals\n"
" optional_space .and '=' .and '=' .and optional_space;\n"
"greater\n"
" optional_space .and '>' .and optional_space;\n"
"greaterequals\n"
" optional_space .and '>' .and '=' .and optional_space;\n"
"lbrace\n"
" optional_space .and '{' .and optional_space;\n"
"lbracket\n"
" optional_space .and '[' .and optional_space;\n"
"less\n"
" optional_space .and '<' .and optional_space;\n"
"lessequals\n"
" optional_space .and '<' .and '=' .and optional_space;\n"
"lparen\n"
" optional_space .and '(' .and optional_space;\n"
"minus\n"
" optional_space .and '-' .and optional_space;\n"
"minusequals\n"
" optional_space .and '-' .and '=' .and optional_space;\n"
"minusminus\n"
" optional_space .and '-' .and '-' .and optional_space;\n"
"plus\n"
" optional_space .and '+' .and optional_space;\n"
"plusequals\n"
" optional_space .and '+' .and '=' .and optional_space;\n"
"plusplus\n"
" optional_space .and '+' .and '+' .and optional_space;\n"
"question\n"
" optional_space .and '?' .and optional_space;\n"
"rbrace\n"
" optional_space .and '}' .and optional_space;\n"
"rbracket\n"
" optional_space .and ']' .and optional_space;\n"
"rparen\n"
" optional_space .and ')' .and optional_space;\n"
"semicolon\n"
" optional_space .and ';' .and optional_space;\n"
"slash\n"
" optional_space .and '/' .and optional_space;\n"
"slashequals\n"
" optional_space .and '/' .and '=' .and optional_space;\n"
"star\n"
" optional_space .and '*' .and optional_space;\n"
"starequals\n"
" optional_space .and '*' .and '=' .and optional_space;\n"
".string string_lexer;\n"
"string_lexer\n"
" lex_first_identifier_character .and .loop lex_next_identifier_character;\n"
"lex_first_identifier_character\n"
" 'a'-'z' .or 'A'-'Z' .or '_';\n"
"lex_next_identifier_character\n"
" 'a'-'z' .or 'A'-'Z' .or '0'-'9' .or '_';\n"
"err_token\n"
" '~' .or '`' .or '!' .or '@' .or '#' .or '$' .or '%' .or '^' .or '&' .or '*' .or '(' .or ')' .or\n"
" '-' .or '+' .or '=' .or '|' .or '\\\\' .or '[' .or ']' .or '{' .or '}' .or ':' .or ';' .or '\"' .or\n"
" '\\'' .or '<' .or ',' .or '>' .or '.' .or '/' .or '?' .or err_identifier;\n"
"err_identifier\n"
" id_character_first .and .loop id_character_next;\n"
""
".syntax translation_unit;\n"
".emtcode REVISION 2\n"
".emtcode EXTERNAL_NULL 0\n"
".emtcode EXTERNAL_FUNCTION_DEFINITION 1\n"
".emtcode EXTERNAL_DECLARATION 2\n"
".emtcode DECLARATION_FUNCTION_PROTOTYPE 1\n"
".emtcode DECLARATION_INIT_DECLARATOR_LIST 2\n"
".emtcode FUNCTION_ORDINARY 0\n"
".emtcode FUNCTION_CONSTRUCTOR 1\n"
".emtcode FUNCTION_OPERATOR 2\n"
".emtcode OPERATOR_ASSIGN 1\n"
".emtcode OPERATOR_ADDASSIGN 2\n"
".emtcode OPERATOR_SUBASSIGN 3\n"
".emtcode OPERATOR_MULASSIGN 4\n"
".emtcode OPERATOR_DIVASSIGN 5\n"
".emtcode OPERATOR_LOGICALXOR 12\n"
".emtcode OPERATOR_EQUAL 16\n"
".emtcode OPERATOR_NOTEQUAL 17\n"
".emtcode OPERATOR_LESS 18\n"
".emtcode OPERATOR_GREATER 19\n"
".emtcode OPERATOR_LESSEQUAL 20\n"
".emtcode OPERATOR_GREATEREQUAL 21\n"
".emtcode OPERATOR_MULTIPLY 24\n"
".emtcode OPERATOR_DIVIDE 25\n"
".emtcode OPERATOR_INCREMENT 27\n"
".emtcode OPERATOR_DECREMENT 28\n"
".emtcode OPERATOR_PLUS 29\n"
".emtcode OPERATOR_MINUS 30\n"
".emtcode OPERATOR_NOT 32\n"
".emtcode DECLARATOR_NONE 0\n"
".emtcode DECLARATOR_NEXT 1\n"
".emtcode VARIABLE_NONE 0\n"
".emtcode VARIABLE_IDENTIFIER 1\n"
".emtcode VARIABLE_INITIALIZER 2\n"
".emtcode VARIABLE_ARRAY_EXPLICIT 3\n"
".emtcode VARIABLE_ARRAY_UNKNOWN 4\n"
".emtcode TYPE_QUALIFIER_NONE 0\n"
".emtcode TYPE_QUALIFIER_CONST 1\n"
".emtcode TYPE_QUALIFIER_ATTRIBUTE 2\n"
".emtcode TYPE_QUALIFIER_VARYING 3\n"
".emtcode TYPE_QUALIFIER_UNIFORM 4\n"
".emtcode TYPE_QUALIFIER_FIXEDOUTPUT 5\n"
".emtcode TYPE_QUALIFIER_FIXEDINPUT 6\n"
".emtcode TYPE_SPECIFIER_VOID 0\n"
".emtcode TYPE_SPECIFIER_BOOL 1\n"
".emtcode TYPE_SPECIFIER_BVEC2 2\n"
".emtcode TYPE_SPECIFIER_BVEC3 3\n"
".emtcode TYPE_SPECIFIER_BVEC4 4\n"
".emtcode TYPE_SPECIFIER_INT 5\n"
".emtcode TYPE_SPECIFIER_IVEC2 6\n"
".emtcode TYPE_SPECIFIER_IVEC3 7\n"
".emtcode TYPE_SPECIFIER_IVEC4 8\n"
".emtcode TYPE_SPECIFIER_FLOAT 9\n"
".emtcode TYPE_SPECIFIER_VEC2 10\n"
".emtcode TYPE_SPECIFIER_VEC3 11\n"
".emtcode TYPE_SPECIFIER_VEC4 12\n"
".emtcode TYPE_SPECIFIER_MAT2 13\n"
".emtcode TYPE_SPECIFIER_MAT3 14\n"
".emtcode TYPE_SPECIFIER_MAT4 15\n"
".emtcode TYPE_SPECIFIER_SAMPLER1D 16\n"
".emtcode TYPE_SPECIFIER_SAMPLER2D 17\n"
".emtcode TYPE_SPECIFIER_SAMPLER3D 18\n"
".emtcode TYPE_SPECIFIER_SAMPLERCUBE 19\n"
".emtcode TYPE_SPECIFIER_SAMPLER1DSHADOW 20\n"
".emtcode TYPE_SPECIFIER_SAMPLER2DSHADOW 21\n"
".emtcode TYPE_SPECIFIER_STRUCT 22\n"
".emtcode TYPE_SPECIFIER_TYPENAME 23\n"
".emtcode FIELD_NONE 0\n"
".emtcode FIELD_NEXT 1\n"
".emtcode FIELD_ARRAY 2\n"
".emtcode OP_END 0\n"
".emtcode OP_BLOCK_BEGIN_NO_NEW_SCOPE 1\n"
".emtcode OP_BLOCK_BEGIN_NEW_SCOPE 2\n"
".emtcode OP_DECLARE 3\n"
".emtcode OP_ASM 4\n"
".emtcode OP_BREAK 5\n"
".emtcode OP_CONTINUE 6\n"
".emtcode OP_DISCARD 7\n"
".emtcode OP_RETURN 8\n"
".emtcode OP_EXPRESSION 9\n"
".emtcode OP_IF 10\n"
".emtcode OP_WHILE 11\n"
".emtcode OP_DO 12\n"
".emtcode OP_FOR 13\n"
".emtcode OP_PUSH_VOID 14\n"
".emtcode OP_PUSH_BOOL 15\n"
".emtcode OP_PUSH_INT 16\n"
".emtcode OP_PUSH_FLOAT 17\n"
".emtcode OP_PUSH_IDENTIFIER 18\n"
".emtcode OP_SEQUENCE 19\n"
".emtcode OP_ASSIGN 20\n"
".emtcode OP_ADDASSIGN 21\n"
".emtcode OP_SUBASSIGN 22\n"
".emtcode OP_MULASSIGN 23\n"
".emtcode OP_DIVASSIGN 24\n"
".emtcode OP_SELECT 31\n"
".emtcode OP_LOGICALOR 32\n"
".emtcode OP_LOGICALXOR 33\n"
".emtcode OP_LOGICALAND 34\n"
".emtcode OP_EQUAL 38\n"
".emtcode OP_NOTEQUAL 39\n"
".emtcode OP_LESS 40\n"
".emtcode OP_GREATER 41\n"
".emtcode OP_LESSEQUAL 42\n"
".emtcode OP_GREATEREQUAL 43\n"
".emtcode OP_ADD 46\n"
".emtcode OP_SUBTRACT 47\n"
".emtcode OP_MULTIPLY 48\n"
".emtcode OP_DIVIDE 49\n"
".emtcode OP_PREINCREMENT 51\n"
".emtcode OP_PREDECREMENT 52\n"
".emtcode OP_PLUS 53\n"
".emtcode OP_MINUS 54\n"
".emtcode OP_NOT 56\n"
".emtcode OP_SUBSCRIPT 57\n"
".emtcode OP_CALL 58\n"
".emtcode OP_FIELD 59\n"
".emtcode OP_POSTINCREMENT 60\n"
".emtcode OP_POSTDECREMENT 61\n"
".emtcode PARAM_QUALIFIER_IN 0\n"
".emtcode PARAM_QUALIFIER_OUT 1\n"
".emtcode PARAM_QUALIFIER_INOUT 2\n"
".emtcode PARAMETER_NONE 0\n"
".emtcode PARAMETER_NEXT 1\n"
".emtcode PARAMETER_ARRAY_NOT_PRESENT 0\n"
".emtcode PARAMETER_ARRAY_PRESENT 1\n"
".errtext INVALID_EXTERNAL_DECLARATION \"error 2001: invalid external declaration\"\n"
".errtext INVALID_OPERATOR_OVERRIDE \"error 2002: invalid operator override\"\n"
".errtext LBRACE_EXPECTED \"error 2003: '{' expected but '$err_token$' found\"\n"
".errtext LPAREN_EXPECTED \"error 2004: '(' expected but '$err_token$' found\"\n"
".errtext RPAREN_EXPECTED \"error 2005: ')' expected but '$err_token$' found\"\n"
".regbyte parsing_builtin 0\n"
".regbyte shader_type 0\n"
"variable_identifier\n"
" identifier .emit OP_PUSH_IDENTIFIER;\n"
"primary_expression\n"
" floatconstant .or boolconstant .or intconstant .or variable_identifier .or primary_expression_1;\n"
"primary_expression_1\n"
" lparen .and expression .and rparen;\n"
"postfix_expression\n"
" postfix_expression_1 .and .loop postfix_expression_2;\n"
"postfix_expression_1\n"
" function_call .or primary_expression;\n"
"postfix_expression_2\n"
" postfix_expression_3 .or postfix_expression_4 .or\n"
" plusplus .emit OP_POSTINCREMENT .or\n"
" minusminus .emit OP_POSTDECREMENT;\n"
"postfix_expression_3\n"
" lbracket .and integer_expression .and rbracket .emit OP_SUBSCRIPT;\n"
"postfix_expression_4\n"
" dot .and field_selection .emit OP_FIELD;\n"
"integer_expression\n"
" expression;\n"
"function_call\n"
" function_call_generic .emit OP_CALL .and .true .emit OP_END;\n"
"function_call_generic\n"
" function_call_generic_1 .or function_call_generic_2;\n"
"function_call_generic_1\n"
" function_call_header_with_parameters .and rparen .error RPAREN_EXPECTED;\n"
"function_call_generic_2\n"
" function_call_header_no_parameters .and rparen .error RPAREN_EXPECTED;\n"
"function_call_header_no_parameters\n"
" function_call_header .and function_call_header_no_parameters_1;\n"
"function_call_header_no_parameters_1\n"
" \"void\" .or .true;\n"
"function_call_header_with_parameters\n"
" function_call_header .and assignment_expression .and .true .emit OP_END .and\n"
" .loop function_call_header_with_parameters_1;\n"
"function_call_header_with_parameters_1\n"
" comma .and assignment_expression .and .true .emit OP_END;\n"
"function_call_header\n"
" function_identifier .and lparen;\n"
"function_identifier\n"
" identifier;\n"
"unary_expression\n"
" postfix_expression .or unary_expression_1 .or unary_expression_2 .or unary_expression_3 .or\n"
" unary_expression_4 .or unary_expression_5;\n"
"unary_expression_1\n"
" plusplus .and unary_expression .and .true .emit OP_PREINCREMENT;\n"
"unary_expression_2\n"
" minusminus .and unary_expression .and .true .emit OP_PREDECREMENT;\n"
"unary_expression_3\n"
" plus .and unary_expression .and .true .emit OP_PLUS;\n"
"unary_expression_4\n"
" minus .and unary_expression .and .true .emit OP_MINUS;\n"
"unary_expression_5\n"
" bang .and unary_expression .and .true .emit OP_NOT;\n"
"multiplicative_expression\n"
" unary_expression .and .loop multiplicative_expression_1;\n"
"multiplicative_expression_1\n"
" multiplicative_expression_2 .or multiplicative_expression_3;\n"
"multiplicative_expression_2\n"
" star .and unary_expression .and .true .emit OP_MULTIPLY;\n"
"multiplicative_expression_3\n"
" slash .and unary_expression .and .true .emit OP_DIVIDE;\n"
"additive_expression\n"
" multiplicative_expression .and .loop additive_expression_1;\n"
"additive_expression_1\n"
" additive_expression_2 .or additive_expression_3;\n"
"additive_expression_2\n"
" plus .and multiplicative_expression .and .true .emit OP_ADD;\n"
"additive_expression_3\n"
" minus .and multiplicative_expression .and .true .emit OP_SUBTRACT;\n"
"shift_expression\n"
" additive_expression;\n"
"relational_expression\n"
" shift_expression .and .loop relational_expression_1;\n"
"relational_expression_1\n"
" relational_expression_2 .or relational_expression_3 .or relational_expression_4 .or\n"
" relational_expression_5;\n"
"relational_expression_2\n"
" lessequals .and shift_expression .and .true .emit OP_LESSEQUAL;\n"
"relational_expression_3\n"
" greaterequals .and shift_expression .and .true .emit OP_GREATEREQUAL;\n"
"relational_expression_4\n"
" less .and shift_expression .and .true .emit OP_LESS;\n"
"relational_expression_5\n"
" greater .and shift_expression .and .true .emit OP_GREATER;\n"
"equality_expression\n"
" relational_expression .and .loop equality_expression_1;\n"
"equality_expression_1\n"
" equality_expression_2 .or equality_expression_3;\n"
"equality_expression_2\n"
" equalsequals .and relational_expression .and .true .emit OP_EQUAL;\n"
"equality_expression_3\n"
" bangequals .and relational_expression .and .true .emit OP_NOTEQUAL;\n"
"and_expression\n"
" equality_expression;\n"
"exclusive_or_expression\n"
" and_expression;\n"
"inclusive_or_expression\n"
" exclusive_or_expression;\n"
"logical_and_expression\n"
" inclusive_or_expression .and .loop logical_and_expression_1;\n"
"logical_and_expression_1\n"
" ampersandampersand .and inclusive_or_expression .and .true .emit OP_LOGICALAND;\n"
"logical_xor_expression\n"
" logical_and_expression .and .loop logical_xor_expression_1;\n"
"logical_xor_expression_1\n"
" caretcaret .and logical_and_expression .and .true .emit OP_LOGICALXOR;\n"
"logical_or_expression\n"
" logical_xor_expression .and .loop logical_or_expression_1;\n"
"logical_or_expression_1\n"
" barbar .and logical_xor_expression .and .true .emit OP_LOGICALOR;\n"
"conditional_expression\n"
" logical_or_expression .and .loop conditional_expression_1;\n"
"conditional_expression_1\n"
" question .and expression .and colon .and conditional_expression .and .true .emit OP_SELECT;\n"
"assignment_expression\n"
" assignment_expression_1 .or assignment_expression_2 .or assignment_expression_3 .or\n"
" assignment_expression_4 .or assignment_expression_5 .or conditional_expression;\n"
"assignment_expression_1\n"
" unary_expression .and equals .and assignment_expression .and .true .emit OP_ASSIGN;\n"
"assignment_expression_2\n"
" unary_expression .and starequals .and assignment_expression .and .true .emit OP_MULASSIGN;\n"
"assignment_expression_3\n"
" unary_expression .and slashequals .and assignment_expression .and .true .emit OP_DIVASSIGN;\n"
"assignment_expression_4\n"
" unary_expression .and plusequals .and assignment_expression .and .true .emit OP_ADDASSIGN;\n"
"assignment_expression_5\n"
" unary_expression .and minusequals .and assignment_expression .and .true .emit OP_SUBASSIGN;\n"
"expression\n"
" assignment_expression .and .loop expression_1;\n"
"expression_1\n"
" comma .and assignment_expression .and .true .emit OP_SEQUENCE;\n"
"constant_expression\n"
" conditional_expression .and .true .emit OP_END;\n"
"declaration\n"
" declaration_1 .or declaration_2;\n"
"declaration_1\n"
" function_prototype .emit DECLARATION_FUNCTION_PROTOTYPE .and semicolon;\n"
"declaration_2\n"
" init_declarator_list .emit DECLARATION_INIT_DECLARATOR_LIST .and semicolon;\n"
"function_prototype\n"
" function_declarator .and rparen .error RPAREN_EXPECTED .emit PARAMETER_NONE;\n"
"function_declarator\n"
" function_header_with_parameters .or function_header;\n"
"function_header_with_parameters\n"
" function_header .and parameter_declaration .and .loop function_header_with_parameters_1;\n"
"function_header_with_parameters_1\n"
" comma .and parameter_declaration;\n"
"function_header\n"
" function_header_nospace .or function_header_space;\n"
"function_header_space\n"
" fully_specified_type_space .and space .and function_decl_identifier .and lparen;\n"
"function_header_nospace\n"
" fully_specified_type_nospace .and function_decl_identifier .and lparen;\n"
"function_decl_identifier\n"
" .if (parsing_builtin != 0) __operator .emit FUNCTION_OPERATOR .or\n"
" .if (parsing_builtin != 0) \"__constructor\" .emit FUNCTION_CONSTRUCTOR .or\n"
" identifier .emit FUNCTION_ORDINARY;\n"
"__operator\n"
" \"__operator\" .and overriden_operator .error INVALID_OPERATOR_OVERRIDE;\n"
"overriden_operator\n"
" plusplus .emit OPERATOR_INCREMENT .or\n"
" plusequals .emit OPERATOR_ADDASSIGN .or\n"
" plus .emit OPERATOR_PLUS .or\n"
" minusminus .emit OPERATOR_DECREMENT .or\n"
" minusequals .emit OPERATOR_SUBASSIGN .or\n"
" minus .emit OPERATOR_MINUS .or\n"
" bangequals .emit OPERATOR_NOTEQUAL .or\n"
" bang .emit OPERATOR_NOT .or\n"
" starequals .emit OPERATOR_MULASSIGN .or\n"
" star .emit OPERATOR_MULTIPLY .or\n"
" slashequals .emit OPERATOR_DIVASSIGN .or\n"
" slash .emit OPERATOR_DIVIDE .or\n"
" lessequals .emit OPERATOR_LESSEQUAL .or\n"
" \n"
" \n"
" less .emit OPERATOR_LESS .or\n"
" greaterequals .emit OPERATOR_GREATEREQUAL .or\n"
" \n"
" \n"
" greater .emit OPERATOR_GREATER .or\n"
" equalsequals .emit OPERATOR_EQUAL .or\n"
" equals .emit OPERATOR_ASSIGN .or\n"
" \n"
" \n"
" \n"
" \n"
" \n"
" \n"
" \n"
" \n"
" caretcaret .emit OPERATOR_LOGICALXOR ;\n"
"parameter_declarator\n"
" parameter_declarator_nospace .or parameter_declarator_space;\n"
"parameter_declarator_nospace\n"
" type_specifier_nospace .and identifier .and parameter_declarator_1;\n"
"parameter_declarator_space\n"
" type_specifier_space .and space .and identifier .and parameter_declarator_1;\n"
"parameter_declarator_1\n"
" parameter_declarator_2 .emit PARAMETER_ARRAY_PRESENT .or\n"
" .true .emit PARAMETER_ARRAY_NOT_PRESENT;\n"
"parameter_declarator_2\n"
" lbracket .and constant_expression .and rbracket;\n"
"parameter_declaration\n"
" parameter_declaration_1 .emit PARAMETER_NEXT;\n"
"parameter_declaration_1\n"
" parameter_declaration_2 .or parameter_declaration_3;\n"
"parameter_declaration_2\n"
" type_qualifier .and space .and parameter_qualifier .and parameter_declaration_4;\n"
"parameter_declaration_3\n"
" parameter_qualifier .emit TYPE_QUALIFIER_NONE .and parameter_declaration_4;\n"
"parameter_declaration_4\n"
" parameter_declarator .or parameter_type_specifier;\n"
"parameter_qualifier\n"
" parameter_qualifier_1 .or .true .emit PARAM_QUALIFIER_IN;\n"
"parameter_qualifier_1\n"
" parameter_qualifier_2 .and space;\n"
"parameter_qualifier_2\n"
" \"in\" .emit PARAM_QUALIFIER_IN .or\n"
" \"out\" .emit PARAM_QUALIFIER_OUT .or\n"
" \"inout\" .emit PARAM_QUALIFIER_INOUT;\n"
"parameter_type_specifier\n"
" parameter_type_specifier_1 .and .true .emit '\\0' .and parameter_type_specifier_2;\n"
"parameter_type_specifier_1\n"
" type_specifier_nospace .or type_specifier_space;\n"
"parameter_type_specifier_2\n"
" parameter_type_specifier_3 .emit PARAMETER_ARRAY_PRESENT .or\n"
" .true .emit PARAMETER_ARRAY_NOT_PRESENT;\n"
"parameter_type_specifier_3\n"
" lbracket .and constant_expression .and rbracket;\n"
"init_declarator_list\n"
" single_declaration .and .loop init_declarator_list_1 .emit DECLARATOR_NEXT .and\n"
" .true .emit DECLARATOR_NONE;\n"
"init_declarator_list_1\n"
" comma .and identifier .emit VARIABLE_IDENTIFIER .and init_declarator_list_2;\n"
"init_declarator_list_2\n"
" init_declarator_list_3 .or init_declarator_list_4 .or .true .emit VARIABLE_NONE;\n"
"init_declarator_list_3\n"
" equals .and initializer .emit VARIABLE_INITIALIZER;\n"
"init_declarator_list_4\n"
" lbracket .and init_declarator_list_5 .and rbracket;\n"
"init_declarator_list_5\n"
" constant_expression .emit VARIABLE_ARRAY_EXPLICIT .or .true .emit VARIABLE_ARRAY_UNKNOWN;\n"
"single_declaration\n"
" single_declaration_nospace .or single_declaration_space;\n"
"single_declaration_space\n"
" fully_specified_type_space .and single_declaration_space_1;\n"
"single_declaration_nospace\n"
" fully_specified_type_nospace .and single_declaration_nospace_1;\n"
"single_declaration_space_1\n"
" single_declaration_space_2 .emit VARIABLE_IDENTIFIER .or .true .emit VARIABLE_NONE;\n"
"single_declaration_nospace_1\n"
" single_declaration_nospace_2 .emit VARIABLE_IDENTIFIER .or .true .emit VARIABLE_NONE;\n"
"single_declaration_space_2\n"
" space .and identifier .and single_declaration_3;\n"
"single_declaration_nospace_2\n"
" identifier .and single_declaration_3;\n"
"single_declaration_3\n"
" single_declaration_4 .or single_declaration_5 .or .true .emit VARIABLE_NONE;\n"
"single_declaration_4\n"
" equals .and initializer .emit VARIABLE_INITIALIZER;\n"
"single_declaration_5\n"
" lbracket .and single_declaration_6 .and rbracket;\n"
"single_declaration_6\n"
" constant_expression .emit VARIABLE_ARRAY_EXPLICIT .or .true .emit VARIABLE_ARRAY_UNKNOWN;\n"
"fully_specified_type_space\n"
" fully_specified_type_1 .and type_specifier_space;\n"
"fully_specified_type_nospace\n"
" fully_specified_type_1 .and type_specifier_nospace;\n"
"fully_specified_type_1\n"
" fully_specified_type_2 .or .true .emit TYPE_QUALIFIER_NONE;\n"
"fully_specified_type_2\n"
" type_qualifier .and space;\n"
"type_qualifier\n"
" \"const\" .emit TYPE_QUALIFIER_CONST .or\n"
" .if (shader_type == 2) \"attribute\" .emit TYPE_QUALIFIER_ATTRIBUTE .or\n"
" \"varying\" .emit TYPE_QUALIFIER_VARYING .or\n"
" \"uniform\" .emit TYPE_QUALIFIER_UNIFORM .or\n"
" .if (parsing_builtin != 0) \"__fixed_output\" .emit TYPE_QUALIFIER_FIXEDOUTPUT .or\n"
" .if (parsing_builtin != 0) \"__fixed_input\" .emit TYPE_QUALIFIER_FIXEDINPUT;\n"
"type_specifier_space\n"
" \"void\" .emit TYPE_SPECIFIER_VOID .or\n"
" \"float\" .emit TYPE_SPECIFIER_FLOAT .or\n"
" \"int\" .emit TYPE_SPECIFIER_INT .or\n"
" \"bool\" .emit TYPE_SPECIFIER_BOOL .or\n"
" \"vec2\" .emit TYPE_SPECIFIER_VEC2 .or\n"
" \"vec3\" .emit TYPE_SPECIFIER_VEC3 .or\n"
" \"vec4\" .emit TYPE_SPECIFIER_VEC4 .or\n"
" \"bvec2\" .emit TYPE_SPECIFIER_BVEC2 .or\n"
" \"bvec3\" .emit TYPE_SPECIFIER_BVEC3 .or\n"
" \"bvec4\" .emit TYPE_SPECIFIER_BVEC4 .or\n"
" \"ivec2\" .emit TYPE_SPECIFIER_IVEC2 .or\n"
" \"ivec3\" .emit TYPE_SPECIFIER_IVEC3 .or\n"
" \"ivec4\" .emit TYPE_SPECIFIER_IVEC4 .or\n"
" \"mat2\" .emit TYPE_SPECIFIER_MAT2 .or\n"
" \"mat3\" .emit TYPE_SPECIFIER_MAT3 .or\n"
" \"mat4\" .emit TYPE_SPECIFIER_MAT4 .or\n"
" \"sampler1D\" .emit TYPE_SPECIFIER_SAMPLER1D .or\n"
" \"sampler2D\" .emit TYPE_SPECIFIER_SAMPLER2D .or\n"
" \"sampler3D\" .emit TYPE_SPECIFIER_SAMPLER3D .or\n"
" \"samplerCube\" .emit TYPE_SPECIFIER_SAMPLERCUBE .or\n"
" \"sampler1DShadow\" .emit TYPE_SPECIFIER_SAMPLER1DSHADOW .or\n"
" \"sampler2DShadow\" .emit TYPE_SPECIFIER_SAMPLER2DSHADOW .or\n"
" type_name .emit TYPE_SPECIFIER_TYPENAME;\n"
"type_specifier_nospace\n"
" struct_specifier .emit TYPE_SPECIFIER_STRUCT;\n"
"struct_specifier\n"
" \"struct\" .and struct_specifier_1 .and optional_space .and lbrace .error LBRACE_EXPECTED .and\n"
" struct_declaration_list .and rbrace .emit FIELD_NONE;\n"
"struct_specifier_1\n"
" struct_specifier_2 .or .true .emit '\\0';\n"
"struct_specifier_2\n"
" space .and identifier;\n"
"struct_declaration_list\n"
" struct_declaration .and .loop struct_declaration .emit FIELD_NEXT;\n"
"struct_declaration\n"
" struct_declaration_nospace .or struct_declaration_space;\n"
"struct_declaration_space\n"
" type_specifier_space .and space .and struct_declarator_list .and semicolon .emit FIELD_NONE;\n"
"struct_declaration_nospace\n"
" type_specifier_nospace .and struct_declarator_list .and semicolon .emit FIELD_NONE;\n"
"struct_declarator_list\n"
" struct_declarator .and .loop struct_declarator_list_1 .emit FIELD_NEXT;\n"
"struct_declarator_list_1\n"
" comma .and struct_declarator;\n"
"struct_declarator\n"
" identifier .and struct_declarator_1;\n"
"struct_declarator_1\n"
" struct_declarator_2 .emit FIELD_ARRAY .or .true .emit FIELD_NONE;\n"
"struct_declarator_2\n"
" lbracket .and constant_expression .and rbracket;\n"
"initializer\n"
" assignment_expression .and .true .emit OP_END;\n"
"declaration_statement\n"
" declaration;\n"
"statement\n"
" compound_statement .or simple_statement;\n"
"statement_space\n"
" compound_statement .or statement_space_1;\n"
"statement_space_1\n"
" space .and simple_statement;\n"
"simple_statement\n"
" .if (parsing_builtin != 0) __asm_statement .emit OP_ASM .or\n"
" selection_statement .or\n"
" iteration_statement .or\n"
" jump_statement .or\n"
" expression_statement .emit OP_EXPRESSION .or\n"
" declaration_statement .emit OP_DECLARE;\n"
"compound_statement\n"
" compound_statement_1 .emit OP_BLOCK_BEGIN_NEW_SCOPE .and .true .emit OP_END;\n"
"compound_statement_1\n"
" compound_statement_2 .or compound_statement_3;\n"
"compound_statement_2\n"
" lbrace .and rbrace;\n"
"compound_statement_3\n"
" lbrace .and statement_list .and rbrace;\n"
"statement_no_new_scope\n"
" compound_statement_no_new_scope .or simple_statement;\n"
"compound_statement_no_new_scope\n"
" compound_statement_no_new_scope_1 .emit OP_BLOCK_BEGIN_NO_NEW_SCOPE .and .true .emit OP_END;\n"
"compound_statement_no_new_scope_1\n"
" compound_statement_no_new_scope_2 .or compound_statement_no_new_scope_3;\n"
"compound_statement_no_new_scope_2\n"
" lbrace .and rbrace;\n"
"compound_statement_no_new_scope_3\n"
" lbrace .and statement_list .and rbrace;\n"
"statement_list\n"
" statement .and .loop statement;\n"
"expression_statement\n"
" expression_statement_1 .or expression_statement_2;\n"
"expression_statement_1\n"
" semicolon .emit OP_PUSH_VOID .emit OP_END;\n"
"expression_statement_2\n"
" expression .and semicolon .emit OP_END;\n"
"selection_statement\n"
" \"if\" .emit OP_IF .and lparen .error LPAREN_EXPECTED .and expression .and\n"
" rparen .error RPAREN_EXPECTED .emit OP_END .and selection_rest_statement;\n"
"selection_rest_statement\n"
" statement .and selection_rest_statement_1;\n"
"selection_rest_statement_1\n"
" selection_rest_statement_2 .or .true .emit OP_EXPRESSION .emit OP_PUSH_VOID .emit OP_END;\n"
"selection_rest_statement_2\n"
" \"else\" .and optional_space .and statement;\n"
"condition\n"
" condition_1 .emit OP_DECLARE .emit DECLARATION_INIT_DECLARATOR_LIST .or\n"
" condition_3 .emit OP_EXPRESSION;\n"
"condition_1\n"
" condition_1_nospace .or condition_1_space;\n"
"condition_1_nospace\n"
" fully_specified_type_nospace .and condition_2;\n"
"condition_1_space\n"
" fully_specified_type_space .and space .and condition_2;\n"
"condition_2\n"
" identifier .emit VARIABLE_IDENTIFIER .and equals .emit VARIABLE_INITIALIZER .and\n"
" initializer .and .true .emit DECLARATOR_NONE;\n"
"condition_3\n"
" expression .and .true .emit OP_END;\n"
"iteration_statement\n"
" iteration_statement_1 .or iteration_statement_2 .or iteration_statement_3;\n"
"iteration_statement_1\n"
" \"while\" .emit OP_WHILE .and lparen .error LPAREN_EXPECTED .and condition .and\n"
" rparen .error RPAREN_EXPECTED .and statement_no_new_scope;\n"
"iteration_statement_2\n"
" \"do\" .emit OP_DO .and statement_space .and \"while\" .and lparen .error LPAREN_EXPECTED .and\n"
" expression .and rparen .error RPAREN_EXPECTED .emit OP_END .and semicolon;\n"
"iteration_statement_3\n"
" \"for\" .emit OP_FOR .and lparen .error LPAREN_EXPECTED .and for_init_statement .and\n"
" for_rest_statement .and rparen .error RPAREN_EXPECTED .and statement_no_new_scope;\n"
"for_init_statement\n"
" expression_statement .emit OP_EXPRESSION .or declaration_statement .emit OP_DECLARE;\n"
"conditionopt\n"
" condition .or\n"
" .true .emit OP_EXPRESSION .emit OP_PUSH_BOOL .emit 2 .emit '1' .emit '\\0' .emit OP_END;\n"
"for_rest_statement\n"
" conditionopt .and semicolon .and for_rest_statement_1;\n"
"for_rest_statement_1\n"
" for_rest_statement_2 .or .true .emit OP_PUSH_VOID .emit OP_END;\n"
"for_rest_statement_2\n"
" expression .and .true .emit OP_END;\n"
"jump_statement\n"
" jump_statement_1 .or jump_statement_2 .or jump_statement_3 .or jump_statement_4 .or\n"
" .if (shader_type == 1) jump_statement_5;\n"
"jump_statement_1\n"
" \"continue\" .and semicolon .emit OP_CONTINUE;\n"
"jump_statement_2\n"
" \"break\" .and semicolon .emit OP_BREAK;\n"
"jump_statement_3\n"
" \"return\" .emit OP_RETURN .and optional_space .and expression .and semicolon .emit OP_END;\n"
"jump_statement_4\n"
" \"return\" .emit OP_RETURN .and semicolon .emit OP_PUSH_VOID .emit OP_END;\n"
"jump_statement_5\n"
" \"discard\" .and semicolon .emit OP_DISCARD;\n"
"__asm_statement\n"
" \"__asm\" .and space .and identifier .and space .and asm_arguments .and semicolon .emit OP_END;\n"
"asm_arguments\n"
" variable_identifier .and .true .emit OP_END .and .loop asm_arguments_1;\n"
"asm_arguments_1\n"
" comma .and variable_identifier .and .true .emit OP_END;\n"
"translation_unit\n"
" optional_space .emit REVISION .and external_declaration .error INVALID_EXTERNAL_DECLARATION .and\n"
" .loop external_declaration .and optional_space .and\n"
" '\\0' .error INVALID_EXTERNAL_DECLARATION .emit EXTERNAL_NULL;\n"
"external_declaration\n"
" function_definition .emit EXTERNAL_FUNCTION_DEFINITION .or\n"
" declaration .emit EXTERNAL_DECLARATION;\n"
"function_definition\n"
" function_prototype .and compound_statement_no_new_scope;\n"
"digit_oct\n"
" '0'-'7';\n"
"digit_dec\n"
" '0'-'9';\n"
"digit_hex\n"
" '0'-'9' .or 'A'-'F' .or 'a'-'f';\n"
"id_character_first\n"
" 'a'-'z' .or 'A'-'Z' .or '_';\n"
"id_character_next\n"
" id_character_first .or digit_dec;\n"
"identifier\n"
" id_character_first .emit * .and .loop id_character_next .emit * .and .true .emit '\\0';\n"
"float\n"
" float_1 .or float_2;\n"
"float_1\n"
" float_fractional_constant .and float_optional_exponent_part;\n"
"float_2\n"
" float_digit_sequence .and .true .emit '\\0' .and float_exponent_part;\n"
"float_fractional_constant\n"
" float_fractional_constant_1 .or float_fractional_constant_2 .or float_fractional_constant_3;\n"
"float_fractional_constant_1\n"
" float_digit_sequence .and '.' .and float_digit_sequence;\n"
"float_fractional_constant_2\n"
" float_digit_sequence .and '.' .and .true .emit '\\0';\n"
"float_fractional_constant_3\n"
" '.' .emit '\\0' .and float_digit_sequence;\n"
"float_optional_exponent_part\n"
" float_exponent_part .or .true .emit '\\0';\n"
"float_digit_sequence\n"
" digit_dec .emit * .and .loop digit_dec .emit * .and .true .emit '\\0';\n"
"float_exponent_part\n"
" float_exponent_part_1 .or float_exponent_part_2;\n"
"float_exponent_part_1\n"
" 'e' .and float_optional_sign .and float_digit_sequence;\n"
"float_exponent_part_2\n"
" 'E' .and float_optional_sign .and float_digit_sequence;\n"
"float_optional_sign\n"
" float_sign .or .true;\n"
"float_sign\n"
" '+' .or '-' .emit '-';\n"
"integer\n"
" integer_hex .or integer_oct .or integer_dec;\n"
"integer_hex\n"
" '0' .and integer_hex_1 .emit 0x10 .and digit_hex .emit * .and .loop digit_hex .emit * .and\n"
" .true .emit '\\0';\n"
"integer_hex_1\n"
" 'x' .or 'X';\n"
"integer_oct\n"
" '0' .emit 8 .emit * .and .loop digit_oct .emit * .and .true .emit '\\0';\n"
"integer_dec\n"
" digit_dec .emit 10 .emit * .and .loop digit_dec .emit * .and .true .emit '\\0';\n"
"boolean\n"
" \"true\" .emit 2 .emit '1' .emit '\\0' .or\n"
" \"false\" .emit 2 .emit '0' .emit '\\0';\n"
"type_name\n"
" identifier;\n"
"field_selection\n"
" identifier;\n"
"floatconstant\n"
" float .emit OP_PUSH_FLOAT;\n"
"intconstant\n"
" integer .emit OP_PUSH_INT;\n"
"boolconstant\n"
" boolean .emit OP_PUSH_BOOL;\n"
"optional_space\n"
" .loop single_space;\n"
"space\n"
" single_space .and .loop single_space;\n"
"single_space\n"
" white_char .or c_style_comment_block .or cpp_style_comment_block;\n"
"white_char\n"
" ' ' .or '\\t' .or new_line .or '\\v' .or '\\f';\n"
"new_line\n"
" cr_lf .or lf_cr .or '\\n' .or '\\r';\n"
"cr_lf\n"
" '\\r' .and '\\n';\n"
"lf_cr\n"
" '\\n' .and '\\r';\n"
"c_style_comment_block\n"
" '/' .and '*' .and c_style_comment_rest;\n"
"c_style_comment_rest\n"
" .loop c_style_comment_char_no_star .and c_style_comment_rest_1;\n"
"c_style_comment_rest_1\n"
" c_style_comment_end .or c_style_comment_rest_2;\n"
"c_style_comment_rest_2\n"
" '*' .and c_style_comment_rest;\n"
"c_style_comment_char_no_star\n"
" '\\x2B'-'\\xFF' .or '\\x01'-'\\x29';\n"
"c_style_comment_end\n"
" '*' .and '/';\n"
"cpp_style_comment_block\n"
" '/' .and '/' .and cpp_style_comment_block_1;\n"
"cpp_style_comment_block_1\n"
" cpp_style_comment_block_2 .or cpp_style_comment_block_3;\n"
"cpp_style_comment_block_2\n"
" .loop cpp_style_comment_char .and new_line;\n"
"cpp_style_comment_block_3\n"
" .loop cpp_style_comment_char;\n"
"cpp_style_comment_char\n"
" '\\x0E'-'\\xFF' .or '\\x01'-'\\x09' .or '\\x0B'-'\\x0C';\n"
"ampersandampersand\n"
" optional_space .and '&' .and '&' .and optional_space;\n"
"barbar\n"
" optional_space .and '|' .and '|' .and optional_space;\n"
"bang\n"
" optional_space .and '!' .and optional_space;\n"
"bangequals\n"
" optional_space .and '!' .and '=' .and optional_space;\n"
"caretcaret\n"
" optional_space .and '^' .and '^' .and optional_space;\n"
"colon\n"
" optional_space .and ':' .and optional_space;\n"
"comma\n"
" optional_space .and ',' .and optional_space;\n"
"dot\n"
" optional_space .and '.' .and optional_space;\n"
"equals\n"
" optional_space .and '=' .and optional_space;\n"
"equalsequals\n"
" optional_space .and '=' .and '=' .and optional_space;\n"
"greater\n"
" optional_space .and '>' .and optional_space;\n"
"greaterequals\n"
" optional_space .and '>' .and '=' .and optional_space;\n"
"lbrace\n"
" optional_space .and '{' .and optional_space;\n"
"lbracket\n"
" optional_space .and '[' .and optional_space;\n"
"less\n"
" optional_space .and '<' .and optional_space;\n"
"lessequals\n"
" optional_space .and '<' .and '=' .and optional_space;\n"
"lparen\n"
" optional_space .and '(' .and optional_space;\n"
"minus\n"
" optional_space .and '-' .and optional_space;\n"
"minusequals\n"
" optional_space .and '-' .and '=' .and optional_space;\n"
"minusminus\n"
" optional_space .and '-' .and '-' .and optional_space;\n"
"plus\n"
" optional_space .and '+' .and optional_space;\n"
"plusequals\n"
" optional_space .and '+' .and '=' .and optional_space;\n"
"plusplus\n"
" optional_space .and '+' .and '+' .and optional_space;\n"
"question\n"
" optional_space .and '?' .and optional_space;\n"
"rbrace\n"
" optional_space .and '}' .and optional_space;\n"
"rbracket\n"
" optional_space .and ']' .and optional_space;\n"
"rparen\n"
" optional_space .and ')' .and optional_space;\n"
"semicolon\n"
" optional_space .and ';' .and optional_space;\n"
"slash\n"
" optional_space .and '/' .and optional_space;\n"
"slashequals\n"
" optional_space .and '/' .and '=' .and optional_space;\n"
"star\n"
" optional_space .and '*' .and optional_space;\n"
"starequals\n"
" optional_space .and '*' .and '=' .and optional_space;\n"
".string string_lexer;\n"
"string_lexer\n"
" lex_first_identifier_character .and .loop lex_next_identifier_character;\n"
"lex_first_identifier_character\n"
" 'a'-'z' .or 'A'-'Z' .or '_';\n"
"lex_next_identifier_character\n"
" 'a'-'z' .or 'A'-'Z' .or '0'-'9' .or '_';\n"
"err_token\n"
" '~' .or '`' .or '!' .or '@' .or '#' .or '$' .or '%' .or '^' .or '&' .or '*' .or '(' .or ')' .or\n"
" '-' .or '+' .or '=' .or '|' .or '\\\\' .or '[' .or ']' .or '{' .or '}' .or ':' .or ';' .or '\"' .or\n"
" '\\'' .or '<' .or ',' .or '>' .or '.' .or '/' .or '?' .or err_identifier;\n"
"err_identifier\n"
" id_character_first .and .loop id_character_next;\n"
""
".syntax version_directive;\n"
"version_directive\n"
" version_directive_1 .and .loop version_directive_2;\n"
"version_directive_1\n"
" prior_optional_spaces .and optional_version_directive .and .true .emit $;\n"
"version_directive_2\n"
" prior_optional_spaces .and version_directive_body .and .true .emit $;\n"
"optional_version_directive\n"
" version_directive_body .or .true .emit 10 .emit 1;\n"
"version_directive_body\n"
" '#' .and optional_space .and \"version\" .and space .and version_number .and optional_space .and\n"
" new_line;\n"
"version_number\n"
" version_number_110;\n"
"version_number_110\n"
" leading_zeroes .and \"110\" .emit 10 .emit 1;\n"
"leading_zeroes\n"
" .loop zero;\n"
"zero\n"
" '0';\n"
"space\n"
" single_space .and .loop single_space;\n"
"optional_space\n"
" .loop single_space;\n"
"single_space\n"
" ' ' .or '\\t';\n"
"prior_optional_spaces\n"
" .loop prior_space;\n"
"prior_space\n"
" c_style_comment_block .or cpp_style_comment_block .or space .or new_line;\n"
"c_style_comment_block\n"
" '/' .and '*' .and c_style_comment_rest;\n"
"c_style_comment_rest\n"
" .loop c_style_comment_char_no_star .and c_style_comment_rest_1;\n"
"c_style_comment_rest_1\n"
" c_style_comment_end .or c_style_comment_rest_2;\n"
"c_style_comment_rest_2\n"
" '*' .and c_style_comment_rest;\n"
"c_style_comment_char_no_star\n"
" '\\x2B'-'\\xFF' .or '\\x01'-'\\x29';\n"
"c_style_comment_end\n"
" '*' .and '/';\n"
"cpp_style_comment_block\n"
" '/' .and '/' .and cpp_style_comment_block_1;\n"
"cpp_style_comment_block_1\n"
" cpp_style_comment_block_2 .or cpp_style_comment_block_3;\n"
"cpp_style_comment_block_2\n"
" .loop cpp_style_comment_char .and new_line;\n"
"cpp_style_comment_block_3\n"
" .loop cpp_style_comment_char;\n"
"cpp_style_comment_char\n"
" '\\x0E'-'\\xFF' .or '\\x01'-'\\x09' .or '\\x0B'-'\\x0C';\n"
"new_line\n"
" cr_lf .or lf_cr .or '\\n' .or '\\r';\n"
"cr_lf\n"
" '\\r' .and '\\n';\n"
"lf_cr\n"
" '\\n' .and '\\r';\n"
".string __string_filter;\n"
"__string_filter\n"
" .loop __identifier_char;\n"
"__identifier_char\n"
" 'a'-'z' .or 'A'-'Z' .or '_' .or '0'-'9';\n"
""
".syntax version_directive;\n"
"version_directive\n"
" version_directive_1 .and .loop version_directive_2;\n"
"version_directive_1\n"
" prior_optional_spaces .and optional_version_directive .and .true .emit $;\n"
"version_directive_2\n"
" prior_optional_spaces .and version_directive_body .and .true .emit $;\n"
"optional_version_directive\n"
" version_directive_body .or .true .emit 10 .emit 1;\n"
"version_directive_body\n"
" '#' .and optional_space .and \"version\" .and space .and version_number .and optional_space .and\n"
" new_line;\n"
"version_number\n"
" version_number_110;\n"
"version_number_110\n"
" leading_zeroes .and \"110\" .emit 10 .emit 1;\n"
"leading_zeroes\n"
" .loop zero;\n"
"zero\n"
" '0';\n"
"space\n"
" single_space .and .loop single_space;\n"
"optional_space\n"
" .loop single_space;\n"
"single_space\n"
" ' ' .or '\\t';\n"
"prior_optional_spaces\n"
" .loop prior_space;\n"
"prior_space\n"
" c_style_comment_block .or cpp_style_comment_block .or space .or new_line;\n"
"c_style_comment_block\n"
" '/' .and '*' .and c_style_comment_rest;\n"
"c_style_comment_rest\n"
" .loop c_style_comment_char_no_star .and c_style_comment_rest_1;\n"
"c_style_comment_rest_1\n"
" c_style_comment_end .or c_style_comment_rest_2;\n"
"c_style_comment_rest_2\n"
" '*' .and c_style_comment_rest;\n"
"c_style_comment_char_no_star\n"
" '\\x2B'-'\\xFF' .or '\\x01'-'\\x29';\n"
"c_style_comment_end\n"
" '*' .and '/';\n"
"cpp_style_comment_block\n"
" '/' .and '/' .and cpp_style_comment_block_1;\n"
"cpp_style_comment_block_1\n"
" cpp_style_comment_block_2 .or cpp_style_comment_block_3;\n"
"cpp_style_comment_block_2\n"
" .loop cpp_style_comment_char .and new_line;\n"
"cpp_style_comment_block_3\n"
" .loop cpp_style_comment_char;\n"
"cpp_style_comment_char\n"
" '\\x0E'-'\\xFF' .or '\\x01'-'\\x09' .or '\\x0B'-'\\x0C';\n"
"new_line\n"
" cr_lf .or lf_cr .or '\\n' .or '\\r';\n"
"cr_lf\n"
" '\\r' .and '\\n';\n"
"lf_cr\n"
" '\\n' .and '\\r';\n"
".string __string_filter;\n"
"__string_filter\n"
" .loop __identifier_char;\n"
"__identifier_char\n"
" 'a'-'z' .or 'A'-'Z' .or '_' .or '0'-'9';\n"
""
/*
* Mesa 3-D graphics library
* Version: 6.3
*
* Copyright (C) 2005 Brian Paul All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
/**
* \file slang_assemble.c
* slang intermediate code assembler
* \author Michal Krol
*/
#include "imports.h"
#include "slang_utility.h"
#include "slang_assemble.h"
#include "slang_compile.h"
#include "slang_storage.h"
#include "slang_assemble_constructor.h"
#include "slang_assemble_typeinfo.h"
#include "slang_assemble_conditional.h"
#include "slang_assemble_assignment.h"
/* slang_assembly */
static void slang_assembly_construct (slang_assembly *assem)
{
assem->type = slang_asm_none;
}
static void slang_assembly_destruct (slang_assembly *assem)
{
}
/* slang_assembly_file */
void slang_assembly_file_construct (slang_assembly_file *file)
{
file->code = NULL;
file->count = 0;
}
void slang_assembly_file_destruct (slang_assembly_file *file)
{
unsigned int i;
for (i = 0; i < file->count; i++)
slang_assembly_destruct (file->code + i);
slang_alloc_free (file->code);
}
static int slang_assembly_file_push_new (slang_assembly_file *file)
{
file->code = (slang_assembly *) slang_alloc_realloc (file->code, file->count * sizeof (
slang_assembly), (file->count + 1) * sizeof (slang_assembly));
if (file->code != NULL)
{
slang_assembly_construct (file->code + file->count);
file->count++;
return 1;
}
return 0;
}
static int slang_assembly_file_push_general (slang_assembly_file *file, slang_assembly_type type,
GLfloat literal, GLuint label, GLuint size)
{
slang_assembly *assem;
if (!slang_assembly_file_push_new (file))
return 0;
assem = file->code + file->count - 1;
assem->type = type;
assem->literal = literal;
assem->param[0] = label;
assem->param[1] = size;
return 1;
}
int slang_assembly_file_push (slang_assembly_file *file, slang_assembly_type type)
{
return slang_assembly_file_push_general (file, type, (GLfloat) 0, 0, 0);
}
int slang_assembly_file_push_label (slang_assembly_file *file, slang_assembly_type type,
GLuint label)
{
return slang_assembly_file_push_general (file, type, (GLfloat) 0, label, 0);
}
int slang_assembly_file_push_label2 (slang_assembly_file *file, slang_assembly_type type,
GLuint label1, GLuint label2)
{
return slang_assembly_file_push_general (file, type, (GLfloat) 0, label1, label2);
}
int slang_assembly_file_push_literal (slang_assembly_file *file, slang_assembly_type type,
GLfloat literal)
{
return slang_assembly_file_push_general (file, type, literal, 0, 0);
}
/* utility functions */
static int sizeof_variable (slang_type_specifier *spec, slang_type_qualifier qual,
slang_operation *array_size, slang_assembly_name_space *space, unsigned int *size)
{
slang_storage_aggregate agg;
slang_storage_aggregate_construct (&agg);
if (!_slang_aggregate_variable (&agg, spec, array_size, space->funcs, space->structs))
{
slang_storage_aggregate_destruct (&agg);
return 0;
}
*size += _slang_sizeof_aggregate (&agg);
if (qual == slang_qual_out || qual == slang_qual_inout)
*size += 4;
slang_storage_aggregate_destruct (&agg);
return 1;
}
static int sizeof_variable2 (slang_variable *var, slang_assembly_name_space *space,
unsigned int *size)
{
var->address = *size;
if (var->type.qualifier == slang_qual_out || var->type.qualifier == slang_qual_inout)
var->address += 4;
return sizeof_variable (&var->type.specifier, var->type.qualifier, var->array_size, space,
size);
}
static int sizeof_variables (slang_variable_scope *vars, unsigned int start, unsigned int stop,
slang_assembly_name_space *space, unsigned int *size)
{
unsigned int i;
for (i = start; i < stop; i++)
if (!sizeof_variable2 (vars->variables + i, space, size))
return 0;
return 1;
}
static int collect_locals (slang_operation *op, slang_assembly_name_space *space,
unsigned int *size)
{
unsigned int i;
if (!sizeof_variables (op->locals, 0, op->locals->num_variables, space, size))
return 0;
for (i = 0; i < op->num_children; i++)
if (!collect_locals (op->children + i, space, size))
return 0;
return 1;
}
/* _slang_locate_function() */
slang_function *_slang_locate_function (const char *name, slang_operation *params,
unsigned int num_params, slang_assembly_name_space *space)
{
unsigned int i;
for (i = 0; i < space->funcs->num_functions; i++)
{
unsigned int j;
slang_function *f = space->funcs->functions + i;
if (slang_string_compare (name, f->header.name) != 0)
continue;
if (f->param_count != num_params)
continue;
for (j = 0; j < num_params; j++)
{
slang_assembly_typeinfo ti;
slang_assembly_typeinfo_construct (&ti);
if (!_slang_typeof_operation (params + j, space, &ti))
{
slang_assembly_typeinfo_destruct (&ti);
return 0;
}
if (!slang_type_specifier_equal (&ti.spec, &f->parameters->variables[j].type.specifier))
{
slang_assembly_typeinfo_destruct (&ti);
break;
}
slang_assembly_typeinfo_destruct (&ti);
/* "out" and "inout" formal parameter requires the actual parameter to be l-value */
if (!ti.can_be_referenced &&
(f->parameters->variables[j].type.qualifier == slang_qual_out ||
f->parameters->variables[j].type.qualifier == slang_qual_inout))
break;
}
if (j == num_params)
return f;
}
if (space->funcs->outer_scope != NULL)
{
slang_assembly_name_space my_space = *space;
my_space.funcs = space->funcs->outer_scope;
return _slang_locate_function (name, params, num_params, &my_space);
}
return NULL;
}
/* _slang_assemble_function() */
int _slang_assemble_function (slang_assembly_file *file, slang_function *fun,
slang_assembly_name_space *space)
{
unsigned int param_size, local_size;
unsigned int skip, cleanup;
slang_assembly_flow_control flow;
slang_assembly_local_info info;
slang_assembly_stack_info stk;
fun->address = file->count;
if (fun->body == NULL)
{
/* TODO: jump to the actual function body */
return 1;
}
/* calculate return value and parameters size */
param_size = 0;
if (fun->header.type.specifier.type != slang_spec_void)
if (!sizeof_variable (&fun->header.type.specifier, slang_qual_none, NULL, space,
&param_size))
return 0;
info.ret_size = param_size;
if (!sizeof_variables (fun->parameters, 0, fun->param_count, space, &param_size))
return 0;
/* calculate local variables size, take into account the four-byte return address and
temporaries for various tasks */
info.addr_tmp = param_size + 4;
info.swizzle_tmp = param_size + 4 + 4;
local_size = param_size + 4 + 4 + 16;
if (!sizeof_variables (fun->parameters, fun->param_count, fun->parameters->num_variables, space,
&local_size))
return 0;
if (!collect_locals (fun->body, space, &local_size))
return 0;
/* allocate local variable storage */
if (!slang_assembly_file_push_label (file, slang_asm_local_alloc, local_size - param_size - 4))
return 0;
/* mark a new frame for function variable storage */
if (!slang_assembly_file_push_label (file, slang_asm_enter, local_size))
return 0;
/* skip the cleanup jump */
skip = file->count;
if (!slang_assembly_file_push_new (file))
return 0;
file->code[skip].type = slang_asm_jump;
/* all "return" statements will be directed here */
flow.function_end = file->count;
cleanup = file->count;
if (!slang_assembly_file_push_new (file))
return 0;
file->code[cleanup].type = slang_asm_jump;
/* execute the function body */
file->code[skip].param[0] = file->count;
if (!_slang_assemble_operation (file, fun->body, 0, &flow, space, &info, &stk))
return 0;
/* this is the end of the function - restore the old function frame */
file->code[cleanup].param[0] = file->count;
if (!slang_assembly_file_push (file, slang_asm_leave))
return 0;
/* free local variable storage */
if (!slang_assembly_file_push_label (file, slang_asm_local_free, local_size - param_size - 4))
return 0;
/* jump out of the function */
if (!slang_assembly_file_push (file, slang_asm_return))
return 0;
return 1;
}
int _slang_cleanup_stack (slang_assembly_file *file, slang_operation *op, int ref,
slang_assembly_name_space *space)
{
slang_assembly_typeinfo ti;
unsigned int size;
slang_assembly_typeinfo_construct (&ti);
if (!_slang_typeof_operation (op, space, &ti))
{
slang_assembly_typeinfo_destruct (&ti);
return 0;
}
if (ti.spec.type == slang_spec_void)
size = 0;
else if (ref)
size = 4;
else
{
size = 0;
if (!sizeof_variable (&ti.spec, slang_qual_none, NULL, space, &size))
{
slang_assembly_typeinfo_destruct (&ti);
return 0;
}
}
slang_assembly_typeinfo_destruct (&ti);
if (size != 0)
{
if (!slang_assembly_file_push_label (file, slang_asm_local_free, size))
return 0;
}
return 1;
}
/* _slang_assemble_operation() */
/* XXX: general swizzle! */
static int dereference_aggregate (slang_assembly_file *file, const slang_storage_aggregate *agg,
unsigned int index, unsigned int *size, slang_assembly_local_info *info)
{
unsigned int i;
for (i = agg->count; i > 0; i--)
{
const slang_storage_array *arr = agg->arrays + i - 1;
unsigned int j;
for (j = arr->length; j > 0; j--)
{
if (arr->type == slang_stor_aggregate)
{
if (!dereference_aggregate (file, arr->aggregate, index, size, info))
return 0;
}
else
{
*size -= 4;
if (!slang_assembly_file_push_label2 (file, slang_asm_local_addr, info->addr_tmp,
4))
return 0;
if (!slang_assembly_file_push (file, slang_asm_addr_deref))
return 0;
if (!slang_assembly_file_push_label (file, slang_asm_addr_push, *size))
return 0;
if (!slang_assembly_file_push (file, slang_asm_addr_add))
return 0;
switch (arr->type)
{
case slang_stor_bool:
if (!slang_assembly_file_push (file, slang_asm_bool_deref))
return 0;
break;
case slang_stor_int:
if (!slang_assembly_file_push (file, slang_asm_int_deref))
return 0;
break;
case slang_stor_float:
if (!slang_assembly_file_push (file, slang_asm_float_deref))
return 0;
break;
}
index += 4;
}
}
}
return 1;
}
/* XXX: general swizzle! */
int dereference (slang_assembly_file *file, slang_operation *op,
slang_assembly_name_space *space, slang_assembly_local_info *info)
{
slang_assembly_typeinfo ti;
int result;
slang_storage_aggregate agg;
unsigned int size;
slang_assembly_typeinfo_construct (&ti);
if (!_slang_typeof_operation (op, space, &ti))
{
slang_assembly_typeinfo_destruct (&ti);
return 0;
}
slang_storage_aggregate_construct (&agg);
if (!_slang_aggregate_variable (&agg, &ti.spec, NULL, space->funcs, space->structs))
{
slang_storage_aggregate_destruct (&agg);
slang_assembly_typeinfo_destruct (&ti);
return 0;
}
size = _slang_sizeof_aggregate (&agg);
result = dereference_aggregate (file, &agg, 0, &size, info);
slang_storage_aggregate_destruct (&agg);
slang_assembly_typeinfo_destruct (&ti);
return result;
}
static int call_function (slang_assembly_file *file, slang_function *fun, slang_operation *params,
unsigned int param_count, int assignment, slang_assembly_name_space *space,
slang_assembly_local_info *info)
{
unsigned int i;
slang_assembly_stack_info stk;
/* make room for the return value, if any */
if (fun->header.type.specifier.type != slang_spec_void)
{
unsigned int ret_size = 0;
if (!sizeof_variable (&fun->header.type.specifier, slang_qual_none, NULL, space, &ret_size))
return 0;
if (!slang_assembly_file_push_label (file, slang_asm_local_alloc, ret_size))
return 0;
}
/* push the actual parameters on the stack */
for (i = 0; i < param_count; i++)
{
slang_assembly_flow_control flow;
if (fun->parameters->variables[i].type.qualifier == slang_qual_inout ||
fun->parameters->variables[i].type.qualifier == slang_qual_out)
{
if (!slang_assembly_file_push_label2 (file, slang_asm_local_addr, info->addr_tmp, 4))
return 0;
/* TODO: optimize the "out" parameter case */
/* TODO: inspect stk */
if (!_slang_assemble_operation (file, params + i, 1, &flow, space, info, &stk))
return 0;
if (!slang_assembly_file_push (file, slang_asm_addr_copy))
return 0;
if (!slang_assembly_file_push (file, slang_asm_addr_deref))
return 0;
if (i == 0 && assignment)
{
if (!slang_assembly_file_push_label2 (file, slang_asm_local_addr, info->addr_tmp,
4))
return 0;
if (!slang_assembly_file_push (file, slang_asm_addr_deref))
return 0;
}
if (!dereference (file, params, space, info))
return 0;
}
else
{
/* TODO: for "out" and "inout" parameters also push the address (first) */
/* TODO: optimize the "out" parameter case */
/* TODO: inspect stk */
if (!_slang_assemble_operation (file, params + i, 0, &flow, space, info, &stk))
return 0;
}
}
/* call the function */
if (!slang_assembly_file_push_label (file, slang_asm_call, fun->address))
return 0;
/* pop the parameters from the stack */
for (i = param_count; i > 0; i--)
{
unsigned int j = i - 1;
if (fun->parameters->variables[j].type.qualifier == slang_qual_inout ||
fun->parameters->variables[j].type.qualifier == slang_qual_out)
{
if (!_slang_assemble_assignment (file, params + j, space, info))
return 0;
if (!slang_assembly_file_push_label (file, slang_asm_local_free, 4))
return 0;
}
else
{
if (!_slang_cleanup_stack (file, params + j, 0, space))
return 0;
}
}
return 1;
}
int call_function_name (slang_assembly_file *file, const char *name, slang_operation *params,
unsigned int param_count, int assignment, slang_assembly_name_space *space,
slang_assembly_local_info *info)
{
slang_function *fun = _slang_locate_function (name, params, param_count, space);
if (fun == NULL)
return 0;
return call_function (file, fun, params, param_count, assignment, space, info);
}
static int call_function_name_dummyint (slang_assembly_file *file, const char *name,
slang_operation *params, slang_assembly_name_space *space, slang_assembly_local_info *info)
{
slang_operation p2[2];
int result;
p2[0] = *params;
if (!slang_operation_construct_a (p2 + 1))
return 0;
p2[1].type = slang_oper_literal_int;
result = call_function_name (file, name, p2, 2, 0, space, info);
slang_operation_destruct (p2 + 1);
return result;
}
static int call_asm_instruction (slang_assembly_file *file, const char *name)
{
const struct
{
const char *name;
slang_assembly_type code1, code2;
} inst[] = {
{ "float_to_int", slang_asm_float_to_int, slang_asm_int_copy },
{ "int_to_float", slang_asm_int_to_float, slang_asm_float_copy },
{ "float_copy", slang_asm_float_copy, slang_asm_none },
{ "int_copy", slang_asm_int_copy, slang_asm_none },
{ "bool_copy", slang_asm_bool_copy, slang_asm_none },
{ "float_add", slang_asm_float_add, slang_asm_float_copy },
{ "float_multiply", slang_asm_float_multiply, slang_asm_float_copy },
{ "float_divide", slang_asm_float_divide, slang_asm_float_copy },
{ "float_negate", slang_asm_float_negate, slang_asm_float_copy },
{ "float_less", slang_asm_float_less, slang_asm_bool_copy },
{ "float_equal", slang_asm_float_equal, slang_asm_bool_copy },
{ NULL, slang_asm_none, slang_asm_none }
};
unsigned int i;
for (i = 0; inst[i].name != NULL; i++)
if (slang_string_compare (name, inst[i].name) == 0)
break;
if (inst[i].name == NULL)
return 0;
if (!slang_assembly_file_push_label2 (file, inst[i].code1, 4, 0))
return 0;
if (inst[i].code2 != slang_asm_none)
if (!slang_assembly_file_push_label2 (file, inst[i].code2, 4, 0))
return 0;
/* clean-up the stack from the remaining dst address */
if (!slang_assembly_file_push_label (file, slang_asm_local_free, 4))
return 0;
return 1;
}
/* XXX: general swizzle! */
static int equality_aggregate (slang_assembly_file *file, const slang_storage_aggregate *agg,
unsigned int *index, unsigned int size, slang_assembly_local_info *info, unsigned int z_label)
{
unsigned int i;
for (i = 0; i < agg->count; i++)
{
const slang_storage_array *arr = agg->arrays + i;
unsigned int j;
for (j = 0; j < arr->length; j++)
{
if (arr->type == slang_stor_aggregate)
{
if (!equality_aggregate (file, arr->aggregate, index, size, info, z_label))
return 0;
}
else
{
if (!slang_assembly_file_push_label2 (file, slang_asm_float_equal, size + *index,
*index))
return 0;
*index += 4;
if (!slang_assembly_file_push_label (file, slang_asm_jump_if_zero, z_label))
return 0;
}
}
}
return 1;
}
/* XXX: general swizzle! */
static int equality (slang_assembly_file *file, slang_operation *op,
slang_assembly_name_space *space, slang_assembly_local_info *info, int equal)
{
slang_assembly_typeinfo ti;
int result;
slang_storage_aggregate agg;
unsigned int index, size;
unsigned int skip_jump, true_label, true_jump, false_label, false_jump;
/* get type of operation */
slang_assembly_typeinfo_construct (&ti);
if (!_slang_typeof_operation (op, space, &ti))
{
slang_assembly_typeinfo_destruct (&ti);
return 0;
}
/* convert it to an aggregate */
slang_storage_aggregate_construct (&agg);
if (!(result = _slang_aggregate_variable (&agg, &ti.spec, NULL, space->funcs, space->structs)))
goto end;
/* compute the size of the agregate - there are two such aggregates on the stack */
size = _slang_sizeof_aggregate (&agg);
/* jump to the actual data-comparison code */
skip_jump = file->count;
if (!(result = slang_assembly_file_push (file, slang_asm_jump)))
goto end;
/* pop off the stack the compared data and push 1 */
true_label = file->count;
if (!(result = slang_assembly_file_push_label (file, slang_asm_local_free, size * 2)))
goto end;
if (!(result = slang_assembly_file_push_literal (file, slang_asm_bool_push, 1.0f)))
goto end;
true_jump = file->count;
if (!(result = slang_assembly_file_push (file, slang_asm_jump)))
goto end;
false_label = file->count;
if (!(result = slang_assembly_file_push_label (file, slang_asm_local_free, size * 2)))
goto end;
if (!(result = slang_assembly_file_push_literal (file, slang_asm_bool_push, 0.0f)))
goto end;
false_jump = file->count;
if (!(result = slang_assembly_file_push (file, slang_asm_jump)))
goto end;
file->code[skip_jump].param[0] = file->count;
/* compare the data on stack, it will eventually jump either to true or false label */
index = 0;
if (!(result = equality_aggregate (file, &agg, &index, size, info,
equal ? false_label : true_label)))
goto end;
if (!(result = slang_assembly_file_push_label (file, slang_asm_jump,
equal ? true_label : false_label)))
goto end;
file->code[true_jump].param[0] = file->count;
file->code[false_jump].param[0] = file->count;
result = 1;
end:
slang_storage_aggregate_destruct (&agg);
slang_assembly_typeinfo_destruct (&ti);
return result;
}
int _slang_assemble_operation (slang_assembly_file *file, slang_operation *op, int reference,
slang_assembly_flow_control *flow, slang_assembly_name_space *space,
slang_assembly_local_info *info, slang_assembly_stack_info *stk)
{
unsigned int assem;
stk->swizzle_mask = 0;
assem = file->count;
if (!slang_assembly_file_push_new (file))
return 0;
switch (op->type)
{
case slang_oper_block_no_new_scope:
case slang_oper_block_new_scope:
{
unsigned int i;
for (i = 0; i < op->num_children; i++)
{
slang_assembly_stack_info stk;
if (!_slang_assemble_operation (file, op->children + i, 0, flow, space, info, &stk))
return 0;
/* TODO: pass-in stk to cleanup */
if (!_slang_cleanup_stack (file, op->children + i, 0, space))
return 0;
}
}
break;
case slang_oper_variable_decl:
{
unsigned int i;
for (i = 0; i < op->num_children; i++)
{
/* TODO: perform initialization of op->children[i] */
/* TODO: clean-up stack */
}
}
break;
case slang_oper_asm:
{
unsigned int i;
for (i = 0; i < op->num_children; i++)
{
slang_assembly_stack_info stk;
if (!_slang_assemble_operation (file, op->children + i, i == 0, flow, space, info,
&stk))
return 0;
/* TODO: inspect stk */
}
if (!call_asm_instruction (file, op->identifier))
return 0;
}
break;
case slang_oper_break:
file->code[assem].type = slang_asm_jump;
file->code[assem].param[0] = flow->loop_end;
break;
case slang_oper_continue:
file->code[assem].type = slang_asm_jump;
file->code[assem].param[0] = flow->loop_start;
break;
case slang_oper_discard:
file->code[assem].type = slang_asm_discard;
if (!slang_assembly_file_push (file, slang_asm_exit))
return 0;
break;
case slang_oper_return:
if (info->ret_size != 0)
{
slang_assembly_stack_info stk;
if (!slang_assembly_file_push_label2 (file, slang_asm_local_addr, 0, info->ret_size))
return 0;
if (!_slang_assemble_operation (file, op->children, 0, flow, space, info, &stk))
return 0;
/* TODO: inspect stk */
if (!_slang_assemble_assignment (file, op->children, space, info))
return 0;
if (!slang_assembly_file_push_label (file, slang_asm_local_free, 4))
return 0;
}
if (!slang_assembly_file_push_label (file, slang_asm_jump, flow->function_end))
return 0;
break;
case slang_oper_expression:
{
slang_assembly_stack_info stk;
if (!_slang_assemble_operation (file, op->children, reference, flow, space, info, &stk))
return 0;
/* TODO: inspect stk */
}
break;
case slang_oper_if:
if (!_slang_assemble_if (file, op, flow, space, info))
return 0;
break;
case slang_oper_while:
if (!_slang_assemble_while (file, op, flow, space, info))
return 0;
break;
case slang_oper_do:
if (!_slang_assemble_do (file, op, flow, space, info))
return 0;
break;
case slang_oper_for:
if (!_slang_assemble_for (file, op, flow, space, info))
return 0;
break;
case slang_oper_void:
break;
case slang_oper_literal_bool:
file->code[assem].type = slang_asm_bool_push;
file->code[assem].literal = op->literal;
break;
case slang_oper_literal_int:
file->code[assem].type = slang_asm_int_push;
file->code[assem].literal = op->literal;
break;
case slang_oper_literal_float:
file->code[assem].type = slang_asm_float_push;
file->code[assem].literal = op->literal;
break;
case slang_oper_identifier:
{
slang_variable *var;
unsigned int size;
var = _slang_locate_variable (op->locals, op->identifier, 1);
if (var == NULL)
return 0;
size = 0;
if (!sizeof_variable (&var->type.specifier, slang_qual_none, var->array_size, space,
&size))
return 0;
if (var->initializer != NULL)
{
assert (!"var->initializer, oper_identifier");
}
else
{
if (!reference)
{
if (!slang_assembly_file_push_label2 (file, slang_asm_local_addr,
info->addr_tmp, 4))
return 0;
}
/* XXX: globals! */
if (!slang_assembly_file_push_label2 (file, slang_asm_local_addr, var->address,
size))
return 0;
if (!reference)
{
if (!slang_assembly_file_push (file, slang_asm_addr_copy))
return 0;
if (!slang_assembly_file_push_label (file, slang_asm_local_free, 4))
return 0;
if (!dereference (file, op, space, info))
return 0;
}
}
}
break;
case slang_oper_sequence:
{
slang_assembly_stack_info stk;
if (!_slang_assemble_operation (file, op->children, 0, flow, space, info, &stk))
return 0;
/* TODO: pass-in stk to cleanup */
if (!_slang_cleanup_stack (file, op->children, 0, space))
return 0;
if (!_slang_assemble_operation (file, op->children + 1, 0, flow, space, info,
&stk))
return 0;
/* TODO: inspect stk */
}
break;
case slang_oper_assign:
if (!_slang_assemble_assign (file, op, "=", reference, space, info))
return 0;
break;
case slang_oper_addassign:
if (!_slang_assemble_assign (file, op, "+=", reference, space, info))
return 0;
break;
case slang_oper_subassign:
if (!_slang_assemble_assign (file, op, "-=", reference, space, info))
return 0;
break;
case slang_oper_mulassign:
if (!_slang_assemble_assign (file, op, "*=", reference, space, info))
return 0;
break;
/*case slang_oper_modassign:*/
/*case slang_oper_lshassign:*/
/*case slang_oper_rshassign:*/
/*case slang_oper_orassign:*/
/*case slang_oper_xorassign:*/
/*case slang_oper_andassign:*/
case slang_oper_divassign:
if (!_slang_assemble_assign (file, op, "/=", reference, space, info))
return 0;
break;
case slang_oper_select:
if (!_slang_assemble_select (file, op, flow, space, info))
return 0;
break;
case slang_oper_logicalor:
if (!_slang_assemble_logicalor (file, op, flow, space, info))
return 0;
break;
case slang_oper_logicaland:
if (!_slang_assemble_logicaland (file, op, flow, space, info))
return 0;
break;
case slang_oper_logicalxor:
if (!call_function_name (file, "^^", op->children, 2, 0, space, info))
return 0;
break;
/*case slang_oper_bitor:*/
/*case slang_oper_bitxor:*/
/*case slang_oper_bitand:*/
case slang_oper_less:
if (!call_function_name (file, "<", op->children, 2, 0, space, info))
return 0;
break;
case slang_oper_greater:
if (!call_function_name (file, ">", op->children, 2, 0, space, info))
return 0;
break;
case slang_oper_lessequal:
if (!call_function_name (file, "<=", op->children, 2, 0, space, info))
return 0;
break;
case slang_oper_greaterequal:
if (!call_function_name (file, ">=", op->children, 2, 0, space, info))
return 0;
break;
/*case slang_oper_lshift:*/
/*case slang_oper_rshift:*/
case slang_oper_add:
if (!call_function_name (file, "+", op->children, 2, 0, space, info))
return 0;
break;
case slang_oper_subtract:
if (!call_function_name (file, "-", op->children, 2, 0, space, info))
return 0;
break;
case slang_oper_multiply:
if (!call_function_name (file, "*", op->children, 2, 0, space, info))
return 0;
break;
/*case slang_oper_modulus:*/
case slang_oper_divide:
if (!call_function_name (file, "/", op->children, 2, 0, space, info))
return 0;
break;
case slang_oper_equal:
{
slang_assembly_stack_info stk;
if (!_slang_assemble_operation (file, op->children, 0, flow, space, info, &stk))
return 0;
/* TODO: inspect stk */
if (!_slang_assemble_operation (file, op->children + 1, 0, flow, space, info, &stk))
return 0;
/* TODO: inspect stk */
if (!equality (file, op->children, space, info, 1))
return 0;
}
break;
case slang_oper_notequal:
{
slang_assembly_stack_info stk;
if (!_slang_assemble_operation (file, op->children, 0, flow, space, info, &stk))
return 0;
/* TODO: inspect stk */
if (!_slang_assemble_operation (file, op->children + 1, 0, flow, space, info, &stk))
return 0;
/* TODO: inspect stk */
if (!equality (file, op->children, space, info, 0))
return 0;
}
break;
case slang_oper_preincrement:
if (!_slang_assemble_assign (file, op, "++", reference, space, info))
return 0;
break;
case slang_oper_predecrement:
if (!_slang_assemble_assign (file, op, "--", reference, space, info))
return 0;
break;
case slang_oper_plus:
if (!call_function_name (file, "+", op->children, 1, 0, space, info))
return 0;
break;
case slang_oper_minus:
if (!call_function_name (file, "-", op->children, 1, 0, space, info))
return 0;
break;
/*case slang_oper_complement:*/
case slang_oper_not:
if (!call_function_name (file, "!", op->children, 1, 0, space, info))
return 0;
break;
case slang_oper_subscript:
{
slang_assembly_stack_info _stk;
slang_assembly_typeinfo ti_arr, ti_elem;
unsigned int arr_size = 0, elem_size = 0;
if (!_slang_assemble_operation (file, op->children, reference, flow, space, info,
&_stk))
return 0;
if (!_slang_assemble_operation (file, op->children + 1, 0, flow, space, info, &_stk))
return 0;
slang_assembly_typeinfo_construct (&ti_arr);
if (!_slang_typeof_operation (op->children, space, &ti_arr))
{
slang_assembly_typeinfo_destruct (&ti_arr);
return 0;
}
if (!sizeof_variable (&ti_arr.spec, slang_qual_none, NULL, space, &arr_size))
{
slang_assembly_typeinfo_destruct (&ti_arr);
return 0;
}
slang_assembly_typeinfo_construct (&ti_elem);
if (!_slang_typeof_operation (op, space, &ti_elem))
{
slang_assembly_typeinfo_destruct (&ti_arr);
slang_assembly_typeinfo_destruct (&ti_elem);
return 0;
}
if (!sizeof_variable (&ti_elem.spec, slang_qual_none, NULL, space, &elem_size))
{
slang_assembly_typeinfo_destruct (&ti_arr);
slang_assembly_typeinfo_destruct (&ti_elem);
return 0;
}
if (!slang_assembly_file_push (file, slang_asm_int_to_addr))
{
slang_assembly_typeinfo_destruct (&ti_arr);
slang_assembly_typeinfo_destruct (&ti_elem);
return 0;
}
if (!slang_assembly_file_push_label (file, slang_asm_addr_push, elem_size))
{
slang_assembly_typeinfo_destruct (&ti_arr);
slang_assembly_typeinfo_destruct (&ti_elem);
return 0;
}
if (!slang_assembly_file_push (file, slang_asm_addr_multiply))
{
slang_assembly_typeinfo_destruct (&ti_arr);
slang_assembly_typeinfo_destruct (&ti_elem);
return 0;
}
if (reference)
{
if (!slang_assembly_file_push (file, slang_asm_addr_add))
{
slang_assembly_typeinfo_destruct (&ti_arr);
slang_assembly_typeinfo_destruct (&ti_elem);
return 0;
}
}
else
{
unsigned int i;
for (i = 0; i < elem_size; i += 4)
{
if (!slang_assembly_file_push_label2 (file, slang_asm_float_move,
arr_size - elem_size + i + 4, i + 4))
{
slang_assembly_typeinfo_destruct (&ti_arr);
slang_assembly_typeinfo_destruct (&ti_elem);
return 0;
}
}
if (!slang_assembly_file_push_label (file, slang_asm_local_free, 4))
{
slang_assembly_typeinfo_destruct (&ti_arr);
slang_assembly_typeinfo_destruct (&ti_elem);
return 0;
}
if (!slang_assembly_file_push_label (file, slang_asm_local_free,
arr_size - elem_size))
{
slang_assembly_typeinfo_destruct (&ti_arr);
slang_assembly_typeinfo_destruct (&ti_elem);
return 0;
}
}
slang_assembly_typeinfo_destruct (&ti_arr);
slang_assembly_typeinfo_destruct (&ti_elem);
}
break;
case slang_oper_call:
{
slang_function *fun = _slang_locate_function (op->identifier, op->children,
op->num_children, space);
if (fun == NULL)
{
if (!_slang_assemble_constructor (file, op, flow, space, info))
return 0;
}
else
{
if (!call_function (file, fun, op->children, op->num_children, 0, space, info))
return 0;
}
}
break;
case slang_oper_field:
{
slang_assembly_typeinfo ti_after, ti_before;
slang_assembly_stack_info _stk;
slang_assembly_typeinfo_construct (&ti_after);
if (!_slang_typeof_operation (op, space, &ti_after))
{
slang_assembly_typeinfo_destruct (&ti_after);
return 0;
}
slang_assembly_typeinfo_construct (&ti_before);
if (!_slang_typeof_operation (op->children, space, &ti_before))
{
slang_assembly_typeinfo_destruct (&ti_after);
slang_assembly_typeinfo_destruct (&ti_before);
return 0;
}
if (!reference && ti_after.is_swizzled)
{
if (!slang_assembly_file_push_label2 (file, slang_asm_local_addr,
info->swizzle_tmp, 16))
{
slang_assembly_typeinfo_destruct (&ti_after);
slang_assembly_typeinfo_destruct (&ti_before);
return 0;
}
}
if (!_slang_assemble_operation (file, op->children, reference, flow, space, info,
&_stk))
{
slang_assembly_typeinfo_destruct (&ti_after);
slang_assembly_typeinfo_destruct (&ti_before);
return 0;
}
/* TODO: inspect stk */
if (ti_after.is_swizzled)
{
if (reference)
{
if (ti_after.swz.num_components == 1)
{
if (!slang_assembly_file_push_label (file, slang_asm_addr_push,
ti_after.swz.swizzle[0] * 4))
{
slang_assembly_typeinfo_destruct (&ti_after);
slang_assembly_typeinfo_destruct (&ti_before);
return 0;
}
if (!slang_assembly_file_push (file, slang_asm_addr_add))
{
slang_assembly_typeinfo_destruct (&ti_after);
slang_assembly_typeinfo_destruct (&ti_before);
return 0;
}
}
else
{
unsigned int i;
for (i = 0; i < ti_after.swz.num_components; i++)
stk->swizzle_mask |= 1 << ti_after.swz.swizzle[i];
}
}
else
{
if (!_slang_assemble_constructor_from_swizzle (file, &ti_after.swz,
&ti_after.spec, &ti_before.spec, info))
{
slang_assembly_typeinfo_destruct (&ti_after);
slang_assembly_typeinfo_destruct (&ti_before);
return 0;
}
}
}
else
{
if (reference)
{
/* TODO: struct field address */
}
else
{
/* TODO: struct field value */
}
}
slang_assembly_typeinfo_destruct (&ti_after);
slang_assembly_typeinfo_destruct (&ti_before);
}
break;
case slang_oper_postincrement:
if (!call_function_name_dummyint (file, "++", op->children, space, info))
return 0;
if (!dereference (file, op, space, info))
return 0;
break;
case slang_oper_postdecrement:
if (!call_function_name_dummyint (file, "--", op->children, space, info))
return 0;
if (!dereference (file, op, space, info))
return 0;
break;
default:
return 0;
}
return 1;
}
void xxx_first (slang_assembly_file *file)
{
slang_assembly_file_push (file, slang_asm_jump);
}
void xxx_prolog (slang_assembly_file *file, unsigned int addr)
{
file->code[0].param[0] = file->count;
slang_assembly_file_push_label (file, slang_asm_call, addr);
slang_assembly_file_push (file, slang_asm_exit);
}
/*
* Mesa 3-D graphics library
* Version: 6.3
*
* Copyright (C) 2005 Brian Paul All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
/**
* \file slang_assemble.c
* slang intermediate code assembler
* \author Michal Krol
*/
#include "imports.h"
#include "slang_utility.h"
#include "slang_assemble.h"
#include "slang_compile.h"
#include "slang_storage.h"
#include "slang_assemble_constructor.h"
#include "slang_assemble_typeinfo.h"
#include "slang_assemble_conditional.h"
#include "slang_assemble_assignment.h"
/* slang_assembly */
static void slang_assembly_construct (slang_assembly *assem)
{
assem->type = slang_asm_none;
}
static void slang_assembly_destruct (slang_assembly *assem)
{
}
/* slang_assembly_file */
void slang_assembly_file_construct (slang_assembly_file *file)
{
file->code = NULL;
file->count = 0;
}
void slang_assembly_file_destruct (slang_assembly_file *file)
{
unsigned int i;
for (i = 0; i < file->count; i++)
slang_assembly_destruct (file->code + i);
slang_alloc_free (file->code);
}
static int slang_assembly_file_push_new (slang_assembly_file *file)
{
file->code = (slang_assembly *) slang_alloc_realloc (file->code, file->count * sizeof (
slang_assembly), (file->count + 1) * sizeof (slang_assembly));
if (file->code != NULL)
{
slang_assembly_construct (file->code + file->count);
file->count++;
return 1;
}
return 0;
}
static int slang_assembly_file_push_general (slang_assembly_file *file, slang_assembly_type type,
GLfloat literal, GLuint label, GLuint size)
{
slang_assembly *assem;
if (!slang_assembly_file_push_new (file))
return 0;
assem = file->code + file->count - 1;
assem->type = type;
assem->literal = literal;
assem->param[0] = label;
assem->param[1] = size;
return 1;
}
int slang_assembly_file_push (slang_assembly_file *file, slang_assembly_type type)
{
return slang_assembly_file_push_general (file, type, (GLfloat) 0, 0, 0);
}
int slang_assembly_file_push_label (slang_assembly_file *file, slang_assembly_type type,
GLuint label)
{
return slang_assembly_file_push_general (file, type, (GLfloat) 0, label, 0);
}
int slang_assembly_file_push_label2 (slang_assembly_file *file, slang_assembly_type type,
GLuint label1, GLuint label2)
{
return slang_assembly_file_push_general (file, type, (GLfloat) 0, label1, label2);
}
int slang_assembly_file_push_literal (slang_assembly_file *file, slang_assembly_type type,
GLfloat literal)
{
return slang_assembly_file_push_general (file, type, literal, 0, 0);
}
/* utility functions */
static int sizeof_variable (slang_type_specifier *spec, slang_type_qualifier qual,
slang_operation *array_size, slang_assembly_name_space *space, unsigned int *size)
{
slang_storage_aggregate agg;
slang_storage_aggregate_construct (&agg);
if (!_slang_aggregate_variable (&agg, spec, array_size, space->funcs, space->structs))
{
slang_storage_aggregate_destruct (&agg);
return 0;
}
*size += _slang_sizeof_aggregate (&agg);
if (qual == slang_qual_out || qual == slang_qual_inout)
*size += 4;
slang_storage_aggregate_destruct (&agg);
return 1;
}
static int sizeof_variable2 (slang_variable *var, slang_assembly_name_space *space,
unsigned int *size)
{
var->address = *size;
if (var->type.qualifier == slang_qual_out || var->type.qualifier == slang_qual_inout)
var->address += 4;
return sizeof_variable (&var->type.specifier, var->type.qualifier, var->array_size, space,
size);
}
static int sizeof_variables (slang_variable_scope *vars, unsigned int start, unsigned int stop,
slang_assembly_name_space *space, unsigned int *size)
{
unsigned int i;
for (i = start; i < stop; i++)
if (!sizeof_variable2 (vars->variables + i, space, size))
return 0;
return 1;
}
static int collect_locals (slang_operation *op, slang_assembly_name_space *space,
unsigned int *size)
{
unsigned int i;
if (!sizeof_variables (op->locals, 0, op->locals->num_variables, space, size))
return 0;
for (i = 0; i < op->num_children; i++)
if (!collect_locals (op->children + i, space, size))
return 0;
return 1;
}
/* _slang_locate_function() */
slang_function *_slang_locate_function (const char *name, slang_operation *params,
unsigned int num_params, slang_assembly_name_space *space)
{
unsigned int i;
for (i = 0; i < space->funcs->num_functions; i++)
{
unsigned int j;
slang_function *f = space->funcs->functions + i;
if (slang_string_compare (name, f->header.name) != 0)
continue;
if (f->param_count != num_params)
continue;
for (j = 0; j < num_params; j++)
{
slang_assembly_typeinfo ti;
slang_assembly_typeinfo_construct (&ti);
if (!_slang_typeof_operation (params + j, space, &ti))
{
slang_assembly_typeinfo_destruct (&ti);
return 0;
}
if (!slang_type_specifier_equal (&ti.spec, &f->parameters->variables[j].type.specifier))
{
slang_assembly_typeinfo_destruct (&ti);
break;
}
slang_assembly_typeinfo_destruct (&ti);
/* "out" and "inout" formal parameter requires the actual parameter to be l-value */
if (!ti.can_be_referenced &&
(f->parameters->variables[j].type.qualifier == slang_qual_out ||
f->parameters->variables[j].type.qualifier == slang_qual_inout))
break;
}
if (j == num_params)
return f;
}
if (space->funcs->outer_scope != NULL)
{
slang_assembly_name_space my_space = *space;
my_space.funcs = space->funcs->outer_scope;
return _slang_locate_function (name, params, num_params, &my_space);
}
return NULL;
}
/* _slang_assemble_function() */
int _slang_assemble_function (slang_assembly_file *file, slang_function *fun,
slang_assembly_name_space *space)
{
unsigned int param_size, local_size;
unsigned int skip, cleanup;
slang_assembly_flow_control flow;
slang_assembly_local_info info;
slang_assembly_stack_info stk;
fun->address = file->count;
if (fun->body == NULL)
{
/* TODO: jump to the actual function body */
return 1;
}
/* calculate return value and parameters size */
param_size = 0;
if (fun->header.type.specifier.type != slang_spec_void)
if (!sizeof_variable (&fun->header.type.specifier, slang_qual_none, NULL, space,
&param_size))
return 0;
info.ret_size = param_size;
if (!sizeof_variables (fun->parameters, 0, fun->param_count, space, &param_size))
return 0;
/* calculate local variables size, take into account the four-byte return address and
temporaries for various tasks */
info.addr_tmp = param_size + 4;
info.swizzle_tmp = param_size + 4 + 4;
local_size = param_size + 4 + 4 + 16;
if (!sizeof_variables (fun->parameters, fun->param_count, fun->parameters->num_variables, space,
&local_size))
return 0;
if (!collect_locals (fun->body, space, &local_size))
return 0;
/* allocate local variable storage */
if (!slang_assembly_file_push_label (file, slang_asm_local_alloc, local_size - param_size - 4))
return 0;
/* mark a new frame for function variable storage */
if (!slang_assembly_file_push_label (file, slang_asm_enter, local_size))
return 0;
/* skip the cleanup jump */
skip = file->count;
if (!slang_assembly_file_push_new (file))
return 0;
file->code[skip].type = slang_asm_jump;
/* all "return" statements will be directed here */
flow.function_end = file->count;
cleanup = file->count;
if (!slang_assembly_file_push_new (file))
return 0;
file->code[cleanup].type = slang_asm_jump;
/* execute the function body */
file->code[skip].param[0] = file->count;
if (!_slang_assemble_operation (file, fun->body, 0, &flow, space, &info, &stk))
return 0;
/* this is the end of the function - restore the old function frame */
file->code[cleanup].param[0] = file->count;
if (!slang_assembly_file_push (file, slang_asm_leave))
return 0;
/* free local variable storage */
if (!slang_assembly_file_push_label (file, slang_asm_local_free, local_size - param_size - 4))
return 0;
/* jump out of the function */
if (!slang_assembly_file_push (file, slang_asm_return))
return 0;
return 1;
}
int _slang_cleanup_stack (slang_assembly_file *file, slang_operation *op, int ref,
slang_assembly_name_space *space)
{
slang_assembly_typeinfo ti;
unsigned int size;
slang_assembly_typeinfo_construct (&ti);
if (!_slang_typeof_operation (op, space, &ti))
{
slang_assembly_typeinfo_destruct (&ti);
return 0;
}
if (ti.spec.type == slang_spec_void)
size = 0;
else if (ref)
size = 4;
else
{
size = 0;
if (!sizeof_variable (&ti.spec, slang_qual_none, NULL, space, &size))
{
slang_assembly_typeinfo_destruct (&ti);
return 0;
}
}
slang_assembly_typeinfo_destruct (&ti);
if (size != 0)
{
if (!slang_assembly_file_push_label (file, slang_asm_local_free, size))
return 0;
}
return 1;
}
/* _slang_assemble_operation() */
/* XXX: general swizzle! */
static int dereference_aggregate (slang_assembly_file *file, const slang_storage_aggregate *agg,
unsigned int index, unsigned int *size, slang_assembly_local_info *info)
{
unsigned int i;
for (i = agg->count; i > 0; i--)
{
const slang_storage_array *arr = agg->arrays + i - 1;
unsigned int j;
for (j = arr->length; j > 0; j--)
{
if (arr->type == slang_stor_aggregate)
{
if (!dereference_aggregate (file, arr->aggregate, index, size, info))
return 0;
}
else
{
*size -= 4;
if (!slang_assembly_file_push_label2 (file, slang_asm_local_addr, info->addr_tmp,
4))
return 0;
if (!slang_assembly_file_push (file, slang_asm_addr_deref))
return 0;
if (!slang_assembly_file_push_label (file, slang_asm_addr_push, *size))
return 0;
if (!slang_assembly_file_push (file, slang_asm_addr_add))
return 0;
switch (arr->type)
{
case slang_stor_bool:
if (!slang_assembly_file_push (file, slang_asm_bool_deref))
return 0;
break;
case slang_stor_int:
if (!slang_assembly_file_push (file, slang_asm_int_deref))
return 0;
break;
case slang_stor_float:
if (!slang_assembly_file_push (file, slang_asm_float_deref))
return 0;
break;
}
index += 4;
}
}
}
return 1;
}
/* XXX: general swizzle! */
int dereference (slang_assembly_file *file, slang_operation *op,
slang_assembly_name_space *space, slang_assembly_local_info *info)
{
slang_assembly_typeinfo ti;
int result;
slang_storage_aggregate agg;
unsigned int size;
slang_assembly_typeinfo_construct (&ti);
if (!_slang_typeof_operation (op, space, &ti))
{
slang_assembly_typeinfo_destruct (&ti);
return 0;
}
slang_storage_aggregate_construct (&agg);
if (!_slang_aggregate_variable (&agg, &ti.spec, NULL, space->funcs, space->structs))
{
slang_storage_aggregate_destruct (&agg);
slang_assembly_typeinfo_destruct (&ti);
return 0;
}
size = _slang_sizeof_aggregate (&agg);
result = dereference_aggregate (file, &agg, 0, &size, info);
slang_storage_aggregate_destruct (&agg);
slang_assembly_typeinfo_destruct (&ti);
return result;
}
static int call_function (slang_assembly_file *file, slang_function *fun, slang_operation *params,
unsigned int param_count, int assignment, slang_assembly_name_space *space,
slang_assembly_local_info *info)
{
unsigned int i;
slang_assembly_stack_info stk;
/* make room for the return value, if any */
if (fun->header.type.specifier.type != slang_spec_void)
{
unsigned int ret_size = 0;
if (!sizeof_variable (&fun->header.type.specifier, slang_qual_none, NULL, space, &ret_size))
return 0;
if (!slang_assembly_file_push_label (file, slang_asm_local_alloc, ret_size))
return 0;
}
/* push the actual parameters on the stack */
for (i = 0; i < param_count; i++)
{
slang_assembly_flow_control flow;
if (fun->parameters->variables[i].type.qualifier == slang_qual_inout ||
fun->parameters->variables[i].type.qualifier == slang_qual_out)
{
if (!slang_assembly_file_push_label2 (file, slang_asm_local_addr, info->addr_tmp, 4))
return 0;
/* TODO: optimize the "out" parameter case */
/* TODO: inspect stk */
if (!_slang_assemble_operation (file, params + i, 1, &flow, space, info, &stk))
return 0;
if (!slang_assembly_file_push (file, slang_asm_addr_copy))
return 0;
if (!slang_assembly_file_push (file, slang_asm_addr_deref))
return 0;
if (i == 0 && assignment)
{
if (!slang_assembly_file_push_label2 (file, slang_asm_local_addr, info->addr_tmp,
4))
return 0;
if (!slang_assembly_file_push (file, slang_asm_addr_deref))
return 0;
}
if (!dereference (file, params, space, info))
return 0;
}
else
{
/* TODO: for "out" and "inout" parameters also push the address (first) */
/* TODO: optimize the "out" parameter case */
/* TODO: inspect stk */
if (!_slang_assemble_operation (file, params + i, 0, &flow, space, info, &stk))
return 0;
}
}
/* call the function */
if (!slang_assembly_file_push_label (file, slang_asm_call, fun->address))
return 0;
/* pop the parameters from the stack */
for (i = param_count; i > 0; i--)
{
unsigned int j = i - 1;
if (fun->parameters->variables[j].type.qualifier == slang_qual_inout ||
fun->parameters->variables[j].type.qualifier == slang_qual_out)
{
if (!_slang_assemble_assignment (file, params + j, space, info))
return 0;
if (!slang_assembly_file_push_label (file, slang_asm_local_free, 4))
return 0;
}
else
{
if (!_slang_cleanup_stack (file, params + j, 0, space))
return 0;
}
}
return 1;
}
int call_function_name (slang_assembly_file *file, const char *name, slang_operation *params,
unsigned int param_count, int assignment, slang_assembly_name_space *space,
slang_assembly_local_info *info)
{
slang_function *fun = _slang_locate_function (name, params, param_count, space);
if (fun == NULL)
return 0;
return call_function (file, fun, params, param_count, assignment, space, info);
}
static int call_function_name_dummyint (slang_assembly_file *file, const char *name,
slang_operation *params, slang_assembly_name_space *space, slang_assembly_local_info *info)
{
slang_operation p2[2];
int result;
p2[0] = *params;
if (!slang_operation_construct_a (p2 + 1))
return 0;
p2[1].type = slang_oper_literal_int;
result = call_function_name (file, name, p2, 2, 0, space, info);
slang_operation_destruct (p2 + 1);
return result;
}
static int call_asm_instruction (slang_assembly_file *file, const char *name)
{
const struct
{
const char *name;
slang_assembly_type code1, code2;
} inst[] = {
{ "float_to_int", slang_asm_float_to_int, slang_asm_int_copy },
{ "int_to_float", slang_asm_int_to_float, slang_asm_float_copy },
{ "float_copy", slang_asm_float_copy, slang_asm_none },
{ "int_copy", slang_asm_int_copy, slang_asm_none },
{ "bool_copy", slang_asm_bool_copy, slang_asm_none },
{ "float_add", slang_asm_float_add, slang_asm_float_copy },
{ "float_multiply", slang_asm_float_multiply, slang_asm_float_copy },
{ "float_divide", slang_asm_float_divide, slang_asm_float_copy },
{ "float_negate", slang_asm_float_negate, slang_asm_float_copy },
{ "float_less", slang_asm_float_less, slang_asm_bool_copy },
{ "float_equal", slang_asm_float_equal, slang_asm_bool_copy },
{ NULL, slang_asm_none, slang_asm_none }
};
unsigned int i;
for (i = 0; inst[i].name != NULL; i++)
if (slang_string_compare (name, inst[i].name) == 0)
break;
if (inst[i].name == NULL)
return 0;
if (!slang_assembly_file_push_label2 (file, inst[i].code1, 4, 0))
return 0;
if (inst[i].code2 != slang_asm_none)
if (!slang_assembly_file_push_label2 (file, inst[i].code2, 4, 0))
return 0;
/* clean-up the stack from the remaining dst address */
if (!slang_assembly_file_push_label (file, slang_asm_local_free, 4))
return 0;
return 1;
}
/* XXX: general swizzle! */
static int equality_aggregate (slang_assembly_file *file, const slang_storage_aggregate *agg,
unsigned int *index, unsigned int size, slang_assembly_local_info *info, unsigned int z_label)
{
unsigned int i;
for (i = 0; i < agg->count; i++)
{
const slang_storage_array *arr = agg->arrays + i;
unsigned int j;
for (j = 0; j < arr->length; j++)
{
if (arr->type == slang_stor_aggregate)
{
if (!equality_aggregate (file, arr->aggregate, index, size, info, z_label))
return 0;
}
else
{
if (!slang_assembly_file_push_label2 (file, slang_asm_float_equal, size + *index,
*index))
return 0;
*index += 4;
if (!slang_assembly_file_push_label (file, slang_asm_jump_if_zero, z_label))
return 0;
}
}
}
return 1;
}
/* XXX: general swizzle! */
static int equality (slang_assembly_file *file, slang_operation *op,
slang_assembly_name_space *space, slang_assembly_local_info *info, int equal)
{
slang_assembly_typeinfo ti;
int result;
slang_storage_aggregate agg;
unsigned int index, size;
unsigned int skip_jump, true_label, true_jump, false_label, false_jump;
/* get type of operation */
slang_assembly_typeinfo_construct (&ti);
if (!_slang_typeof_operation (op, space, &ti))
{
slang_assembly_typeinfo_destruct (&ti);
return 0;
}
/* convert it to an aggregate */
slang_storage_aggregate_construct (&agg);
if (!(result = _slang_aggregate_variable (&agg, &ti.spec, NULL, space->funcs, space->structs)))
goto end;
/* compute the size of the agregate - there are two such aggregates on the stack */
size = _slang_sizeof_aggregate (&agg);
/* jump to the actual data-comparison code */
skip_jump = file->count;
if (!(result = slang_assembly_file_push (file, slang_asm_jump)))
goto end;
/* pop off the stack the compared data and push 1 */
true_label = file->count;
if (!(result = slang_assembly_file_push_label (file, slang_asm_local_free, size * 2)))
goto end;
if (!(result = slang_assembly_file_push_literal (file, slang_asm_bool_push, 1.0f)))
goto end;
true_jump = file->count;
if (!(result = slang_assembly_file_push (file, slang_asm_jump)))
goto end;
false_label = file->count;
if (!(result = slang_assembly_file_push_label (file, slang_asm_local_free, size * 2)))
goto end;
if (!(result = slang_assembly_file_push_literal (file, slang_asm_bool_push, 0.0f)))
goto end;
false_jump = file->count;
if (!(result = slang_assembly_file_push (file, slang_asm_jump)))
goto end;
file->code[skip_jump].param[0] = file->count;
/* compare the data on stack, it will eventually jump either to true or false label */
index = 0;
if (!(result = equality_aggregate (file, &agg, &index, size, info,
equal ? false_label : true_label)))
goto end;
if (!(result = slang_assembly_file_push_label (file, slang_asm_jump,
equal ? true_label : false_label)))
goto end;
file->code[true_jump].param[0] = file->count;
file->code[false_jump].param[0] = file->count;
result = 1;
end:
slang_storage_aggregate_destruct (&agg);
slang_assembly_typeinfo_destruct (&ti);
return result;
}
int _slang_assemble_operation (slang_assembly_file *file, slang_operation *op, int reference,
slang_assembly_flow_control *flow, slang_assembly_name_space *space,
slang_assembly_local_info *info, slang_assembly_stack_info *stk)
{
unsigned int assem;
stk->swizzle_mask = 0;
assem = file->count;
if (!slang_assembly_file_push_new (file))
return 0;
switch (op->type)
{
case slang_oper_block_no_new_scope:
case slang_oper_block_new_scope:
{
unsigned int i;
for (i = 0; i < op->num_children; i++)
{
slang_assembly_stack_info stk;
if (!_slang_assemble_operation (file, op->children + i, 0, flow, space, info, &stk))
return 0;
/* TODO: pass-in stk to cleanup */
if (!_slang_cleanup_stack (file, op->children + i, 0, space))
return 0;
}
}
break;
case slang_oper_variable_decl:
{
unsigned int i;
for (i = 0; i < op->num_children; i++)
{
/* TODO: perform initialization of op->children[i] */
/* TODO: clean-up stack */
}
}
break;
case slang_oper_asm:
{
unsigned int i;
for (i = 0; i < op->num_children; i++)
{
slang_assembly_stack_info stk;
if (!_slang_assemble_operation (file, op->children + i, i == 0, flow, space, info,
&stk))
return 0;
/* TODO: inspect stk */
}
if (!call_asm_instruction (file, op->identifier))
return 0;
}
break;
case slang_oper_break:
file->code[assem].type = slang_asm_jump;
file->code[assem].param[0] = flow->loop_end;
break;
case slang_oper_continue:
file->code[assem].type = slang_asm_jump;
file->code[assem].param[0] = flow->loop_start;
break;
case slang_oper_discard:
file->code[assem].type = slang_asm_discard;
if (!slang_assembly_file_push (file, slang_asm_exit))
return 0;
break;
case slang_oper_return:
if (info->ret_size != 0)
{
slang_assembly_stack_info stk;
if (!slang_assembly_file_push_label2 (file, slang_asm_local_addr, 0, info->ret_size))
return 0;
if (!_slang_assemble_operation (file, op->children, 0, flow, space, info, &stk))
return 0;
/* TODO: inspect stk */
if (!_slang_assemble_assignment (file, op->children, space, info))
return 0;
if (!slang_assembly_file_push_label (file, slang_asm_local_free, 4))
return 0;
}
if (!slang_assembly_file_push_label (file, slang_asm_jump, flow->function_end))
return 0;
break;
case slang_oper_expression:
{
slang_assembly_stack_info stk;
if (!_slang_assemble_operation (file, op->children, reference, flow, space, info, &stk))
return 0;
/* TODO: inspect stk */
}
break;
case slang_oper_if:
if (!_slang_assemble_if (file, op, flow, space, info))
return 0;
break;
case slang_oper_while:
if (!_slang_assemble_while (file, op, flow, space, info))
return 0;
break;
case slang_oper_do:
if (!_slang_assemble_do (file, op, flow, space, info))
return 0;
break;
case slang_oper_for:
if (!_slang_assemble_for (file, op, flow, space, info))
return 0;
break;
case slang_oper_void:
break;
case slang_oper_literal_bool:
file->code[assem].type = slang_asm_bool_push;
file->code[assem].literal = op->literal;
break;
case slang_oper_literal_int:
file->code[assem].type = slang_asm_int_push;
file->code[assem].literal = op->literal;
break;
case slang_oper_literal_float:
file->code[assem].type = slang_asm_float_push;
file->code[assem].literal = op->literal;
break;
case slang_oper_identifier:
{
slang_variable *var;
unsigned int size;
var = _slang_locate_variable (op->locals, op->identifier, 1);
if (var == NULL)
return 0;
size = 0;
if (!sizeof_variable (&var->type.specifier, slang_qual_none, var->array_size, space,
&size))
return 0;
if (var->initializer != NULL)
{
assert (!"var->initializer, oper_identifier");
}
else
{
if (!reference)
{
if (!slang_assembly_file_push_label2 (file, slang_asm_local_addr,
info->addr_tmp, 4))
return 0;
}
/* XXX: globals! */
if (!slang_assembly_file_push_label2 (file, slang_asm_local_addr, var->address,
size))
return 0;
if (!reference)
{
if (!slang_assembly_file_push (file, slang_asm_addr_copy))
return 0;
if (!slang_assembly_file_push_label (file, slang_asm_local_free, 4))
return 0;
if (!dereference (file, op, space, info))
return 0;
}
}
}
break;
case slang_oper_sequence:
{
slang_assembly_stack_info stk;
if (!_slang_assemble_operation (file, op->children, 0, flow, space, info, &stk))
return 0;
/* TODO: pass-in stk to cleanup */
if (!_slang_cleanup_stack (file, op->children, 0, space))
return 0;
if (!_slang_assemble_operation (file, op->children + 1, 0, flow, space, info,
&stk))
return 0;
/* TODO: inspect stk */
}
break;
case slang_oper_assign:
if (!_slang_assemble_assign (file, op, "=", reference, space, info))
return 0;
break;
case slang_oper_addassign:
if (!_slang_assemble_assign (file, op, "+=", reference, space, info))
return 0;
break;
case slang_oper_subassign:
if (!_slang_assemble_assign (file, op, "-=", reference, space, info))
return 0;
break;
case slang_oper_mulassign:
if (!_slang_assemble_assign (file, op, "*=", reference, space, info))
return 0;
break;
/*case slang_oper_modassign:*/
/*case slang_oper_lshassign:*/
/*case slang_oper_rshassign:*/
/*case slang_oper_orassign:*/
/*case slang_oper_xorassign:*/
/*case slang_oper_andassign:*/
case slang_oper_divassign:
if (!_slang_assemble_assign (file, op, "/=", reference, space, info))
return 0;
break;
case slang_oper_select:
if (!_slang_assemble_select (file, op, flow, space, info))
return 0;
break;
case slang_oper_logicalor:
if (!_slang_assemble_logicalor (file, op, flow, space, info))
return 0;
break;
case slang_oper_logicaland:
if (!_slang_assemble_logicaland (file, op, flow, space, info))
return 0;
break;
case slang_oper_logicalxor:
if (!call_function_name (file, "^^", op->children, 2, 0, space, info))
return 0;
break;
/*case slang_oper_bitor:*/
/*case slang_oper_bitxor:*/
/*case slang_oper_bitand:*/
case slang_oper_less:
if (!call_function_name (file, "<", op->children, 2, 0, space, info))
return 0;
break;
case slang_oper_greater:
if (!call_function_name (file, ">", op->children, 2, 0, space, info))
return 0;
break;
case slang_oper_lessequal:
if (!call_function_name (file, "<=", op->children, 2, 0, space, info))
return 0;
break;
case slang_oper_greaterequal:
if (!call_function_name (file, ">=", op->children, 2, 0, space, info))
return 0;
break;
/*case slang_oper_lshift:*/
/*case slang_oper_rshift:*/
case slang_oper_add:
if (!call_function_name (file, "+", op->children, 2, 0, space, info))
return 0;
break;
case slang_oper_subtract:
if (!call_function_name (file, "-", op->children, 2, 0, space, info))
return 0;
break;
case slang_oper_multiply:
if (!call_function_name (file, "*", op->children, 2, 0, space, info))
return 0;
break;
/*case slang_oper_modulus:*/
case slang_oper_divide:
if (!call_function_name (file, "/", op->children, 2, 0, space, info))
return 0;
break;
case slang_oper_equal:
{
slang_assembly_stack_info stk;
if (!_slang_assemble_operation (file, op->children, 0, flow, space, info, &stk))
return 0;
/* TODO: inspect stk */
if (!_slang_assemble_operation (file, op->children + 1, 0, flow, space, info, &stk))
return 0;
/* TODO: inspect stk */
if (!equality (file, op->children, space, info, 1))
return 0;
}
break;
case slang_oper_notequal:
{
slang_assembly_stack_info stk;
if (!_slang_assemble_operation (file, op->children, 0, flow, space, info, &stk))
return 0;
/* TODO: inspect stk */
if (!_slang_assemble_operation (file, op->children + 1, 0, flow, space, info, &stk))
return 0;
/* TODO: inspect stk */
if (!equality (file, op->children, space, info, 0))
return 0;
}
break;
case slang_oper_preincrement:
if (!_slang_assemble_assign (file, op, "++", reference, space, info))
return 0;
break;
case slang_oper_predecrement:
if (!_slang_assemble_assign (file, op, "--", reference, space, info))
return 0;
break;
case slang_oper_plus:
if (!call_function_name (file, "+", op->children, 1, 0, space, info))
return 0;
break;
case slang_oper_minus:
if (!call_function_name (file, "-", op->children, 1, 0, space, info))
return 0;
break;
/*case slang_oper_complement:*/
case slang_oper_not:
if (!call_function_name (file, "!", op->children, 1, 0, space, info))
return 0;
break;
case slang_oper_subscript:
{
slang_assembly_stack_info _stk;
slang_assembly_typeinfo ti_arr, ti_elem;
unsigned int arr_size = 0, elem_size = 0;
if (!_slang_assemble_operation (file, op->children, reference, flow, space, info,
&_stk))
return 0;
if (!_slang_assemble_operation (file, op->children + 1, 0, flow, space, info, &_stk))
return 0;
slang_assembly_typeinfo_construct (&ti_arr);
if (!_slang_typeof_operation (op->children, space, &ti_arr))
{
slang_assembly_typeinfo_destruct (&ti_arr);
return 0;
}
if (!sizeof_variable (&ti_arr.spec, slang_qual_none, NULL, space, &arr_size))
{
slang_assembly_typeinfo_destruct (&ti_arr);
return 0;
}
slang_assembly_typeinfo_construct (&ti_elem);
if (!_slang_typeof_operation (op, space, &ti_elem))
{
slang_assembly_typeinfo_destruct (&ti_arr);
slang_assembly_typeinfo_destruct (&ti_elem);
return 0;
}
if (!sizeof_variable (&ti_elem.spec, slang_qual_none, NULL, space, &elem_size))
{
slang_assembly_typeinfo_destruct (&ti_arr);
slang_assembly_typeinfo_destruct (&ti_elem);
return 0;
}
if (!slang_assembly_file_push (file, slang_asm_int_to_addr))
{
slang_assembly_typeinfo_destruct (&ti_arr);
slang_assembly_typeinfo_destruct (&ti_elem);
return 0;
}
if (!slang_assembly_file_push_label (file, slang_asm_addr_push, elem_size))
{
slang_assembly_typeinfo_destruct (&ti_arr);
slang_assembly_typeinfo_destruct (&ti_elem);
return 0;
}
if (!slang_assembly_file_push (file, slang_asm_addr_multiply))
{
slang_assembly_typeinfo_destruct (&ti_arr);
slang_assembly_typeinfo_destruct (&ti_elem);
return 0;
}
if (reference)
{
if (!slang_assembly_file_push (file, slang_asm_addr_add))
{
slang_assembly_typeinfo_destruct (&ti_arr);
slang_assembly_typeinfo_destruct (&ti_elem);
return 0;
}
}
else
{
unsigned int i;
for (i = 0; i < elem_size; i += 4)
{
if (!slang_assembly_file_push_label2 (file, slang_asm_float_move,
arr_size - elem_size + i + 4, i + 4))
{
slang_assembly_typeinfo_destruct (&ti_arr);
slang_assembly_typeinfo_destruct (&ti_elem);
return 0;
}
}
if (!slang_assembly_file_push_label (file, slang_asm_local_free, 4))
{
slang_assembly_typeinfo_destruct (&ti_arr);
slang_assembly_typeinfo_destruct (&ti_elem);
return 0;
}
if (!slang_assembly_file_push_label (file, slang_asm_local_free,
arr_size - elem_size))
{
slang_assembly_typeinfo_destruct (&ti_arr);
slang_assembly_typeinfo_destruct (&ti_elem);
return 0;
}
}
slang_assembly_typeinfo_destruct (&ti_arr);
slang_assembly_typeinfo_destruct (&ti_elem);
}
break;
case slang_oper_call:
{
slang_function *fun = _slang_locate_function (op->identifier, op->children,
op->num_children, space);
if (fun == NULL)
{
if (!_slang_assemble_constructor (file, op, flow, space, info))
return 0;
}
else
{
if (!call_function (file, fun, op->children, op->num_children, 0, space, info))
return 0;
}
}
break;
case slang_oper_field:
{
slang_assembly_typeinfo ti_after, ti_before;
slang_assembly_stack_info _stk;
slang_assembly_typeinfo_construct (&ti_after);
if (!_slang_typeof_operation (op, space, &ti_after))
{
slang_assembly_typeinfo_destruct (&ti_after);
return 0;
}
slang_assembly_typeinfo_construct (&ti_before);
if (!_slang_typeof_operation (op->children, space, &ti_before))
{
slang_assembly_typeinfo_destruct (&ti_after);
slang_assembly_typeinfo_destruct (&ti_before);
return 0;
}
if (!reference && ti_after.is_swizzled)
{
if (!slang_assembly_file_push_label2 (file, slang_asm_local_addr,
info->swizzle_tmp, 16))
{
slang_assembly_typeinfo_destruct (&ti_after);
slang_assembly_typeinfo_destruct (&ti_before);
return 0;
}
}
if (!_slang_assemble_operation (file, op->children, reference, flow, space, info,
&_stk))
{
slang_assembly_typeinfo_destruct (&ti_after);
slang_assembly_typeinfo_destruct (&ti_before);
return 0;
}
/* TODO: inspect stk */
if (ti_after.is_swizzled)
{
if (reference)
{
if (ti_after.swz.num_components == 1)
{
if (!slang_assembly_file_push_label (file, slang_asm_addr_push,
ti_after.swz.swizzle[0] * 4))
{
slang_assembly_typeinfo_destruct (&ti_after);
slang_assembly_typeinfo_destruct (&ti_before);
return 0;
}
if (!slang_assembly_file_push (file, slang_asm_addr_add))
{
slang_assembly_typeinfo_destruct (&ti_after);
slang_assembly_typeinfo_destruct (&ti_before);
return 0;
}
}
else
{
unsigned int i;
for (i = 0; i < ti_after.swz.num_components; i++)
stk->swizzle_mask |= 1 << ti_after.swz.swizzle[i];
}
}
else
{
if (!_slang_assemble_constructor_from_swizzle (file, &ti_after.swz,
&ti_after.spec, &ti_before.spec, info))
{
slang_assembly_typeinfo_destruct (&ti_after);
slang_assembly_typeinfo_destruct (&ti_before);
return 0;
}
}
}
else
{
if (reference)
{
/* TODO: struct field address */
}
else
{
/* TODO: struct field value */
}
}
slang_assembly_typeinfo_destruct (&ti_after);
slang_assembly_typeinfo_destruct (&ti_before);
}
break;
case slang_oper_postincrement:
if (!call_function_name_dummyint (file, "++", op->children, space, info))
return 0;
if (!dereference (file, op, space, info))
return 0;
break;
case slang_oper_postdecrement:
if (!call_function_name_dummyint (file, "--", op->children, space, info))
return 0;
if (!dereference (file, op, space, info))
return 0;
break;
default:
return 0;
}
return 1;
}
void xxx_first (slang_assembly_file *file)
{
slang_assembly_file_push (file, slang_asm_jump);
}
void xxx_prolog (slang_assembly_file *file, unsigned int addr)
{
file->code[0].param[0] = file->count;
slang_assembly_file_push_label (file, slang_asm_call, addr);
slang_assembly_file_push (file, slang_asm_exit);
}
/*
* Mesa 3-D graphics library
* Version: 6.3
*
* Copyright (C) 2005 Brian Paul All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#if !defined SLANG_ASSEMBLE_H
#define SLANG_ASSEMBLE_H
#include "slang_compile.h"
#if defined __cplusplus
extern "C" {
#endif
typedef enum slang_assembly_type_
{
/* core */
slang_asm_none,
slang_asm_float_copy,
slang_asm_float_move,
slang_asm_float_push,
slang_asm_float_deref,
slang_asm_float_add,
slang_asm_float_multiply,
slang_asm_float_divide,
slang_asm_float_negate,
slang_asm_float_less,
slang_asm_float_equal,
slang_asm_float_to_int,
slang_asm_int_copy,
slang_asm_int_move,
slang_asm_int_push,
slang_asm_int_deref,
slang_asm_int_to_float,
slang_asm_int_to_addr,
slang_asm_bool_copy,
slang_asm_bool_move,
slang_asm_bool_push,
slang_asm_bool_deref,
slang_asm_addr_copy,
slang_asm_addr_push,
slang_asm_addr_deref,
slang_asm_addr_add,
slang_asm_addr_multiply,
slang_asm_jump,
slang_asm_jump_if_zero,
slang_asm_enter,
slang_asm_leave,
slang_asm_local_alloc,
slang_asm_local_free,
slang_asm_local_addr,
slang_asm_call,
slang_asm_return,
slang_asm_discard,
slang_asm_exit,
slang_asm__last
} slang_assembly_type;
typedef struct slang_assembly_
{
slang_assembly_type type;
GLfloat literal;
GLuint param[2];
} slang_assembly;
typedef struct slang_assembly_file_
{
slang_assembly *code;
unsigned int count;
} slang_assembly_file;
void slang_assembly_file_construct (slang_assembly_file *);
void slang_assembly_file_destruct (slang_assembly_file *);
int slang_assembly_file_push (slang_assembly_file *, slang_assembly_type);
int slang_assembly_file_push_label (slang_assembly_file *, slang_assembly_type, GLuint);
int slang_assembly_file_push_label2 (slang_assembly_file *, slang_assembly_type, GLuint, GLuint);
int slang_assembly_file_push_literal (slang_assembly_file *, slang_assembly_type, GLfloat);
typedef struct slang_assembly_flow_control_
{
unsigned int loop_start; /* for "continue" statement */
unsigned int loop_end; /* for "break" statement */
unsigned int function_end; /* for "return" statement */
} slang_assembly_flow_control;
typedef struct slang_assembly_name_space_
{
struct slang_function_scope_ *funcs;
struct slang_struct_scope_ *structs;
struct slang_variable_scope_ *vars;
} slang_assembly_name_space;
slang_function *_slang_locate_function (const char *name, slang_operation *params,
unsigned int num_params, slang_assembly_name_space *space);
int _slang_assemble_function (slang_assembly_file *, struct slang_function_ *,
slang_assembly_name_space *);
typedef struct slang_assembly_stack_info_
{
unsigned int swizzle_mask;
} slang_assembly_stack_info;
int _slang_cleanup_stack (slang_assembly_file *, slang_operation *, int ref,
slang_assembly_name_space *);
typedef struct slang_assembly_local_info_
{
unsigned int ret_size;
unsigned int addr_tmp;
unsigned int swizzle_tmp;
} slang_assembly_local_info;
int _slang_assemble_operation (slang_assembly_file *, struct slang_operation_ *, int reference,
slang_assembly_flow_control *, slang_assembly_name_space *, slang_assembly_local_info *,
slang_assembly_stack_info *);
void xxx_first (slang_assembly_file *);
void xxx_prolog (slang_assembly_file *, unsigned int);
#ifdef __cplusplus
}
#endif
#endif
/*
* Mesa 3-D graphics library
* Version: 6.3
*
* Copyright (C) 2005 Brian Paul All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#if !defined SLANG_ASSEMBLE_H
#define SLANG_ASSEMBLE_H
#include "slang_compile.h"
#if defined __cplusplus
extern "C" {
#endif
typedef enum slang_assembly_type_
{
/* core */
slang_asm_none,
slang_asm_float_copy,
slang_asm_float_move,
slang_asm_float_push,
slang_asm_float_deref,
slang_asm_float_add,
slang_asm_float_multiply,
slang_asm_float_divide,
slang_asm_float_negate,
slang_asm_float_less,
slang_asm_float_equal,
slang_asm_float_to_int,
slang_asm_int_copy,
slang_asm_int_move,
slang_asm_int_push,
slang_asm_int_deref,
slang_asm_int_to_float,
slang_asm_int_to_addr,
slang_asm_bool_copy,
slang_asm_bool_move,
slang_asm_bool_push,
slang_asm_bool_deref,
slang_asm_addr_copy,
slang_asm_addr_push,
slang_asm_addr_deref,
slang_asm_addr_add,
slang_asm_addr_multiply,
slang_asm_jump,
slang_asm_jump_if_zero,
slang_asm_enter,
slang_asm_leave,
slang_asm_local_alloc,
slang_asm_local_free,
slang_asm_local_addr,
slang_asm_call,
slang_asm_return,
slang_asm_discard,
slang_asm_exit,
slang_asm__last
} slang_assembly_type;
typedef struct slang_assembly_
{
slang_assembly_type type;
GLfloat literal;
GLuint param[2];
} slang_assembly;
typedef struct slang_assembly_file_
{
slang_assembly *code;
unsigned int count;
} slang_assembly_file;
void slang_assembly_file_construct (slang_assembly_file *);
void slang_assembly_file_destruct (slang_assembly_file *);
int slang_assembly_file_push (slang_assembly_file *, slang_assembly_type);
int slang_assembly_file_push_label (slang_assembly_file *, slang_assembly_type, GLuint);
int slang_assembly_file_push_label2 (slang_assembly_file *, slang_assembly_type, GLuint, GLuint);
int slang_assembly_file_push_literal (slang_assembly_file *, slang_assembly_type, GLfloat);
typedef struct slang_assembly_flow_control_
{
unsigned int loop_start; /* for "continue" statement */
unsigned int loop_end; /* for "break" statement */
unsigned int function_end; /* for "return" statement */
} slang_assembly_flow_control;
typedef struct slang_assembly_name_space_
{
struct slang_function_scope_ *funcs;
struct slang_struct_scope_ *structs;
struct slang_variable_scope_ *vars;
} slang_assembly_name_space;
slang_function *_slang_locate_function (const char *name, slang_operation *params,
unsigned int num_params, slang_assembly_name_space *space);
int _slang_assemble_function (slang_assembly_file *, struct slang_function_ *,
slang_assembly_name_space *);
typedef struct slang_assembly_stack_info_
{
unsigned int swizzle_mask;
} slang_assembly_stack_info;
int _slang_cleanup_stack (slang_assembly_file *, slang_operation *, int ref,
slang_assembly_name_space *);
typedef struct slang_assembly_local_info_
{
unsigned int ret_size;
unsigned int addr_tmp;
unsigned int swizzle_tmp;
} slang_assembly_local_info;
int _slang_assemble_operation (slang_assembly_file *, struct slang_operation_ *, int reference,
slang_assembly_flow_control *, slang_assembly_name_space *, slang_assembly_local_info *,
slang_assembly_stack_info *);
void xxx_first (slang_assembly_file *);
void xxx_prolog (slang_assembly_file *, unsigned int);
#ifdef __cplusplus
}
#endif
#endif
/*
* Mesa 3-D graphics library
* Version: 6.3
*
* Copyright (C) 2005 Brian Paul All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
/**
* \file slang_assemble_assignment.c
* slang assignment expressions assembler
* \author Michal Krol
*/
#include "imports.h"
#include "slang_assemble_assignment.h"
#include "slang_assemble_typeinfo.h"
#include "slang_storage.h"
#include "slang_utility.h"
/*
_slang_assemble_assignment()
copies values on the stack (<component 0> to <component N-1>) to a memory
location pointed by <addr of variable>;
in:
+------------------+
| addr of variable |
+------------------+
| component N-1 |
| ... |
| component 0 |
+------------------+
out:
+------------------+
| addr of variable |
+------------------+
*/
/* TODO: add support for swizzle mask */
static int assign_aggregate (slang_assembly_file *file, const slang_storage_aggregate *agg,
unsigned int *index, unsigned int size, slang_assembly_local_info *info)
{
unsigned int i;
for (i = 0; i < agg->count; i++)
{
const slang_storage_array *arr = agg->arrays + i;
unsigned int j;
for (j = 0; j < arr->length; j++)
{
if (arr->type == slang_stor_aggregate)
{
if (!assign_aggregate (file, arr->aggregate, index, size, info))
return 0;
}
else
{
slang_assembly_type ty;
switch (arr->type)
{
case slang_stor_bool:
ty = slang_asm_bool_copy;
break;
case slang_stor_int:
ty = slang_asm_int_copy;
break;
case slang_stor_float:
ty = slang_asm_float_copy;
break;
default:
break;
}
if (!slang_assembly_file_push_label2 (file, ty, size - *index, *index))
return 0;
*index += 4;
}
}
}
return 1;
}
int _slang_assemble_assignment (slang_assembly_file *file, slang_operation *op,
slang_assembly_name_space *space, slang_assembly_local_info *info)
{
slang_assembly_typeinfo ti;
int result;
slang_storage_aggregate agg;
unsigned int index, size;
slang_assembly_typeinfo_construct (&ti);
if (!_slang_typeof_operation (op, space, &ti))
{
slang_assembly_typeinfo_destruct (&ti);
return 0;
}
slang_storage_aggregate_construct (&agg);
if (!_slang_aggregate_variable (&agg, &ti.spec, NULL, space->funcs, space->structs))
{
slang_storage_aggregate_destruct (&agg);
slang_assembly_typeinfo_destruct (&ti);
return 0;
}
index = 0;
size = _slang_sizeof_aggregate (&agg);
result = assign_aggregate (file, &agg, &index, size, info);
slang_storage_aggregate_destruct (&agg);
slang_assembly_typeinfo_destruct (&ti);
return result;
}
/*
_slang_assemble_assign()
performs unary (pre ++ and --) or binary (=, +=, -=, *=, /=) assignment on the operation's
children
*/
int dereference (slang_assembly_file *file, slang_operation *op,
slang_assembly_name_space *space, slang_assembly_local_info *info);
int call_function_name (slang_assembly_file *file, const char *name, slang_operation *params,
unsigned int param_count, int assignment, slang_assembly_name_space *space,
slang_assembly_local_info *info);
int _slang_assemble_assign (slang_assembly_file *file, slang_operation *op, const char *oper,
int ref, slang_assembly_name_space *space, slang_assembly_local_info *info)
{
slang_assembly_stack_info stk;
slang_assembly_flow_control flow;
if (!ref)
{
if (!slang_assembly_file_push_label2 (file, slang_asm_local_addr, info->addr_tmp, 4))
return 0;
}
if (slang_string_compare ("=", oper) == 0)
{
if (!_slang_assemble_operation (file, op->children, 1, &flow, space, info, &stk))
return 0;
if (!_slang_assemble_operation (file, op->children + 1, 0, &flow, space, info, &stk))
return 0;
if (!_slang_assemble_assignment (file, op->children, space, info))
return 0;
}
else
{
if (!call_function_name (file, oper, op->children, op->num_children, 1, space, info))
return 0;
}
if (!ref)
{
if (!slang_assembly_file_push (file, slang_asm_addr_copy))
return 0;
if (!slang_assembly_file_push_label (file, slang_asm_local_free, 4))
return 0;
if (!dereference (file, op->children, space, info))
return 0;
}
return 1;
}
/*
* Mesa 3-D graphics library
* Version: 6.3
*
* Copyright (C) 2005 Brian Paul All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
/**
* \file slang_assemble_assignment.c
* slang assignment expressions assembler
* \author Michal Krol
*/
#include "imports.h"
#include "slang_assemble_assignment.h"
#include "slang_assemble_typeinfo.h"
#include "slang_storage.h"
#include "slang_utility.h"
/*
_slang_assemble_assignment()
copies values on the stack (<component 0> to <component N-1>) to a memory
location pointed by <addr of variable>;
in:
+------------------+
| addr of variable |
+------------------+
| component N-1 |
| ... |
| component 0 |
+------------------+
out:
+------------------+
| addr of variable |
+------------------+
*/
/* TODO: add support for swizzle mask */
static int assign_aggregate (slang_assembly_file *file, const slang_storage_aggregate *agg,
unsigned int *index, unsigned int size, slang_assembly_local_info *info)
{
unsigned int i;
for (i = 0; i < agg->count; i++)
{
const slang_storage_array *arr = agg->arrays + i;
unsigned int j;
for (j = 0; j < arr->length; j++)
{
if (arr->type == slang_stor_aggregate)
{
if (!assign_aggregate (file, arr->aggregate, index, size, info))
return 0;
}
else
{
slang_assembly_type ty;
switch (arr->type)
{
case slang_stor_bool:
ty = slang_asm_bool_copy;
break;
case slang_stor_int:
ty = slang_asm_int_copy;
break;
case slang_stor_float:
ty = slang_asm_float_copy;
break;
default:
break;
}
if (!slang_assembly_file_push_label2 (file, ty, size - *index, *index))
return 0;
*index += 4;
}
}
}
return 1;
}
int _slang_assemble_assignment (slang_assembly_file *file, slang_operation *op,
slang_assembly_name_space *space, slang_assembly_local_info *info)
{
slang_assembly_typeinfo ti;
int result;
slang_storage_aggregate agg;
unsigned int index, size;
slang_assembly_typeinfo_construct (&ti);
if (!_slang_typeof_operation (op, space, &ti))
{
slang_assembly_typeinfo_destruct (&ti);
return 0;
}
slang_storage_aggregate_construct (&agg);
if (!_slang_aggregate_variable (&agg, &ti.spec, NULL, space->funcs, space->structs))
{
slang_storage_aggregate_destruct (&agg);
slang_assembly_typeinfo_destruct (&ti);
return 0;
}
index = 0;
size = _slang_sizeof_aggregate (&agg);
result = assign_aggregate (file, &agg, &index, size, info);
slang_storage_aggregate_destruct (&agg);
slang_assembly_typeinfo_destruct (&ti);
return result;
}
/*
_slang_assemble_assign()
performs unary (pre ++ and --) or binary (=, +=, -=, *=, /=) assignment on the operation's
children
*/
int dereference (slang_assembly_file *file, slang_operation *op,
slang_assembly_name_space *space, slang_assembly_local_info *info);
int call_function_name (slang_assembly_file *file, const char *name, slang_operation *params,
unsigned int param_count, int assignment, slang_assembly_name_space *space,
slang_assembly_local_info *info);
int _slang_assemble_assign (slang_assembly_file *file, slang_operation *op, const char *oper,
int ref, slang_assembly_name_space *space, slang_assembly_local_info *info)
{
slang_assembly_stack_info stk;
slang_assembly_flow_control flow;
if (!ref)
{
if (!slang_assembly_file_push_label2 (file, slang_asm_local_addr, info->addr_tmp, 4))
return 0;
}
if (slang_string_compare ("=", oper) == 0)
{
if (!_slang_assemble_operation (file, op->children, 1, &flow, space, info, &stk))
return 0;
if (!_slang_assemble_operation (file, op->children + 1, 0, &flow, space, info, &stk))
return 0;
if (!_slang_assemble_assignment (file, op->children, space, info))
return 0;
}
else
{
if (!call_function_name (file, oper, op->children, op->num_children, 1, space, info))
return 0;
}
if (!ref)
{
if (!slang_assembly_file_push (file, slang_asm_addr_copy))
return 0;
if (!slang_assembly_file_push_label (file, slang_asm_local_free, 4))
return 0;
if (!dereference (file, op->children, space, info))
return 0;
}
return 1;
}
/*
* Mesa 3-D graphics library
* Version: 6.3
*
* Copyright (C) 2005 Brian Paul All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#if !defined SLANG_ASSEMBLE_ASSIGNMENT_H
#define SLANG_ASSEMBLE_ASSIGNMENT_H
#include "slang_assemble.h"
#if defined __cplusplus
extern "C" {
#endif
int _slang_assemble_assignment (slang_assembly_file *, slang_operation *,
slang_assembly_name_space *, slang_assembly_local_info *);
int _slang_assemble_assign (slang_assembly_file *, slang_operation *, const char *, int ref,
slang_assembly_name_space *, slang_assembly_local_info *);
#ifdef __cplusplus
}
#endif
#endif
/*
* Mesa 3-D graphics library
* Version: 6.3
*
* Copyright (C) 2005 Brian Paul All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#if !defined SLANG_ASSEMBLE_ASSIGNMENT_H
#define SLANG_ASSEMBLE_ASSIGNMENT_H
#include "slang_assemble.h"
#if defined __cplusplus
extern "C" {
#endif
int _slang_assemble_assignment (slang_assembly_file *, slang_operation *,
slang_assembly_name_space *, slang_assembly_local_info *);
int _slang_assemble_assign (slang_assembly_file *, slang_operation *, const char *, int ref,
slang_assembly_name_space *, slang_assembly_local_info *);
#ifdef __cplusplus
}
#endif
#endif
/*
* Mesa 3-D graphics library
* Version: 6.3
*
* Copyright (C) 2005 Brian Paul All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
/**
* \file slang_assemble_conditional.c
* slang condtional expressions assembler
* \author Michal Krol
*/
#include "imports.h"
#include "slang_utility.h"
#include "slang_assemble_conditional.h"
#include "slang_assemble.h"
/* _slang_assemble_logicaland() */
int _slang_assemble_logicaland (slang_assembly_file *file, slang_operation *op,
slang_assembly_flow_control *flow, slang_assembly_name_space *space,
slang_assembly_local_info *info)
{
/*
and:
<left-expression>
jumpz zero
<right-expression>
jump end
zero:
push 0
end:
*/
unsigned int zero_jump, end_jump;
slang_assembly_stack_info stk;
/* evaluate left expression */
if (!_slang_assemble_operation (file, op->children, 0, flow, space, info, &stk))
return 0;
/* TODO: inspect stk */
/* jump to pushing 0 if not true */
zero_jump = file->count;
if (!slang_assembly_file_push (file, slang_asm_jump_if_zero))
return 0;
/* evaluate right expression */
if (!_slang_assemble_operation (file, op->children + 1, 0, flow, space, info, &stk))
return 0;
/* TODO: inspect stk */
/* jump to the end of the expression */
end_jump = file->count;
if (!slang_assembly_file_push (file, slang_asm_jump))
return 0;
/* push 0 on stack */
file->code[zero_jump].param[0] = file->count;
if (!slang_assembly_file_push (file, slang_asm_bool_push))
return 0;
/* the end of the expression */
file->code[end_jump].param[0] = file->count;
return 1;
}
/* _slang_assemble_logicalor() */
int _slang_assemble_logicalor (slang_assembly_file *file, slang_operation *op,
slang_assembly_flow_control *flow, slang_assembly_name_space *space,
slang_assembly_local_info *info)
{
/*
or:
<left-expression>
jumpz right
push 1
jump end
right:
<right-expression>
end:
*/
unsigned int right_jump, end_jump;
slang_assembly_stack_info stk;
/* evaluate left expression */
if (!_slang_assemble_operation (file, op->children, 0, flow, space, info, &stk))
return 0;
/* TODO: inspect stk */
/* jump to evaluation of right expression if not true */
right_jump = file->count;
if (!slang_assembly_file_push (file, slang_asm_jump_if_zero))
return 0;
/* push 1 on stack */
if (!slang_assembly_file_push_literal (file, slang_asm_bool_push, 1.0f))
return 0;
/* jump to the end of the expression */
end_jump = file->count;
if (!slang_assembly_file_push (file, slang_asm_jump))
return 0;
/* evaluate right expression */
file->code[right_jump].param[0] = file->count;
if (!_slang_assemble_operation (file, op->children + 1, 0, flow, space, info, &stk))
return 0;
/* TODO: inspect stk */
/* the end of the expression */
file->code[end_jump].param[0] = file->count;
return 1;
}
/* _slang_assemble_select() */
int _slang_assemble_select (slang_assembly_file *file, slang_operation *op,
slang_assembly_flow_control *flow, slang_assembly_name_space *space,
slang_assembly_local_info *info)
{
/*
select:
<condition-expression>
jumpz false
<true-expression>
jump end
false:
<false-expression>
end:
*/
unsigned int cond_jump, end_jump;
slang_assembly_stack_info stk;
/* execute condition expression */
if (!_slang_assemble_operation (file, op->children, 0, flow, space, info, &stk))
return 0;
/* TODO: inspect stk */
/* jump to false expression if not true */
cond_jump = file->count;
if (!slang_assembly_file_push (file, slang_asm_jump_if_zero))
return 0;
/* execute true expression */
if (!_slang_assemble_operation (file, op->children + 1, 0, flow, space, info, &stk))
return 0;
/* TODO: inspect stk */
/* jump to the end of the expression */
end_jump = file->count;
if (!slang_assembly_file_push (file, slang_asm_jump))
return 0;
/* resolve false point */
file->code[cond_jump].param[0] = file->count;
/* execute false expression */
if (!_slang_assemble_operation (file, op->children + 2, 0, flow, space, info, &stk))
return 0;
/* TODO: inspect stk */
/* resolve the end of the expression */
file->code[end_jump].param[0] = file->count;
return 1;
}
/* _slang_assemble_for() */
int _slang_assemble_for (slang_assembly_file *file, slang_operation *op,
slang_assembly_flow_control *flow, slang_assembly_name_space *space,
slang_assembly_local_info *info)
{
/*
for:
<init-statement>
jump start
break:
jump end
continue:
<loop-increment>
start:
<condition-statement>
jumpz end
<loop-body>
jump continue
end:
*/
unsigned int start_jump, end_jump, cond_jump;
unsigned int break_label, cont_label;
slang_assembly_flow_control loop_flow = *flow;
slang_assembly_stack_info stk;
/* execute initialization statement */
if (!_slang_assemble_operation (file, op->children, 0, flow, space, info, &stk))
return 0;
/* TODO: pass-in stk to cleanup */
if (!_slang_cleanup_stack (file, op->children, 0, space))
return 0;
/* skip the "go to the end of the loop" and loop-increment statements */
start_jump = file->count;
if (!slang_assembly_file_push (file, slang_asm_jump))
return 0;
/* go to the end of the loop - break statements are directed here */
break_label = file->count;
end_jump = file->count;
if (!slang_assembly_file_push (file, slang_asm_jump))
return 0;
/* resolve the beginning of the loop - continue statements are directed here */
cont_label = file->count;
/* execute loop-increment statement */
if (!_slang_assemble_operation (file, op->children + 2, 0, flow, space, info, &stk))
return 0;
/* TODO: pass-in stk to cleanup */
if (!_slang_cleanup_stack (file, op->children + 2, 0, space))
return 0;
/* resolve the condition point */
file->code[start_jump].param[0] = file->count;
/* execute condition statement */
if (!_slang_assemble_operation (file, op->children + 1, 0, flow, space, info, &stk))
return 0;
/* TODO: inspect stk */
/* jump to the end of the loop if not true */
cond_jump = file->count;
if (!slang_assembly_file_push (file, slang_asm_jump_if_zero))
return 0;
/* execute loop body */
loop_flow.loop_start = cont_label;
loop_flow.loop_end = break_label;
if (!_slang_assemble_operation (file, op->children + 3, 0, &loop_flow, space, info, &stk))
return 0;
/* TODO: pass-in stk to cleanup */
if (!_slang_cleanup_stack (file, op->children + 3, 0, space))
return 0;
/* go to the beginning of the loop */
if (!slang_assembly_file_push_label (file, slang_asm_jump, cont_label))
return 0;
/* resolve the end of the loop */
file->code[end_jump].param[0] = file->count;
file->code[cond_jump].param[0] = file->count;
return 1;
}
/* _slang_assemble_do() */
int _slang_assemble_do (slang_assembly_file *file, slang_operation *op,
slang_assembly_flow_control *flow, slang_assembly_name_space *space,
slang_assembly_local_info *info)
{
/*
do:
jump start
break:
jump end
continue:
jump condition
start:
<loop-body>
condition:
<condition-statement>
jumpz end
jump start
end:
*/
unsigned int skip_jump, end_jump, cont_jump, cond_jump;
unsigned int break_label, cont_label;
slang_assembly_flow_control loop_flow = *flow;
slang_assembly_stack_info stk;
/* skip the "go to the end of the loop" and "go to condition" statements */
skip_jump = file->count;
if (!slang_assembly_file_push (file, slang_asm_jump))
return 0;
/* go to the end of the loop - break statements are directed here */
break_label = file->count;
end_jump = file->count;
if (!slang_assembly_file_push (file, slang_asm_jump))
return 0;
/* go to condition - continue statements are directed here */
cont_label = file->count;
cont_jump = file->count;
if (!slang_assembly_file_push (file, slang_asm_jump))
return 0;
/* resolve the beginning of the loop */
file->code[skip_jump].param[0] = file->count;
/* execute loop body */
loop_flow.loop_start = cont_label;
loop_flow.loop_end = break_label;
if (!_slang_assemble_operation (file, op->children, 0, &loop_flow, space, info, &stk))
return 0;
/* TODO: pass-in stk to cleanup */
if (!_slang_cleanup_stack (file, op->children, 0, space))
return 0;
/* resolve condition point */
file->code[cont_jump].param[0] = file->count;
/* execute condition statement */
if (!_slang_assemble_operation (file, op->children + 1, 0, flow, space, info, &stk))
return 0;
/* TODO: pass-in stk to cleanup */
/* jump to the end of the loop if not true */
cond_jump = file->count;
if (!slang_assembly_file_push (file, slang_asm_jump_if_zero))
return 0;
/* jump to the beginning of the loop */
if (!slang_assembly_file_push_label (file, slang_asm_jump, file->code[skip_jump].param[0]))
return 0;
/* resolve the end of the loop */
file->code[end_jump].param[0] = file->count;
file->code[cond_jump].param[0] = file->count;
return 1;
}
/* _slang_assemble_while() */
int _slang_assemble_while (slang_assembly_file *file, slang_operation *op,
slang_assembly_flow_control *flow, slang_assembly_name_space *space,
slang_assembly_local_info *info)
{
/*
while:
jump continue
break:
jump end
continue:
<condition-statement>
jumpz end
<loop-body>
jump continue
end:
*/
unsigned int skip_jump, end_jump, cond_jump;
unsigned int break_label;
slang_assembly_flow_control loop_flow = *flow;
slang_assembly_stack_info stk;
/* skip the "go to the end of the loop" statement */
skip_jump = file->count;
if (!slang_assembly_file_push (file, slang_asm_jump))
return 0;
/* go to the end of the loop - break statements are directed here */
break_label = file->count;
end_jump = file->count;
if (!slang_assembly_file_push (file, slang_asm_jump))
return 0;
/* resolve the beginning of the loop - continue statements are directed here */
file->code[skip_jump].param[0] = file->count;
/* execute condition statement */
if (!_slang_assemble_operation (file, op->children, 0, flow, space, info, &stk))
return 0;
/* TODO: pass-in stk to cleanup */
/* jump to the end of the loop if not true */
cond_jump = file->count;
if (!slang_assembly_file_push (file, slang_asm_jump_if_zero))
return 0;
/* execute loop body */
loop_flow.loop_start = file->code[skip_jump].param[0];
loop_flow.loop_end = break_label;
if (!_slang_assemble_operation (file, op->children + 1, 0, &loop_flow, space, info, &stk))
return 0;
/* TODO: pass-in stk to cleanup */
if (!_slang_cleanup_stack (file, op->children + 1, 0, space))
return 0;
/* jump to the beginning of the loop */
if (!slang_assembly_file_push_label (file, slang_asm_jump, file->code[skip_jump].param[0]))
return 0;
/* resolve the end of the loop */
file->code[end_jump].param[0] = file->count;
file->code[cond_jump].param[0] = file->count;
return 1;
}
/* _slang_assemble_if() */
int _slang_assemble_if (slang_assembly_file *file, slang_operation *op,
slang_assembly_flow_control *flow, slang_assembly_name_space *space,
slang_assembly_local_info *info)
{
/*
if:
<condition-statement>
jumpz else
<true-statement>
jump end
else:
<false-statement>
end:
*/
unsigned int cond_jump, else_jump;
slang_assembly_stack_info stk;
/* execute condition statement */
if (!_slang_assemble_operation (file, op->children, 0, flow, space, info, &stk))
return 0;
/* TODO: pass-in stk to cleanup */
/* jump to false-statement if not true */
cond_jump = file->count;
if (!slang_assembly_file_push (file, slang_asm_jump_if_zero))
return 0;
/* execute true-statement */
if (!_slang_assemble_operation (file, op->children + 1, 0, flow, space, info, &stk))
return 0;
/* TODO: pass-in stk to cleanup */
if (!_slang_cleanup_stack (file, op->children + 1, 0, space))
return 0;
/* skip if-false statement */
else_jump = file->count;
if (!slang_assembly_file_push (file, slang_asm_jump))
return 0;
/* resolve start of false-statement */
file->code[cond_jump].param[0] = file->count;
/* execute false-statement */
if (!_slang_assemble_operation (file, op->children + 2, 0, flow, space, info, &stk))
return 0;
/* TODO: pass-in stk to cleanup */
if (!_slang_cleanup_stack (file, op->children + 2, 0, space))
return 0;
/* resolve end of if-false statement */
file->code[else_jump].param[0] = file->count;
return 1;
}
/*
* Mesa 3-D graphics library
* Version: 6.3
*
* Copyright (C) 2005 Brian Paul All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
/**
* \file slang_assemble_conditional.c
* slang condtional expressions assembler
* \author Michal Krol
*/
#include "imports.h"
#include "slang_utility.h"
#include "slang_assemble_conditional.h"
#include "slang_assemble.h"
/* _slang_assemble_logicaland() */
int _slang_assemble_logicaland (slang_assembly_file *file, slang_operation *op,
slang_assembly_flow_control *flow, slang_assembly_name_space *space,
slang_assembly_local_info *info)
{
/*
and:
<left-expression>
jumpz zero
<right-expression>
jump end
zero:
push 0
end:
*/
unsigned int zero_jump, end_jump;
slang_assembly_stack_info stk;
/* evaluate left expression */
if (!_slang_assemble_operation (file, op->children, 0, flow, space, info, &stk))
return 0;
/* TODO: inspect stk */
/* jump to pushing 0 if not true */
zero_jump = file->count;
if (!slang_assembly_file_push (file, slang_asm_jump_if_zero))
return 0;
/* evaluate right expression */
if (!_slang_assemble_operation (file, op->children + 1, 0, flow, space, info, &stk))
return 0;
/* TODO: inspect stk */
/* jump to the end of the expression */
end_jump = file->count;
if (!slang_assembly_file_push (file, slang_asm_jump))
return 0;
/* push 0 on stack */
file->code[zero_jump].param[0] = file->count;
if (!slang_assembly_file_push (file, slang_asm_bool_push))
return 0;
/* the end of the expression */
file->code[end_jump].param[0] = file->count;
return 1;
}
/* _slang_assemble_logicalor() */
int _slang_assemble_logicalor (slang_assembly_file *file, slang_operation *op,
slang_assembly_flow_control *flow, slang_assembly_name_space *space,
slang_assembly_local_info *info)
{
/*
or:
<left-expression>
jumpz right
push 1
jump end
right:
<right-expression>
end:
*/
unsigned int right_jump, end_jump;
slang_assembly_stack_info stk;
/* evaluate left expression */
if (!_slang_assemble_operation (file, op->children, 0, flow, space, info, &stk))
return 0;
/* TODO: inspect stk */
/* jump to evaluation of right expression if not true */
right_jump = file->count;
if (!slang_assembly_file_push (file, slang_asm_jump_if_zero))
return 0;
/* push 1 on stack */
if (!slang_assembly_file_push_literal (file, slang_asm_bool_push, 1.0f))
return 0;
/* jump to the end of the expression */
end_jump = file->count;
if (!slang_assembly_file_push (file, slang_asm_jump))
return 0;
/* evaluate right expression */
file->code[right_jump].param[0] = file->count;
if (!_slang_assemble_operation (file, op->children + 1, 0, flow, space, info, &stk))
return 0;
/* TODO: inspect stk */
/* the end of the expression */
file->code[end_jump].param[0] = file->count;
return 1;
}
/* _slang_assemble_select() */
int _slang_assemble_select (slang_assembly_file *file, slang_operation *op,
slang_assembly_flow_control *flow, slang_assembly_name_space *space,
slang_assembly_local_info *info)
{
/*
select:
<condition-expression>
jumpz false
<true-expression>
jump end
false:
<false-expression>
end:
*/
unsigned int cond_jump, end_jump;
slang_assembly_stack_info stk;
/* execute condition expression */
if (!_slang_assemble_operation (file, op->children, 0, flow, space, info, &stk))
return 0;
/* TODO: inspect stk */
/* jump to false expression if not true */
cond_jump = file->count;
if (!slang_assembly_file_push (file, slang_asm_jump_if_zero))
return 0;
/* execute true expression */
if (!_slang_assemble_operation (file, op->children + 1, 0, flow, space, info, &stk))
return 0;
/* TODO: inspect stk */
/* jump to the end of the expression */
end_jump = file->count;
if (!slang_assembly_file_push (file, slang_asm_jump))
return 0;
/* resolve false point */
file->code[cond_jump].param[0] = file->count;
/* execute false expression */
if (!_slang_assemble_operation (file, op->children + 2, 0, flow, space, info, &stk))
return 0;
/* TODO: inspect stk */
/* resolve the end of the expression */
file->code[end_jump].param[0] = file->count;
return 1;
}
/* _slang_assemble_for() */
int _slang_assemble_for (slang_assembly_file *file, slang_operation *op,
slang_assembly_flow_control *flow, slang_assembly_name_space *space,
slang_assembly_local_info *info)
{
/*
for:
<init-statement>
jump start
break:
jump end
continue:
<loop-increment>
start:
<condition-statement>
jumpz end
<loop-body>
jump continue
end:
*/
unsigned int start_jump, end_jump, cond_jump;
unsigned int break_label, cont_label;
slang_assembly_flow_control loop_flow = *flow;
slang_assembly_stack_info stk;
/* execute initialization statement */
if (!_slang_assemble_operation (file, op->children, 0, flow, space, info, &stk))
return 0;
/* TODO: pass-in stk to cleanup */
if (!_slang_cleanup_stack (file, op->children, 0, space))
return 0;
/* skip the "go to the end of the loop" and loop-increment statements */
start_jump = file->count;
if (!slang_assembly_file_push (file, slang_asm_jump))
return 0;
/* go to the end of the loop - break statements are directed here */
break_label = file->count;
end_jump = file->count;
if (!slang_assembly_file_push (file, slang_asm_jump))
return 0;
/* resolve the beginning of the loop - continue statements are directed here */
cont_label = file->count;
/* execute loop-increment statement */
if (!_slang_assemble_operation (file, op->children + 2, 0, flow, space, info, &stk))
return 0;
/* TODO: pass-in stk to cleanup */
if (!_slang_cleanup_stack (file, op->children + 2, 0, space))
return 0;
/* resolve the condition point */
file->code[start_jump].param[0] = file->count;
/* execute condition statement */
if (!_slang_assemble_operation (file, op->children + 1, 0, flow, space, info, &stk))
return 0;
/* TODO: inspect stk */
/* jump to the end of the loop if not true */
cond_jump = file->count;
if (!slang_assembly_file_push (file, slang_asm_jump_if_zero))
return 0;
/* execute loop body */
loop_flow.loop_start = cont_label;
loop_flow.loop_end = break_label;
if (!_slang_assemble_operation (file, op->children + 3, 0, &loop_flow, space, info, &stk))
return 0;
/* TODO: pass-in stk to cleanup */
if (!_slang_cleanup_stack (file, op->children + 3, 0, space))
return 0;
/* go to the beginning of the loop */
if (!slang_assembly_file_push_label (file, slang_asm_jump, cont_label))
return 0;
/* resolve the end of the loop */
file->code[end_jump].param[0] = file->count;
file->code[cond_jump].param[0] = file->count;
return 1;
}
/* _slang_assemble_do() */
int _slang_assemble_do (slang_assembly_file *file, slang_operation *op,
slang_assembly_flow_control *flow, slang_assembly_name_space *space,
slang_assembly_local_info *info)
{
/*
do:
jump start
break:
jump end
continue:
jump condition
start:
<loop-body>
condition:
<condition-statement>
jumpz end
jump start
end:
*/
unsigned int skip_jump, end_jump, cont_jump, cond_jump;
unsigned int break_label, cont_label;
slang_assembly_flow_control loop_flow = *flow;
slang_assembly_stack_info stk;
/* skip the "go to the end of the loop" and "go to condition" statements */
skip_jump = file->count;
if (!slang_assembly_file_push (file, slang_asm_jump))
return 0;
/* go to the end of the loop - break statements are directed here */
break_label = file->count;
end_jump = file->count;
if (!slang_assembly_file_push (file, slang_asm_jump))
return 0;
/* go to condition - continue statements are directed here */
cont_label = file->count;
cont_jump = file->count;
if (!slang_assembly_file_push (file, slang_asm_jump))
return 0;
/* resolve the beginning of the loop */
file->code[skip_jump].param[0] = file->count;
/* execute loop body */
loop_flow.loop_start = cont_label;
loop_flow.loop_end = break_label;
if (!_slang_assemble_operation (file, op->children, 0, &loop_flow, space, info, &stk))
return 0;
/* TODO: pass-in stk to cleanup */
if (!_slang_cleanup_stack (file, op->children, 0, space))
return 0;
/* resolve condition point */
file->code[cont_jump].param[0] = file->count;
/* execute condition statement */
if (!_slang_assemble_operation (file, op->children + 1, 0, flow, space, info, &stk))
return 0;
/* TODO: pass-in stk to cleanup */
/* jump to the end of the loop if not true */
cond_jump = file->count;
if (!slang_assembly_file_push (file, slang_asm_jump_if_zero))
return 0;
/* jump to the beginning of the loop */
if (!slang_assembly_file_push_label (file, slang_asm_jump, file->code[skip_jump].param[0]))
return 0;
/* resolve the end of the loop */
file->code[end_jump].param[0] = file->count;
file->code[cond_jump].param[0] = file->count;
return 1;
}
/* _slang_assemble_while() */
int _slang_assemble_while (slang_assembly_file *file, slang_operation *op,
slang_assembly_flow_control *flow, slang_assembly_name_space *space,
slang_assembly_local_info *info)
{
/*
while:
jump continue
break:
jump end
continue:
<condition-statement>
jumpz end
<loop-body>
jump continue
end:
*/
unsigned int skip_jump, end_jump, cond_jump;
unsigned int break_label;
slang_assembly_flow_control loop_flow = *flow;
slang_assembly_stack_info stk;
/* skip the "go to the end of the loop" statement */
skip_jump = file->count;
if (!slang_assembly_file_push (file, slang_asm_jump))
return 0;
/* go to the end of the loop - break statements are directed here */
break_label = file->count;
end_jump = file->count;
if (!slang_assembly_file_push (file, slang_asm_jump))
return 0;
/* resolve the beginning of the loop - continue statements are directed here */
file->code[skip_jump].param[0] = file->count;
/* execute condition statement */
if (!_slang_assemble_operation (file, op->children, 0, flow, space, info, &stk))
return 0;
/* TODO: pass-in stk to cleanup */
/* jump to the end of the loop if not true */
cond_jump = file->count;
if (!slang_assembly_file_push (file, slang_asm_jump_if_zero))
return 0;
/* execute loop body */
loop_flow.loop_start = file->code[skip_jump].param[0];
loop_flow.loop_end = break_label;
if (!_slang_assemble_operation (file, op->children + 1, 0, &loop_flow, space, info, &stk))
return 0;
/* TODO: pass-in stk to cleanup */
if (!_slang_cleanup_stack (file, op->children + 1, 0, space))
return 0;
/* jump to the beginning of the loop */
if (!slang_assembly_file_push_label (file, slang_asm_jump, file->code[skip_jump].param[0]))
return 0;
/* resolve the end of the loop */
file->code[end_jump].param[0] = file->count;
file->code[cond_jump].param[0] = file->count;
return 1;
}
/* _slang_assemble_if() */
int _slang_assemble_if (slang_assembly_file *file, slang_operation *op,
slang_assembly_flow_control *flow, slang_assembly_name_space *space,
slang_assembly_local_info *info)
{
/*
if:
<condition-statement>
jumpz else
<true-statement>
jump end
else:
<false-statement>
end:
*/
unsigned int cond_jump, else_jump;
slang_assembly_stack_info stk;
/* execute condition statement */
if (!_slang_assemble_operation (file, op->children, 0, flow, space, info, &stk))
return 0;
/* TODO: pass-in stk to cleanup */
/* jump to false-statement if not true */
cond_jump = file->count;
if (!slang_assembly_file_push (file, slang_asm_jump_if_zero))
return 0;
/* execute true-statement */
if (!_slang_assemble_operation (file, op->children + 1, 0, flow, space, info, &stk))
return 0;
/* TODO: pass-in stk to cleanup */
if (!_slang_cleanup_stack (file, op->children + 1, 0, space))
return 0;
/* skip if-false statement */
else_jump = file->count;
if (!slang_assembly_file_push (file, slang_asm_jump))
return 0;
/* resolve start of false-statement */
file->code[cond_jump].param[0] = file->count;
/* execute false-statement */
if (!_slang_assemble_operation (file, op->children + 2, 0, flow, space, info, &stk))
return 0;
/* TODO: pass-in stk to cleanup */
if (!_slang_cleanup_stack (file, op->children + 2, 0, space))
return 0;
/* resolve end of if-false statement */
file->code[else_jump].param[0] = file->count;
return 1;
}
/*
* Mesa 3-D graphics library
* Version: 6.3
*
* Copyright (C) 2005 Brian Paul All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#if !defined SLANG_ASSEMBLE_CONDITIONAL_H
#define SLANG_ASSEMBLE_CONDITIONAL_H
#include "slang_assemble.h"
#if defined __cplusplus
extern "C" {
#endif
int _slang_assemble_logicaland (slang_assembly_file *file, slang_operation *op,
slang_assembly_flow_control *flow, slang_assembly_name_space *space,
slang_assembly_local_info *info);
int _slang_assemble_logicalor (slang_assembly_file *file, slang_operation *op,
slang_assembly_flow_control *flow, slang_assembly_name_space *space,
slang_assembly_local_info *info);
int _slang_assemble_select (slang_assembly_file *file, slang_operation *op,
slang_assembly_flow_control *flow, slang_assembly_name_space *space,
slang_assembly_local_info *info);
int _slang_assemble_for (slang_assembly_file *file, slang_operation *op,
slang_assembly_flow_control *flow, slang_assembly_name_space *space,
slang_assembly_local_info *info);
int _slang_assemble_do (slang_assembly_file *file, slang_operation *op,
slang_assembly_flow_control *flow, slang_assembly_name_space *space,
slang_assembly_local_info *info);
int _slang_assemble_while (slang_assembly_file *file, slang_operation *op,
slang_assembly_flow_control *flow, slang_assembly_name_space *space,
slang_assembly_local_info *info);
int _slang_assemble_if (slang_assembly_file *file, slang_operation *op,
slang_assembly_flow_control *flow, slang_assembly_name_space *space,
slang_assembly_local_info *info);
#ifdef __cplusplus
}
#endif
#endif
/*
* Mesa 3-D graphics library
* Version: 6.3
*
* Copyright (C) 2005 Brian Paul All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#if !defined SLANG_ASSEMBLE_CONDITIONAL_H
#define SLANG_ASSEMBLE_CONDITIONAL_H
#include "slang_assemble.h"
#if defined __cplusplus
extern "C" {
#endif
int _slang_assemble_logicaland (slang_assembly_file *file, slang_operation *op,
slang_assembly_flow_control *flow, slang_assembly_name_space *space,
slang_assembly_local_info *info);
int _slang_assemble_logicalor (slang_assembly_file *file, slang_operation *op,
slang_assembly_flow_control *flow, slang_assembly_name_space *space,
slang_assembly_local_info *info);
int _slang_assemble_select (slang_assembly_file *file, slang_operation *op,
slang_assembly_flow_control *flow, slang_assembly_name_space *space,
slang_assembly_local_info *info);
int _slang_assemble_for (slang_assembly_file *file, slang_operation *op,
slang_assembly_flow_control *flow, slang_assembly_name_space *space,
slang_assembly_local_info *info);
int _slang_assemble_do (slang_assembly_file *file, slang_operation *op,
slang_assembly_flow_control *flow, slang_assembly_name_space *space,
slang_assembly_local_info *info);
int _slang_assemble_while (slang_assembly_file *file, slang_operation *op,
slang_assembly_flow_control *flow, slang_assembly_name_space *space,
slang_assembly_local_info *info);
int _slang_assemble_if (slang_assembly_file *file, slang_operation *op,
slang_assembly_flow_control *flow, slang_assembly_name_space *space,
slang_assembly_local_info *info);
#ifdef __cplusplus
}
#endif
#endif
/*
* Mesa 3-D graphics library
* Version: 6.3
*
* Copyright (C) 2005 Brian Paul All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
/**
* \file slang_assemble_constructor.c
* slang constructor and vector swizzle assembler
* \author Michal Krol
*/
#include "imports.h"
#include "slang_utility.h"
#include "slang_assemble_constructor.h"
#include "slang_assemble_typeinfo.h"
#include "slang_storage.h"
/* _slang_is_swizzle() */
int _slang_is_swizzle (const char *field, unsigned int rows, slang_swizzle *swz)
{
unsigned int i;
int xyzw = 0, rgba = 0, stpq = 0;
/* the swizzle can be at most 4-component long */
swz->num_components = slang_string_length (field);
if (swz->num_components > 4)
return 0;
for (i = 0; i < swz->num_components; i++)
{
/* mark which swizzle group is used */
switch (field[i])
{
case 'x':
case 'y':
case 'z':
case 'w':
xyzw = 1;
break;
case 'r':
case 'g':
case 'b':
case 'a':
rgba = 1;
break;
case 's':
case 't':
case 'p':
case 'q':
stpq = 1;
break;
default:
return 0;
}
/* collect swizzle component */
switch (field[i])
{
case 'x':
case 'r':
case 's':
swz->swizzle[i] = 0;
break;
case 'y':
case 'g':
case 't':
if (rows < 2)
return 0;
swz->swizzle[i] = 1;
break;
case 'z':
case 'b':
case 'p':
if (rows < 3)
return 0;
swz->swizzle[i] = 2;
break;
case 'w':
case 'a':
case 'q':
if (rows < 4)
return 0;
swz->swizzle[i] = 3;
break;
}
}
/* only one swizzle group can be used */
if ((xyzw && rgba) || (xyzw && stpq) || (rgba && stpq))
return 0;
return 1;
}
/* _slang_is_swizzle_mask() */
int _slang_is_swizzle_mask (const slang_swizzle *swz, unsigned int rows)
{
unsigned int c, i;
if (swz->num_components > rows)
return 0;
c = swz->swizzle[0];
for (i = 1; i < swz->num_components; i++)
{
if (swz->swizzle[i] <= c)
return 0;
c = swz->swizzle[i];
}
return 1;
}
/* _slang_multiply_swizzles() */
void _slang_multiply_swizzles (slang_swizzle *dst, const slang_swizzle *left,
const slang_swizzle *right)
{
unsigned int i;
dst->num_components = right->num_components;
for (i = 0; i < right->num_components; i++)
dst->swizzle[i] = left->swizzle[right->swizzle[i]];
}
/* _slang_assemble_constructor() */
static int constructor_aggregate (slang_assembly_file *file, const slang_storage_aggregate *flat,
unsigned int *index, slang_operation *op, unsigned int size, slang_assembly_flow_control *flow,
slang_assembly_name_space *space, slang_assembly_local_info *info)
{
slang_assembly_typeinfo ti;
int result;
slang_storage_aggregate agg, flat_agg;
slang_assembly_stack_info stk;
unsigned int i;
slang_assembly_typeinfo_construct (&ti);
if (!(result = _slang_typeof_operation (op, space, &ti)))
goto end1;
slang_storage_aggregate_construct (&agg);
if (!(result = _slang_aggregate_variable (&agg, &ti.spec, NULL, space->funcs, space->structs)))
goto end2;
slang_storage_aggregate_construct (&flat_agg);
if (!(result = _slang_flatten_aggregate (&flat_agg, &agg)))
goto end;
if (!(result = _slang_assemble_operation (file, op, 0, flow, space, info, &stk)))
goto end;
for (i = 0; i < flat_agg.count; i++)
{
const slang_storage_array *arr1 = flat_agg.arrays + i;
const slang_storage_array *arr2 = flat->arrays + *index;
if (arr1->type != arr2->type)
{
/* TODO: convert (generic) from arr1 to arr2 */
}
(*index)++;
/* TODO: watch the index, if it reaches the size, pop off the stack subsequent values */
}
result = 1;
end:
slang_storage_aggregate_destruct (&flat_agg);
end2:
slang_storage_aggregate_destruct (&agg);
end1:
slang_assembly_typeinfo_destruct (&ti);
return result;
}
/* XXX: general swizzle! */
int _slang_assemble_constructor (slang_assembly_file *file, slang_operation *op,
slang_assembly_flow_control *flow, slang_assembly_name_space *space,
slang_assembly_local_info *info)
{
slang_assembly_typeinfo ti;
int result;
slang_storage_aggregate agg, flat;
unsigned int size, index, i;
slang_assembly_typeinfo_construct (&ti);
if (!(result = _slang_typeof_operation (op, space, &ti)))
goto end1;
slang_storage_aggregate_construct (&agg);
if (!(result = _slang_aggregate_variable (&agg, &ti.spec, NULL, space->funcs, space->structs)))
goto end2;
size = _slang_sizeof_aggregate (&agg);
slang_storage_aggregate_construct (&flat);
if (!(result = _slang_flatten_aggregate (&flat, &agg)))
goto end;
index = 0;
for (i = 0; i < op->num_children; i++)
{
if (!(result = constructor_aggregate (file, &flat, &index, op->children + i, size, flow,
space, info)))
goto end;
/* TODO: watch the index, if it reaches the size, raise an error */
}
result = 1;
end:
slang_storage_aggregate_destruct (&flat);
end2:
slang_storage_aggregate_destruct (&agg);
end1:
slang_assembly_typeinfo_destruct (&ti);
return result;
}
/* _slang_assemble_constructor_from_swizzle() */
/* XXX: wrong */
int _slang_assemble_constructor_from_swizzle (slang_assembly_file *file, const slang_swizzle *swz,
slang_type_specifier *spec, slang_type_specifier *master_spec, slang_assembly_local_info *info)
{
unsigned int master_rows, i;
switch (master_spec->type)
{
case slang_spec_bool:
case slang_spec_int:
case slang_spec_float:
master_rows = 1;
break;
case slang_spec_bvec2:
case slang_spec_ivec2:
case slang_spec_vec2:
master_rows = 2;
break;
case slang_spec_bvec3:
case slang_spec_ivec3:
case slang_spec_vec3:
master_rows = 3;
break;
case slang_spec_bvec4:
case slang_spec_ivec4:
case slang_spec_vec4:
master_rows = 4;
break;
default:
break;
}
for (i = 0; i < master_rows; i++)
{
switch (master_spec->type)
{
case slang_spec_bool:
case slang_spec_bvec2:
case slang_spec_bvec3:
case slang_spec_bvec4:
if (!slang_assembly_file_push_label2 (file, slang_asm_bool_copy, (master_rows - i) * 4,
i * 4))
return 0;
break;
case slang_spec_int:
case slang_spec_ivec2:
case slang_spec_ivec3:
case slang_spec_ivec4:
if (!slang_assembly_file_push_label2 (file, slang_asm_int_copy, (master_rows - i) * 4,
i * 4))
return 0;
break;
case slang_spec_float:
case slang_spec_vec2:
case slang_spec_vec3:
case slang_spec_vec4:
if (!slang_assembly_file_push_label2 (file, slang_asm_float_copy,
(master_rows - i) * 4, i * 4))
return 0;
break;
default:
break;
}
}
if (!slang_assembly_file_push_label (file, slang_asm_local_free, 4))
return 0;
for (i = swz->num_components; i > 0; i--)
{
unsigned int n = i - 1;
if (!slang_assembly_file_push_label2 (file, slang_asm_local_addr, info->swizzle_tmp, 16))
return 0;
if (!slang_assembly_file_push_label (file, slang_asm_addr_push, swz->swizzle[n] * 4))
return 0;
if (!slang_assembly_file_push (file, slang_asm_addr_add))
return 0;
switch (master_spec->type)
{
case slang_spec_bool:
case slang_spec_bvec2:
case slang_spec_bvec3:
case slang_spec_bvec4:
if (!slang_assembly_file_push (file, slang_asm_bool_deref))
return 0;
break;
case slang_spec_int:
case slang_spec_ivec2:
case slang_spec_ivec3:
case slang_spec_ivec4:
if (!slang_assembly_file_push (file, slang_asm_int_deref))
return 0;
break;
case slang_spec_float:
case slang_spec_vec2:
case slang_spec_vec3:
case slang_spec_vec4:
if (!slang_assembly_file_push (file, slang_asm_float_deref))
return 0;
break;
default:
break;
}
}
return 1;
}
/*
* Mesa 3-D graphics library
* Version: 6.3
*
* Copyright (C) 2005 Brian Paul All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
/**
* \file slang_assemble_constructor.c
* slang constructor and vector swizzle assembler
* \author Michal Krol
*/
#include "imports.h"
#include "slang_utility.h"
#include "slang_assemble_constructor.h"
#include "slang_assemble_typeinfo.h"
#include "slang_storage.h"
/* _slang_is_swizzle() */
int _slang_is_swizzle (const char *field, unsigned int rows, slang_swizzle *swz)
{
unsigned int i;
int xyzw = 0, rgba = 0, stpq = 0;
/* the swizzle can be at most 4-component long */
swz->num_components = slang_string_length (field);
if (swz->num_components > 4)
return 0;
for (i = 0; i < swz->num_components; i++)
{
/* mark which swizzle group is used */
switch (field[i])
{
case 'x':
case 'y':
case 'z':
case 'w':
xyzw = 1;
break;
case 'r':
case 'g':
case 'b':
case 'a':
rgba = 1;
break;
case 's':
case 't':
case 'p':
case 'q':
stpq = 1;
break;
default:
return 0;
}
/* collect swizzle component */
switch (field[i])
{
case 'x':
case 'r':
case 's':
swz->swizzle[i] = 0;
break;
case 'y':
case 'g':
case 't':
if (rows < 2)
return 0;
swz->swizzle[i] = 1;
break;
case 'z':
case 'b':
case 'p':
if (rows < 3)
return 0;
swz->swizzle[i] = 2;
break;
case 'w':
case 'a':
case 'q':
if (rows < 4)
return 0;
swz->swizzle[i] = 3;
break;
}
}
/* only one swizzle group can be used */
if ((xyzw && rgba) || (xyzw && stpq) || (rgba && stpq))
return 0;
return 1;
}
/* _slang_is_swizzle_mask() */
int _slang_is_swizzle_mask (const slang_swizzle *swz, unsigned int rows)
{
unsigned int c, i;
if (swz->num_components > rows)
return 0;
c = swz->swizzle[0];
for (i = 1; i < swz->num_components; i++)
{
if (swz->swizzle[i] <= c)
return 0;
c = swz->swizzle[i];
}
return 1;
}
/* _slang_multiply_swizzles() */
void _slang_multiply_swizzles (slang_swizzle *dst, const slang_swizzle *left,
const slang_swizzle *right)
{
unsigned int i;
dst->num_components = right->num_components;
for (i = 0; i < right->num_components; i++)
dst->swizzle[i] = left->swizzle[right->swizzle[i]];
}
/* _slang_assemble_constructor() */
static int constructor_aggregate (slang_assembly_file *file, const slang_storage_aggregate *flat,
unsigned int *index, slang_operation *op, unsigned int size, slang_assembly_flow_control *flow,
slang_assembly_name_space *space, slang_assembly_local_info *info)
{
slang_assembly_typeinfo ti;
int result;
slang_storage_aggregate agg, flat_agg;
slang_assembly_stack_info stk;
unsigned int i;
slang_assembly_typeinfo_construct (&ti);
if (!(result = _slang_typeof_operation (op, space, &ti)))
goto end1;
slang_storage_aggregate_construct (&agg);
if (!(result = _slang_aggregate_variable (&agg, &ti.spec, NULL, space->funcs, space->structs)))
goto end2;
slang_storage_aggregate_construct (&flat_agg);
if (!(result = _slang_flatten_aggregate (&flat_agg, &agg)))
goto end;
if (!(result = _slang_assemble_operation (file, op, 0, flow, space, info, &stk)))
goto end;
for (i = 0; i < flat_agg.count; i++)
{
const slang_storage_array *arr1 = flat_agg.arrays + i;
const slang_storage_array *arr2 = flat->arrays + *index;
if (arr1->type != arr2->type)
{
/* TODO: convert (generic) from arr1 to arr2 */
}
(*index)++;
/* TODO: watch the index, if it reaches the size, pop off the stack subsequent values */
}
result = 1;
end:
slang_storage_aggregate_destruct (&flat_agg);
end2:
slang_storage_aggregate_destruct (&agg);
end1:
slang_assembly_typeinfo_destruct (&ti);
return result;
}
/* XXX: general swizzle! */
int _slang_assemble_constructor (slang_assembly_file *file, slang_operation *op,
slang_assembly_flow_control *flow, slang_assembly_name_space *space,
slang_assembly_local_info *info)
{
slang_assembly_typeinfo ti;
int result;
slang_storage_aggregate agg, flat;
unsigned int size, index, i;
slang_assembly_typeinfo_construct (&ti);
if (!(result = _slang_typeof_operation (op, space, &ti)))
goto end1;
slang_storage_aggregate_construct (&agg);
if (!(result = _slang_aggregate_variable (&agg, &ti.spec, NULL, space->funcs, space->structs)))
goto end2;
size = _slang_sizeof_aggregate (&agg);
slang_storage_aggregate_construct (&flat);
if (!(result = _slang_flatten_aggregate (&flat, &agg)))
goto end;
index = 0;
for (i = 0; i < op->num_children; i++)
{
if (!(result = constructor_aggregate (file, &flat, &index, op->children + i, size, flow,
space, info)))
goto end;
/* TODO: watch the index, if it reaches the size, raise an error */
}
result = 1;
end:
slang_storage_aggregate_destruct (&flat);
end2:
slang_storage_aggregate_destruct (&agg);
end1:
slang_assembly_typeinfo_destruct (&ti);
return result;
}
/* _slang_assemble_constructor_from_swizzle() */
/* XXX: wrong */
int _slang_assemble_constructor_from_swizzle (slang_assembly_file *file, const slang_swizzle *swz,
slang_type_specifier *spec, slang_type_specifier *master_spec, slang_assembly_local_info *info)
{
unsigned int master_rows, i;
switch (master_spec->type)
{
case slang_spec_bool:
case slang_spec_int:
case slang_spec_float:
master_rows = 1;
break;
case slang_spec_bvec2:
case slang_spec_ivec2:
case slang_spec_vec2:
master_rows = 2;
break;
case slang_spec_bvec3:
case slang_spec_ivec3:
case slang_spec_vec3:
master_rows = 3;
break;
case slang_spec_bvec4:
case slang_spec_ivec4:
case slang_spec_vec4:
master_rows = 4;
break;
default:
break;
}
for (i = 0; i < master_rows; i++)
{
switch (master_spec->type)
{
case slang_spec_bool:
case slang_spec_bvec2:
case slang_spec_bvec3:
case slang_spec_bvec4:
if (!slang_assembly_file_push_label2 (file, slang_asm_bool_copy, (master_rows - i) * 4,
i * 4))
return 0;
break;
case slang_spec_int:
case slang_spec_ivec2:
case slang_spec_ivec3:
case slang_spec_ivec4:
if (!slang_assembly_file_push_label2 (file, slang_asm_int_copy, (master_rows - i) * 4,
i * 4))
return 0;
break;
case slang_spec_float:
case slang_spec_vec2:
case slang_spec_vec3:
case slang_spec_vec4:
if (!slang_assembly_file_push_label2 (file, slang_asm_float_copy,
(master_rows - i) * 4, i * 4))
return 0;
break;
default:
break;
}
}
if (!slang_assembly_file_push_label (file, slang_asm_local_free, 4))
return 0;
for (i = swz->num_components; i > 0; i--)
{
unsigned int n = i - 1;
if (!slang_assembly_file_push_label2 (file, slang_asm_local_addr, info->swizzle_tmp, 16))
return 0;
if (!slang_assembly_file_push_label (file, slang_asm_addr_push, swz->swizzle[n] * 4))
return 0;
if (!slang_assembly_file_push (file, slang_asm_addr_add))
return 0;
switch (master_spec->type)
{
case slang_spec_bool:
case slang_spec_bvec2:
case slang_spec_bvec3:
case slang_spec_bvec4:
if (!slang_assembly_file_push (file, slang_asm_bool_deref))
return 0;
break;
case slang_spec_int:
case slang_spec_ivec2:
case slang_spec_ivec3:
case slang_spec_ivec4:
if (!slang_assembly_file_push (file, slang_asm_int_deref))
return 0;
break;
case slang_spec_float:
case slang_spec_vec2:
case slang_spec_vec3:
case slang_spec_vec4:
if (!slang_assembly_file_push (file, slang_asm_float_deref))
return 0;
break;
default:
break;
}
}
return 1;
}
/*
* Mesa 3-D graphics library
* Version: 6.3
*
* Copyright (C) 2005 Brian Paul All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#if !defined SLANG_ASSEMBLE_CONSTRUCTOR_H
#define SLANG_ASSEMBLE_CONSTRUCTOR_H
#include "slang_assemble.h"
#include "slang_compile.h"
#if defined __cplusplus
extern "C" {
#endif
/*
holds a complete information about vector swizzle - the <swizzle> array contains
vector component sources indices, where 0 is "x", 1 is "y", ...
example: "xwz" --> { 3, { 0, 3, 2, n/u } }
*/
typedef struct slang_swizzle_
{
unsigned int num_components;
unsigned int swizzle[4];
} slang_swizzle;
/*
checks if a field selector is a general swizzle (an r-value swizzle with replicated
components or an l-value swizzle mask) for a vector
returns 1 if this is the case, <swz> is filled with swizzle information
returns 0 otherwise
*/
int _slang_is_swizzle (const char *field, unsigned int rows, slang_swizzle *swz);
/*
checks if a general swizzle is an l-value swizzle - these swizzles do not have
duplicated fields and they are specified in order
returns 1 if this is a swizzle mask
returns 0 otherwise
*/
int _slang_is_swizzle_mask (const slang_swizzle *swz, unsigned int rows);
/*
combines two swizzles to form single swizzle
example: "wzyx.yx" --> "zw"
*/
void _slang_multiply_swizzles (slang_swizzle *, const slang_swizzle *, const slang_swizzle *);
int _slang_assemble_constructor (slang_assembly_file *file, slang_operation *op,
slang_assembly_flow_control *flow, slang_assembly_name_space *space,
slang_assembly_local_info *info);
int _slang_assemble_constructor_from_swizzle (slang_assembly_file *file, const slang_swizzle *swz,
slang_type_specifier *spec, slang_type_specifier *master_spec, slang_assembly_local_info *info);
#ifdef __cplusplus
}
#endif
#endif
/*
* Mesa 3-D graphics library
* Version: 6.3
*
* Copyright (C) 2005 Brian Paul All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#if !defined SLANG_ASSEMBLE_CONSTRUCTOR_H
#define SLANG_ASSEMBLE_CONSTRUCTOR_H
#include "slang_assemble.h"
#include "slang_compile.h"
#if defined __cplusplus
extern "C" {
#endif
/*
holds a complete information about vector swizzle - the <swizzle> array contains
vector component sources indices, where 0 is "x", 1 is "y", ...
example: "xwz" --> { 3, { 0, 3, 2, n/u } }
*/
typedef struct slang_swizzle_
{
unsigned int num_components;
unsigned int swizzle[4];
} slang_swizzle;
/*
checks if a field selector is a general swizzle (an r-value swizzle with replicated
components or an l-value swizzle mask) for a vector
returns 1 if this is the case, <swz> is filled with swizzle information
returns 0 otherwise
*/
int _slang_is_swizzle (const char *field, unsigned int rows, slang_swizzle *swz);
/*
checks if a general swizzle is an l-value swizzle - these swizzles do not have
duplicated fields and they are specified in order
returns 1 if this is a swizzle mask
returns 0 otherwise
*/
int _slang_is_swizzle_mask (const slang_swizzle *swz, unsigned int rows);
/*
combines two swizzles to form single swizzle
example: "wzyx.yx" --> "zw"
*/
void _slang_multiply_swizzles (slang_swizzle *, const slang_swizzle *, const slang_swizzle *);
int _slang_assemble_constructor (slang_assembly_file *file, slang_operation *op,
slang_assembly_flow_control *flow, slang_assembly_name_space *space,
slang_assembly_local_info *info);
int _slang_assemble_constructor_from_swizzle (slang_assembly_file *file, const slang_swizzle *swz,
slang_type_specifier *spec, slang_type_specifier *master_spec, slang_assembly_local_info *info);
#ifdef __cplusplus
}
#endif
#endif
/*
* Mesa 3-D graphics library
* Version: 6.3
*
* Copyright (C) 2005 Brian Paul All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
/**
* \file slang_assemble_typeinfo.c
* slang type info
* \author Michal Krol
*/
#include "imports.h"
#include "slang_utility.h"
#include "slang_assemble_typeinfo.h"
/* slang_assembly_typeinfo */
void slang_assembly_typeinfo_construct (slang_assembly_typeinfo *ti)
{
slang_type_specifier_construct (&ti->spec);
}
void slang_assembly_typeinfo_destruct (slang_assembly_typeinfo *ti)
{
slang_type_specifier_destruct (&ti->spec);
}
/* _slang_typeof_operation() */
int _slang_typeof_operation (slang_operation *op, slang_assembly_name_space *space,
slang_assembly_typeinfo *ti)
{
ti->can_be_referenced = 0;
ti->is_swizzled = 0;
switch (op->type)
{
case slang_oper_block_no_new_scope:
case slang_oper_block_new_scope:
case slang_oper_variable_decl:
case slang_oper_asm:
case slang_oper_break:
case slang_oper_continue:
case slang_oper_discard:
case slang_oper_return:
case slang_oper_if:
case slang_oper_while:
case slang_oper_do:
case slang_oper_for:
case slang_oper_void:
ti->spec.type = slang_spec_void;
break;
case slang_oper_expression:
case slang_oper_assign:
case slang_oper_addassign:
case slang_oper_subassign:
case slang_oper_mulassign:
case slang_oper_divassign:
case slang_oper_preincrement:
case slang_oper_predecrement:
if (!_slang_typeof_operation (op->children, space, ti))
return 0;
break;
case slang_oper_literal_bool:
case slang_oper_logicalor:
case slang_oper_logicalxor:
case slang_oper_logicaland:
case slang_oper_equal:
case slang_oper_notequal:
case slang_oper_less:
case slang_oper_greater:
case slang_oper_lessequal:
case slang_oper_greaterequal:
case slang_oper_not:
ti->spec.type = slang_spec_bool;
break;
case slang_oper_literal_int:
ti->spec.type = slang_spec_int;
break;
case slang_oper_literal_float:
ti->spec.type = slang_spec_float;
break;
case slang_oper_identifier:
{
slang_variable *var;
var = _slang_locate_variable (op->locals, op->identifier, 1);
if (var == NULL)
return 0;
if (!slang_type_specifier_copy (&ti->spec, &var->type.specifier))
return 0;
ti->can_be_referenced = 1;
}
break;
case slang_oper_sequence:
/* TODO: check [0] and [1] if they match */
if (!_slang_typeof_operation (op->children + 1, space, ti))
return 0;
ti->can_be_referenced = 0;
ti->is_swizzled = 0;
break;
/*case slang_oper_modassign:*/
/*case slang_oper_lshassign:*/
/*case slang_oper_rshassign:*/
/*case slang_oper_orassign:*/
/*case slang_oper_xorassign:*/
/*case slang_oper_andassign:*/
case slang_oper_select:
/* TODO: check [1] and [2] if they match */
if (!_slang_typeof_operation (op->children + 1, space, ti))
return 0;
ti->can_be_referenced = 0;
ti->is_swizzled = 0;
break;
/*case slang_oper_bitor:*/
/*case slang_oper_bitxor:*/
/*case slang_oper_bitand:*/
/*case slang_oper_lshift:*/
/*case slang_oper_rshift:*/
case slang_oper_add:
{
int exists;
if (!_slang_typeof_function ("+", op->children, 2, space, &ti->spec, &exists))
return 0;
if (!exists)
return 0;
}
break;
case slang_oper_subtract:
{
int exists;
if (!_slang_typeof_function ("-", op->children, 2, space, &ti->spec, &exists))
return 0;
if (!exists)
return 0;
}
break;
case slang_oper_multiply:
{
int exists;
if (!_slang_typeof_function ("*", op->children, 2, space, &ti->spec, &exists))
return 0;
if (!exists)
return 0;
}
break;
case slang_oper_divide:
{
int exists;
if (!_slang_typeof_function ("/", op->children, 2, space, &ti->spec, &exists))
return 0;
if (!exists)
return 0;
}
break;
/*case slang_oper_modulus:*/
case slang_oper_plus:
{
int exists;
if (!_slang_typeof_function ("+", op->children, 1, space, &ti->spec, &exists))
return 0;
if (!exists)
return 0;
}
break;
case slang_oper_minus:
{
int exists;
if (!_slang_typeof_function ("-", op->children, 1, space, &ti->spec, &exists))
return 0;
if (!exists)
return 0;
}
break;
/*case slang_oper_complement:*/
case slang_oper_subscript:
{
slang_assembly_typeinfo _ti;
slang_assembly_typeinfo_construct (&_ti);
if (!_slang_typeof_operation (op->children, space, &_ti))
{
slang_assembly_typeinfo_destruct (&_ti);
return 0;
}
ti->can_be_referenced = _ti.can_be_referenced;
switch (_ti.spec.type)
{
case slang_spec_bvec2:
case slang_spec_bvec3:
case slang_spec_bvec4:
ti->spec.type = slang_spec_bool;
break;
case slang_spec_ivec2:
case slang_spec_ivec3:
case slang_spec_ivec4:
ti->spec.type = slang_spec_int;
break;
case slang_spec_vec2:
case slang_spec_vec3:
case slang_spec_vec4:
ti->spec.type = slang_spec_float;
break;
case slang_spec_mat2:
ti->spec.type = slang_spec_vec2;
break;
case slang_spec_mat3:
ti->spec.type = slang_spec_vec3;
break;
case slang_spec_mat4:
ti->spec.type = slang_spec_vec4;
break;
case slang_spec_array:
if (!slang_type_specifier_copy (&ti->spec, _ti.spec._array))
{
slang_assembly_typeinfo_destruct (&_ti);
return 0;
}
break;
default:
slang_assembly_typeinfo_destruct (&_ti);
return 0;
}
slang_assembly_typeinfo_destruct (&_ti);
}
break;
case slang_oper_call:
{
int exists;
if (!_slang_typeof_function (op->identifier, op->children, op->num_children, space,
&ti->spec, &exists))
return 0;
if (!exists)
{
slang_struct *s = slang_struct_scope_find (space->structs, op->identifier, 1);
if (s != NULL)
{
ti->spec.type = slang_spec_struct;
ti->spec._struct = (slang_struct *) slang_alloc_malloc (sizeof (slang_struct));
if (ti->spec._struct == NULL)
return 0;
if (!slang_struct_construct_a (ti->spec._struct))
{
slang_alloc_free (ti->spec._struct);
ti->spec._struct = NULL;
return 0;
}
if (!slang_struct_copy (ti->spec._struct, s))
return 0;
}
else
{
slang_type_specifier_type type = slang_type_specifier_type_from_string (
op->identifier);
if (type == slang_spec_void)
return 0;
ti->spec.type = type;
}
}
}
break;
case slang_oper_field:
{
slang_assembly_typeinfo _ti;
slang_assembly_typeinfo_construct (&_ti);
if (!_slang_typeof_operation (op->children, space, &_ti))
{
slang_assembly_typeinfo_destruct (&_ti);
return 0;
}
if (_ti.spec.type == slang_spec_struct)
{
slang_variable *field = _slang_locate_variable (_ti.spec._struct->fields,
op->identifier, 0);
if (field == NULL)
{
slang_assembly_typeinfo_destruct (&_ti);
return 0;
}
if (!slang_type_specifier_copy (&ti->spec, &field->type.specifier))
{
slang_assembly_typeinfo_destruct (&_ti);
return 0;
}
}
else
{
unsigned int rows;
switch (_ti.spec.type)
{
case slang_spec_vec2:
case slang_spec_ivec2:
case slang_spec_bvec2:
rows = 2;
break;
case slang_spec_vec3:
case slang_spec_ivec3:
case slang_spec_bvec3:
rows = 3;
break;
case slang_spec_vec4:
case slang_spec_ivec4:
case slang_spec_bvec4:
rows = 4;
break;
default:
slang_assembly_typeinfo_destruct (&_ti);
return 0;
}
if (!_slang_is_swizzle (op->identifier, rows, &ti->swz))
return 0;
ti->is_swizzled = 1;
ti->can_be_referenced = _ti.can_be_referenced && _slang_is_swizzle_mask (&ti->swz,
rows);
if (_ti.is_swizzled)
{
slang_swizzle swz;
_slang_multiply_swizzles (&swz, &_ti.swz, &ti->swz);
ti->swz = swz;
}
switch (_ti.spec.type)
{
case slang_spec_vec2:
case slang_spec_vec3:
case slang_spec_vec4:
switch (ti->swz.num_components)
{
case 1:
ti->spec.type = slang_spec_float;
break;
case 2:
ti->spec.type = slang_spec_vec2;
break;
case 3:
ti->spec.type = slang_spec_vec3;
break;
case 4:
ti->spec.type = slang_spec_vec4;
break;
}
break;
case slang_spec_ivec2:
case slang_spec_ivec3:
case slang_spec_ivec4:
switch (ti->swz.num_components)
{
case 1:
ti->spec.type = slang_spec_int;
break;
case 2:
ti->spec.type = slang_spec_ivec2;
break;
case 3:
ti->spec.type = slang_spec_ivec3;
break;
case 4:
ti->spec.type = slang_spec_ivec4;
break;
}
break;
case slang_spec_bvec2:
case slang_spec_bvec3:
case slang_spec_bvec4:
switch (ti->swz.num_components)
{
case 1:
ti->spec.type = slang_spec_bool;
break;
case 2:
ti->spec.type = slang_spec_bvec2;
break;
case 3:
ti->spec.type = slang_spec_bvec3;
break;
case 4:
ti->spec.type = slang_spec_bvec4;
break;
}
break;
default:
break;
}
}
slang_assembly_typeinfo_destruct (&_ti);
return 1;
}
break;
case slang_oper_postincrement:
case slang_oper_postdecrement:
if (!_slang_typeof_operation (op->children, space, ti))
return 0;
ti->can_be_referenced = 0;
ti->is_swizzled = 0;
break;
default:
return 0;
}
return 1;
}
/* _slang_typeof_function() */
int _slang_typeof_function (const char *name, slang_operation *params, unsigned int num_params,
slang_assembly_name_space *space, slang_type_specifier *spec, int *exists)
{
slang_function *fun = _slang_locate_function (name, params, num_params, space);
*exists = fun != NULL;
if (fun == NULL)
return 1;
return slang_type_specifier_copy (spec, &fun->header.type.specifier);
}
/*
* Mesa 3-D graphics library
* Version: 6.3
*
* Copyright (C) 2005 Brian Paul All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
/**
* \file slang_assemble_typeinfo.c
* slang type info
* \author Michal Krol
*/
#include "imports.h"
#include "slang_utility.h"
#include "slang_assemble_typeinfo.h"
/* slang_assembly_typeinfo */
void slang_assembly_typeinfo_construct (slang_assembly_typeinfo *ti)
{
slang_type_specifier_construct (&ti->spec);
}
void slang_assembly_typeinfo_destruct (slang_assembly_typeinfo *ti)
{
slang_type_specifier_destruct (&ti->spec);
}
/* _slang_typeof_operation() */
int _slang_typeof_operation (slang_operation *op, slang_assembly_name_space *space,
slang_assembly_typeinfo *ti)
{
ti->can_be_referenced = 0;
ti->is_swizzled = 0;
switch (op->type)
{
case slang_oper_block_no_new_scope:
case slang_oper_block_new_scope:
case slang_oper_variable_decl:
case slang_oper_asm:
case slang_oper_break:
case slang_oper_continue:
case slang_oper_discard:
case slang_oper_return:
case slang_oper_if:
case slang_oper_while:
case slang_oper_do:
case slang_oper_for:
case slang_oper_void:
ti->spec.type = slang_spec_void;
break;
case slang_oper_expression:
case slang_oper_assign:
case slang_oper_addassign:
case slang_oper_subassign:
case slang_oper_mulassign:
case slang_oper_divassign:
case slang_oper_preincrement:
case slang_oper_predecrement:
if (!_slang_typeof_operation (op->children, space, ti))
return 0;
break;
case slang_oper_literal_bool:
case slang_oper_logicalor:
case slang_oper_logicalxor:
case slang_oper_logicaland:
case slang_oper_equal:
case slang_oper_notequal:
case slang_oper_less:
case slang_oper_greater:
case slang_oper_lessequal:
case slang_oper_greaterequal:
case slang_oper_not:
ti->spec.type = slang_spec_bool;
break;
case slang_oper_literal_int:
ti->spec.type = slang_spec_int;
break;
case slang_oper_literal_float:
ti->spec.type = slang_spec_float;
break;
case slang_oper_identifier:
{
slang_variable *var;
var = _slang_locate_variable (op->locals, op->identifier, 1);
if (var == NULL)
return 0;
if (!slang_type_specifier_copy (&ti->spec, &var->type.specifier))
return 0;
ti->can_be_referenced = 1;
}
break;
case slang_oper_sequence:
/* TODO: check [0] and [1] if they match */
if (!_slang_typeof_operation (op->children + 1, space, ti))
return 0;
ti->can_be_referenced = 0;
ti->is_swizzled = 0;
break;
/*case slang_oper_modassign:*/
/*case slang_oper_lshassign:*/
/*case slang_oper_rshassign:*/
/*case slang_oper_orassign:*/
/*case slang_oper_xorassign:*/
/*case slang_oper_andassign:*/
case slang_oper_select:
/* TODO: check [1] and [2] if they match */
if (!_slang_typeof_operation (op->children + 1, space, ti))
return 0;
ti->can_be_referenced = 0;
ti->is_swizzled = 0;
break;
/*case slang_oper_bitor:*/
/*case slang_oper_bitxor:*/
/*case slang_oper_bitand:*/
/*case slang_oper_lshift:*/
/*case slang_oper_rshift:*/
case slang_oper_add:
{
int exists;
if (!_slang_typeof_function ("+", op->children, 2, space, &ti->spec, &exists))
return 0;
if (!exists)
return 0;
}
break;
case slang_oper_subtract:
{
int exists;
if (!_slang_typeof_function ("-", op->children, 2, space, &ti->spec, &exists))
return 0;
if (!exists)
return 0;
}
break;
case slang_oper_multiply:
{
int exists;
if (!_slang_typeof_function ("*", op->children, 2, space, &ti->spec, &exists))
return 0;
if (!exists)
return 0;
}
break;
case slang_oper_divide:
{
int exists;
if (!_slang_typeof_function ("/", op->children, 2, space, &ti->spec, &exists))
return 0;
if (!exists)
return 0;
}
break;
/*case slang_oper_modulus:*/
case slang_oper_plus:
{
int exists;
if (!_slang_typeof_function ("+", op->children, 1, space, &ti->spec, &exists))
return 0;
if (!exists)
return 0;
}
break;
case slang_oper_minus:
{
int exists;
if (!_slang_typeof_function ("-", op->children, 1, space, &ti->spec, &exists))
return 0;
if (!exists)
return 0;
}
break;
/*case slang_oper_complement:*/
case slang_oper_subscript:
{
slang_assembly_typeinfo _ti;
slang_assembly_typeinfo_construct (&_ti);
if (!_slang_typeof_operation (op->children, space, &_ti))
{
slang_assembly_typeinfo_destruct (&_ti);
return 0;
}
ti->can_be_referenced = _ti.can_be_referenced;
switch (_ti.spec.type)
{
case slang_spec_bvec2:
case slang_spec_bvec3:
case slang_spec_bvec4:
ti->spec.type = slang_spec_bool;
break;
case slang_spec_ivec2:
case slang_spec_ivec3:
case slang_spec_ivec4:
ti->spec.type = slang_spec_int;
break;
case slang_spec_vec2:
case slang_spec_vec3:
case slang_spec_vec4:
ti->spec.type = slang_spec_float;
break;
case slang_spec_mat2:
ti->spec.type = slang_spec_vec2;
break;
case slang_spec_mat3:
ti->spec.type = slang_spec_vec3;
break;
case slang_spec_mat4:
ti->spec.type = slang_spec_vec4;
break;
case slang_spec_array:
if (!slang_type_specifier_copy (&ti->spec, _ti.spec._array))
{
slang_assembly_typeinfo_destruct (&_ti);
return 0;
}
break;
default:
slang_assembly_typeinfo_destruct (&_ti);
return 0;
}
slang_assembly_typeinfo_destruct (&_ti);
}
break;
case slang_oper_call:
{
int exists;
if (!_slang_typeof_function (op->identifier, op->children, op->num_children, space,
&ti->spec, &exists))
return 0;
if (!exists)
{
slang_struct *s = slang_struct_scope_find (space->structs, op->identifier, 1);
if (s != NULL)
{
ti->spec.type = slang_spec_struct;
ti->spec._struct = (slang_struct *) slang_alloc_malloc (sizeof (slang_struct));
if (ti->spec._struct == NULL)
return 0;
if (!slang_struct_construct_a (ti->spec._struct))
{
slang_alloc_free (ti->spec._struct);
ti->spec._struct = NULL;
return 0;
}
if (!slang_struct_copy (ti->spec._struct, s))
return 0;
}
else
{
slang_type_specifier_type type = slang_type_specifier_type_from_string (
op->identifier);
if (type == slang_spec_void)
return 0;
ti->spec.type = type;
}
}
}
break;
case slang_oper_field:
{
slang_assembly_typeinfo _ti;
slang_assembly_typeinfo_construct (&_ti);
if (!_slang_typeof_operation (op->children, space, &_ti))
{
slang_assembly_typeinfo_destruct (&_ti);
return 0;
}
if (_ti.spec.type == slang_spec_struct)
{
slang_variable *field = _slang_locate_variable (_ti.spec._struct->fields,
op->identifier, 0);
if (field == NULL)
{
slang_assembly_typeinfo_destruct (&_ti);
return 0;
}
if (!slang_type_specifier_copy (&ti->spec, &field->type.specifier))
{
slang_assembly_typeinfo_destruct (&_ti);
return 0;
}
}
else
{
unsigned int rows;
switch (_ti.spec.type)
{
case slang_spec_vec2:
case slang_spec_ivec2:
case slang_spec_bvec2:
rows = 2;
break;
case slang_spec_vec3:
case slang_spec_ivec3:
case slang_spec_bvec3:
rows = 3;
break;
case slang_spec_vec4:
case slang_spec_ivec4:
case slang_spec_bvec4:
rows = 4;
break;
default:
slang_assembly_typeinfo_destruct (&_ti);
return 0;
}
if (!_slang_is_swizzle (op->identifier, rows, &ti->swz))
return 0;
ti->is_swizzled = 1;
ti->can_be_referenced = _ti.can_be_referenced && _slang_is_swizzle_mask (&ti->swz,
rows);
if (_ti.is_swizzled)
{
slang_swizzle swz;
_slang_multiply_swizzles (&swz, &_ti.swz, &ti->swz);
ti->swz = swz;
}
switch (_ti.spec.type)
{
case slang_spec_vec2:
case slang_spec_vec3:
case slang_spec_vec4:
switch (ti->swz.num_components)
{
case 1:
ti->spec.type = slang_spec_float;
break;
case 2:
ti->spec.type = slang_spec_vec2;
break;
case 3:
ti->spec.type = slang_spec_vec3;
break;
case 4:
ti->spec.type = slang_spec_vec4;
break;
}
break;
case slang_spec_ivec2:
case slang_spec_ivec3:
case slang_spec_ivec4:
switch (ti->swz.num_components)
{
case 1:
ti->spec.type = slang_spec_int;
break;
case 2:
ti->spec.type = slang_spec_ivec2;
break;
case 3:
ti->spec.type = slang_spec_ivec3;
break;
case 4:
ti->spec.type = slang_spec_ivec4;
break;
}
break;
case slang_spec_bvec2:
case slang_spec_bvec3:
case slang_spec_bvec4:
switch (ti->swz.num_components)
{
case 1:
ti->spec.type = slang_spec_bool;
break;
case 2:
ti->spec.type = slang_spec_bvec2;
break;
case 3:
ti->spec.type = slang_spec_bvec3;
break;
case 4:
ti->spec.type = slang_spec_bvec4;
break;
}
break;
default:
break;
}
}
slang_assembly_typeinfo_destruct (&_ti);
return 1;
}
break;
case slang_oper_postincrement:
case slang_oper_postdecrement:
if (!_slang_typeof_operation (op->children, space, ti))
return 0;
ti->can_be_referenced = 0;
ti->is_swizzled = 0;
break;
default:
return 0;
}
return 1;
}
/* _slang_typeof_function() */
int _slang_typeof_function (const char *name, slang_operation *params, unsigned int num_params,
slang_assembly_name_space *space, slang_type_specifier *spec, int *exists)
{
slang_function *fun = _slang_locate_function (name, params, num_params, space);
*exists = fun != NULL;
if (fun == NULL)
return 1;
return slang_type_specifier_copy (spec, &fun->header.type.specifier);
}
/*
* Mesa 3-D graphics library
* Version: 6.3
*
* Copyright (C) 2005 Brian Paul All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#if !defined SLANG_ASSEMBLE_TYPEINFO_H
#define SLANG_ASSEMBLE_TYPEINFO_H
#include "slang_assemble_constructor.h"
#include "slang_compile.h"
#if defined __cplusplus
extern "C" {
#endif
typedef struct slang_assembly_typeinfo_
{
int can_be_referenced;
int is_swizzled;
slang_swizzle swz;
slang_type_specifier spec;
} slang_assembly_typeinfo;
void slang_assembly_typeinfo_construct (slang_assembly_typeinfo *);
void slang_assembly_typeinfo_destruct (slang_assembly_typeinfo *);
/*
retrieves type information about an operation
returns 1 on success
returns 0 otherwise
*/
int _slang_typeof_operation (slang_operation *, slang_assembly_name_space *,
slang_assembly_typeinfo *);
/*
retrieves type of a function prototype, if one exists
returns 1 on success, even if the function was not found
returns 0 otherwise
*/
int _slang_typeof_function (const char *name, slang_operation *params, unsigned int num_params,
slang_assembly_name_space *space, slang_type_specifier *spec, int *exists);
#ifdef __cplusplus
}
#endif
#endif
/*
* Mesa 3-D graphics library
* Version: 6.3
*
* Copyright (C) 2005 Brian Paul All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#if !defined SLANG_ASSEMBLE_TYPEINFO_H
#define SLANG_ASSEMBLE_TYPEINFO_H
#include "slang_assemble_constructor.h"
#include "slang_compile.h"
#if defined __cplusplus
extern "C" {
#endif
typedef struct slang_assembly_typeinfo_
{
int can_be_referenced;
int is_swizzled;
slang_swizzle swz;
slang_type_specifier spec;
} slang_assembly_typeinfo;
void slang_assembly_typeinfo_construct (slang_assembly_typeinfo *);
void slang_assembly_typeinfo_destruct (slang_assembly_typeinfo *);
/*
retrieves type information about an operation
returns 1 on success
returns 0 otherwise
*/
int _slang_typeof_operation (slang_operation *, slang_assembly_name_space *,
slang_assembly_typeinfo *);
/*
retrieves type of a function prototype, if one exists
returns 1 on success, even if the function was not found
returns 0 otherwise
*/
int _slang_typeof_function (const char *name, slang_operation *params, unsigned int num_params,
slang_assembly_name_space *space, slang_type_specifier *spec, int *exists);
#ifdef __cplusplus
}
#endif
#endif
......@@ -68,8 +68,8 @@ typedef enum slang_type_specifier_type_
slang_spec_sampler2DShadow,
slang_spec_struct,
slang_spec_array
} slang_type_specifier_type;
} slang_type_specifier_type;
slang_type_specifier_type slang_type_specifier_type_from_string (const char *);
typedef struct slang_type_specifier_
......@@ -77,11 +77,11 @@ typedef struct slang_type_specifier_
slang_type_specifier_type type;
struct slang_struct_ *_struct; /* spec_struct */
struct slang_type_specifier_ *_array; /* spec_array */
} slang_type_specifier;
void slang_type_specifier_construct (slang_type_specifier *);
void slang_type_specifier_destruct (slang_type_specifier *);
int slang_type_specifier_copy (slang_type_specifier *, const slang_type_specifier *);
} slang_type_specifier;
void slang_type_specifier_construct (slang_type_specifier *);
void slang_type_specifier_destruct (slang_type_specifier *);
int slang_type_specifier_copy (slang_type_specifier *, const slang_type_specifier *);
int slang_type_specifier_equal (const slang_type_specifier *, const slang_type_specifier *);
typedef struct slang_fully_specified_type_
......@@ -171,9 +171,9 @@ typedef struct slang_operation_
float literal; /* bool, literal_int, literal_float */
char *identifier; /* asm, identifier, call, field */
slang_variable_scope *locals;
} slang_operation;
int slang_operation_construct_a (slang_operation *);
} slang_operation;
int slang_operation_construct_a (slang_operation *);
void slang_operation_destruct (slang_operation *);
typedef struct slang_variable_
......@@ -181,10 +181,10 @@ typedef struct slang_variable_
slang_fully_specified_type type;
char *name;
slang_operation *array_size; /* spec_array */
slang_operation *initializer;
slang_operation *initializer;
unsigned int address;
} slang_variable;
} slang_variable;
slang_variable *_slang_locate_variable (slang_variable_scope *scope, const char *name, int all);
typedef struct slang_struct_scope_
......@@ -192,8 +192,8 @@ typedef struct slang_struct_scope_
struct slang_struct_ *structs;
unsigned int num_structs;
struct slang_struct_scope_ *outer_scope;
} slang_struct_scope;
} slang_struct_scope;
struct slang_struct_ *slang_struct_scope_find (slang_struct_scope *, const char *, int);
typedef struct slang_struct_
......@@ -201,9 +201,9 @@ typedef struct slang_struct_
char *name;
slang_variable_scope *fields;
slang_struct_scope *structs;
} slang_struct;
int slang_struct_construct_a (slang_struct *);
} slang_struct;
int slang_struct_construct_a (slang_struct *);
int slang_struct_copy (slang_struct *, const slang_struct *);
typedef enum slang_function_kind_
......@@ -219,7 +219,7 @@ typedef struct slang_function_
slang_variable header;
slang_variable_scope *parameters;
unsigned int param_count;
slang_operation *body;
slang_operation *body;
unsigned int address;
} slang_function;
......
/*
* Mesa 3-D graphics library
* Version: 6.3
*
* Copyright (C) 2005 Brian Paul All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
/**
* \file slang_execute.c
* intermediate code interpreter
* \author Michal Krol
*/
#include "imports.h"
#include "slang_utility.h"
#include "slang_assemble.h"
#include "slang_storage.h"
#include "slang_execute.h"
static void dump_instruction (FILE *f, slang_assembly *a, unsigned int i)
{
fprintf (f, "%.5u:\t", i);
switch (a->type)
{
case slang_asm_none:
fprintf (f, "none");
break;
case slang_asm_float_copy:
fprintf (f, "float_copy\t%d, %d", a->param[0], a->param[1]);
break;
case slang_asm_float_move:
fprintf (f, "float_move\t%d, %d", a->param[0], a->param[1]);
break;
case slang_asm_float_push:
fprintf (f, "float_push\t%f", a->literal);
break;
case slang_asm_float_deref:
fprintf (f, "float_deref");
break;
case slang_asm_float_add:
fprintf (f, "float_add");
break;
case slang_asm_float_multiply:
fprintf (f, "float_multiply");
break;
case slang_asm_float_divide:
fprintf (f, "float_divide");
break;
case slang_asm_float_negate:
fprintf (f, "float_negate");
break;
case slang_asm_float_less:
fprintf (f, "float_less");
break;
case slang_asm_float_equal:
fprintf (f, "float_equal\t%d, %d", a->param[0], a->param[1]);
break;
case slang_asm_float_to_int:
fprintf (f, "float_to_int");
break;
case slang_asm_int_copy:
fprintf (f, "int_copy\t%d, %d", a->param[0], a->param[1]);
break;
case slang_asm_int_move:
fprintf (f, "int_move\t%d, %d", a->param[0], a->param[1]);
break;
case slang_asm_int_push:
fprintf (f, "int_push\t%d", (GLint) a->literal);
break;
case slang_asm_int_deref:
fprintf (f, "int_deref");
break;
case slang_asm_int_to_float:
fprintf (f, "int_to_float");
break;
case slang_asm_int_to_addr:
fprintf (f, "int_to_addr");
break;
case slang_asm_bool_copy:
fprintf (f, "bool_copy\t%d, %d", a->param[0], a->param[1]);
break;
case slang_asm_bool_move:
fprintf (f, "bool_move\t%d, %d", a->param[0], a->param[1]);
break;
case slang_asm_bool_push:
fprintf (f, "bool_push\t%d", a->literal != 0.0f);
break;
case slang_asm_bool_deref:
fprintf (f, "bool_deref");
break;
case slang_asm_addr_copy:
fprintf (f, "addr_copy");
break;
case slang_asm_addr_push:
fprintf (f, "addr_push\t%u", a->param[0]);
break;
case slang_asm_addr_deref:
fprintf (f, "addr_deref");
break;
case slang_asm_addr_add:
fprintf (f, "addr_add");
break;
case slang_asm_addr_multiply:
fprintf (f, "addr_multiply");
break;
case slang_asm_jump:
fprintf (f, "jump\t%u", a->param[0]);
break;
case slang_asm_jump_if_zero:
fprintf (f, "jump_if_zero\t%u", a->param[0]);
break;
case slang_asm_enter:
fprintf (f, "enter\t%u", a->param[0]);
break;
case slang_asm_leave:
fprintf (f, "leave");
break;
case slang_asm_local_alloc:
fprintf (f, "local_alloc\t%u", a->param[0]);
break;
case slang_asm_local_free:
fprintf (f, "local_free\t%u", a->param[0]);
break;
case slang_asm_local_addr:
fprintf (f, "local_addr\t%u, %u", a->param[0], a->param[1]);
break;
case slang_asm_call:
fprintf (f, "call\t%u", a->param[0]);
break;
case slang_asm_return:
fprintf (f, "return");
break;
case slang_asm_discard:
fprintf (f, "discard");
break;
case slang_asm_exit:
fprintf (f, "exit");
break;
default:
break;
}
fprintf (f, "\n");
}
static void dump (const slang_assembly_file *file)
{
unsigned int i;
static unsigned int counter = 0;
FILE *f;
char filename[256];
counter++;
sprintf (filename, "~mesa-slang-assembly-dump-(%u).txt", counter);
f = fopen (filename, "w");
if (f == NULL)
return;
for (i = 0; i < file->count; i++)
dump_instruction (f, file->code + i, i);
fclose (f);
}
int _slang_execute (const slang_assembly_file *file)
{
slang_machine mach;
FILE *f;
mach.ip = 0;
mach.sp = SLANG_MACHINE_STACK_SIZE;
mach.bp = 0;
mach.kill = 0;
mach.exit = 0;
/* assume 32-bit machine */
/* XXX why???, disabling the pointer size assertions here.
* See bug 4021.
*/
_static_assert(sizeof (GLfloat) == 4);
/*_static_assert(sizeof (GLfloat *) == 4);*/
_static_assert(sizeof (GLuint) == 4);
/*_static_assert(sizeof (GLuint *) == 4);*/
dump (file);
f = fopen ("~mesa-slang-assembly-execution.txt", "w");
while (!mach.exit)
{
slang_assembly *a = file->code + mach.ip;
if (f != NULL)
{
unsigned int i;
dump_instruction (f, a, mach.ip);
fprintf (f, "\t\tsp=%u bp=%u\n", mach.sp, mach.bp);
for (i = mach.sp; i < SLANG_MACHINE_STACK_SIZE; i++)
fprintf (f, "\t%.5u\t%6f\t%u\n", i, mach.stack._float[i], mach.stack._addr[i]);
fflush (f);
}
mach.ip++;
switch (a->type)
{
case slang_asm_none:
break;
case slang_asm_float_copy:
case slang_asm_int_copy:
case slang_asm_bool_copy:
*(mach.stack._floatp[mach.sp + a->param[0] / 4] + a->param[1] / 4) =
mach.stack._float[mach.sp];
mach.sp++;
break;
case slang_asm_float_move:
case slang_asm_int_move:
case slang_asm_bool_move:
mach.stack._float[mach.sp + a->param[0] / 4] =
mach.stack._float[mach.sp + (mach.stack._addr[mach.sp] + a->param[1]) / 4];
break;
case slang_asm_float_push:
case slang_asm_int_push:
case slang_asm_bool_push:
mach.sp--;
mach.stack._float[mach.sp] = a->literal;
break;
case slang_asm_float_deref:
case slang_asm_int_deref:
case slang_asm_bool_deref:
mach.stack._float[mach.sp] = *mach.stack._floatp[mach.sp];
break;
case slang_asm_float_add:
mach.stack._float[mach.sp + 1] += mach.stack._float[mach.sp];
mach.sp++;
break;
case slang_asm_float_multiply:
mach.stack._float[mach.sp + 1] *= mach.stack._float[mach.sp];
mach.sp++;
break;
case slang_asm_float_divide:
mach.stack._float[mach.sp + 1] /= mach.stack._float[mach.sp];
mach.sp++;
break;
case slang_asm_float_negate:
mach.stack._float[mach.sp] = -mach.stack._float[mach.sp];
break;
case slang_asm_float_less:
mach.stack._float[mach.sp + 1] =
mach.stack._float[mach.sp + 1] < mach.stack._float[mach.sp] ? 1.0f : 0.0f;
mach.sp++;
break;
case slang_asm_float_equal:
mach.sp--;
mach.stack._float[mach.sp] = mach.stack._float[mach.sp + 1 + a->param[0] / 4] ==
mach.stack._float[mach.sp + 1 + a->param[1] / 4] ? 1.0f : 0.0f;
break;
case slang_asm_float_to_int:
mach.stack._float[mach.sp] = (GLfloat) (GLint) mach.stack._float[mach.sp];
break;
case slang_asm_int_to_float:
break;
case slang_asm_int_to_addr:
mach.stack._addr[mach.sp] = (GLuint) (GLint) mach.stack._float[mach.sp];
break;
case slang_asm_addr_copy:
*mach.stack._addrp[mach.sp + 1] = mach.stack._addr[mach.sp];
mach.sp++;
break;
case slang_asm_addr_push:
mach.sp--;
mach.stack._addr[mach.sp] = a->param[0];
break;
case slang_asm_addr_deref:
mach.stack._addr[mach.sp] = *mach.stack._addrp[mach.sp];
break;
case slang_asm_addr_add:
mach.stack._addr[mach.sp + 1] += mach.stack._addr[mach.sp];
mach.sp++;
break;
case slang_asm_addr_multiply:
mach.stack._addr[mach.sp + 1] *= mach.stack._addr[mach.sp];
mach.sp++;
break;
case slang_asm_jump:
mach.ip = a->param[0];
break;
case slang_asm_jump_if_zero:
if (mach.stack._float[mach.sp] == 0.0f)
mach.ip = a->param[0];
mach.sp++;
break;
case slang_asm_enter:
mach.sp--;
mach.stack._addr[mach.sp] = mach.bp;
mach.bp = mach.sp + a->param[0] / 4;
break;
case slang_asm_leave:
mach.bp = mach.stack._addr[mach.sp];
mach.sp++;
break;
case slang_asm_local_alloc:
mach.sp -= a->param[0] / 4;
break;
case slang_asm_local_free:
mach.sp += a->param[0] / 4;
break;
case slang_asm_local_addr:
mach.sp--;
mach.stack._addr[mach.sp] = (GLuint) mach.stack._addr + mach.bp * 4 -
(a->param[0] + a->param[1]) + 4;
break;
case slang_asm_call:
mach.sp--;
mach.stack._addr[mach.sp] = mach.ip;
mach.ip = a->param[0];
break;
case slang_asm_return:
mach.ip = mach.stack._addr[mach.sp];
mach.sp++;
break;
case slang_asm_discard:
mach.kill = 1;
break;
case slang_asm_exit:
mach.exit = 1;
break;
}
}
if (f != NULL)
fclose (f);
return 0;
}
/*
* Mesa 3-D graphics library
* Version: 6.3
*
* Copyright (C) 2005 Brian Paul All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
/**
* \file slang_execute.c
* intermediate code interpreter
* \author Michal Krol
*/
#include "imports.h"
#include "slang_utility.h"
#include "slang_assemble.h"
#include "slang_storage.h"
#include "slang_execute.h"
static void dump_instruction (FILE *f, slang_assembly *a, unsigned int i)
{
fprintf (f, "%.5u:\t", i);
switch (a->type)
{
case slang_asm_none:
fprintf (f, "none");
break;
case slang_asm_float_copy:
fprintf (f, "float_copy\t%d, %d", a->param[0], a->param[1]);
break;
case slang_asm_float_move:
fprintf (f, "float_move\t%d, %d", a->param[0], a->param[1]);
break;
case slang_asm_float_push:
fprintf (f, "float_push\t%f", a->literal);
break;
case slang_asm_float_deref:
fprintf (f, "float_deref");
break;
case slang_asm_float_add:
fprintf (f, "float_add");
break;
case slang_asm_float_multiply:
fprintf (f, "float_multiply");
break;
case slang_asm_float_divide:
fprintf (f, "float_divide");
break;
case slang_asm_float_negate:
fprintf (f, "float_negate");
break;
case slang_asm_float_less:
fprintf (f, "float_less");
break;
case slang_asm_float_equal:
fprintf (f, "float_equal\t%d, %d", a->param[0], a->param[1]);
break;
case slang_asm_float_to_int:
fprintf (f, "float_to_int");
break;
case slang_asm_int_copy:
fprintf (f, "int_copy\t%d, %d", a->param[0], a->param[1]);
break;
case slang_asm_int_move:
fprintf (f, "int_move\t%d, %d", a->param[0], a->param[1]);
break;
case slang_asm_int_push:
fprintf (f, "int_push\t%d", (GLint) a->literal);
break;
case slang_asm_int_deref:
fprintf (f, "int_deref");
break;
case slang_asm_int_to_float:
fprintf (f, "int_to_float");
break;
case slang_asm_int_to_addr:
fprintf (f, "int_to_addr");
break;
case slang_asm_bool_copy:
fprintf (f, "bool_copy\t%d, %d", a->param[0], a->param[1]);
break;
case slang_asm_bool_move:
fprintf (f, "bool_move\t%d, %d", a->param[0], a->param[1]);
break;
case slang_asm_bool_push:
fprintf (f, "bool_push\t%d", a->literal != 0.0f);
break;
case slang_asm_bool_deref:
fprintf (f, "bool_deref");
break;
case slang_asm_addr_copy:
fprintf (f, "addr_copy");
break;
case slang_asm_addr_push:
fprintf (f, "addr_push\t%u", a->param[0]);
break;
case slang_asm_addr_deref:
fprintf (f, "addr_deref");
break;
case slang_asm_addr_add:
fprintf (f, "addr_add");
break;
case slang_asm_addr_multiply:
fprintf (f, "addr_multiply");
break;
case slang_asm_jump:
fprintf (f, "jump\t%u", a->param[0]);
break;
case slang_asm_jump_if_zero:
fprintf (f, "jump_if_zero\t%u", a->param[0]);
break;
case slang_asm_enter:
fprintf (f, "enter\t%u", a->param[0]);
break;
case slang_asm_leave:
fprintf (f, "leave");
break;
case slang_asm_local_alloc:
fprintf (f, "local_alloc\t%u", a->param[0]);
break;
case slang_asm_local_free:
fprintf (f, "local_free\t%u", a->param[0]);
break;
case slang_asm_local_addr:
fprintf (f, "local_addr\t%u, %u", a->param[0], a->param[1]);
break;
case slang_asm_call:
fprintf (f, "call\t%u", a->param[0]);
break;
case slang_asm_return:
fprintf (f, "return");
break;
case slang_asm_discard:
fprintf (f, "discard");
break;
case slang_asm_exit:
fprintf (f, "exit");
break;
default:
break;
}
fprintf (f, "\n");
}
static void dump (const slang_assembly_file *file)
{
unsigned int i;
static unsigned int counter = 0;
FILE *f;
char filename[256];
counter++;
sprintf (filename, "~mesa-slang-assembly-dump-(%u).txt", counter);
f = fopen (filename, "w");
if (f == NULL)
return;
for (i = 0; i < file->count; i++)
dump_instruction (f, file->code + i, i);
fclose (f);
}
int _slang_execute (const slang_assembly_file *file)
{
slang_machine mach;
FILE *f;
mach.ip = 0;
mach.sp = SLANG_MACHINE_STACK_SIZE;
mach.bp = 0;
mach.kill = 0;
mach.exit = 0;
/* assume 32-bit machine */
/* XXX why???, disabling the pointer size assertions here.
* See bug 4021.
*/
_static_assert(sizeof (GLfloat) == 4);
/*_static_assert(sizeof (GLfloat *) == 4);*/
_static_assert(sizeof (GLuint) == 4);
/*_static_assert(sizeof (GLuint *) == 4);*/
dump (file);
f = fopen ("~mesa-slang-assembly-execution.txt", "w");
while (!mach.exit)
{
slang_assembly *a = file->code + mach.ip;
if (f != NULL)
{
unsigned int i;
dump_instruction (f, a, mach.ip);
fprintf (f, "\t\tsp=%u bp=%u\n", mach.sp, mach.bp);
for (i = mach.sp; i < SLANG_MACHINE_STACK_SIZE; i++)
fprintf (f, "\t%.5u\t%6f\t%u\n", i, mach.stack._float[i], mach.stack._addr[i]);
fflush (f);
}
mach.ip++;
switch (a->type)
{
case slang_asm_none:
break;
case slang_asm_float_copy:
case slang_asm_int_copy:
case slang_asm_bool_copy:
*(mach.stack._floatp[mach.sp + a->param[0] / 4] + a->param[1] / 4) =
mach.stack._float[mach.sp];
mach.sp++;
break;
case slang_asm_float_move:
case slang_asm_int_move:
case slang_asm_bool_move:
mach.stack._float[mach.sp + a->param[0] / 4] =
mach.stack._float[mach.sp + (mach.stack._addr[mach.sp] + a->param[1]) / 4];
break;
case slang_asm_float_push:
case slang_asm_int_push:
case slang_asm_bool_push:
mach.sp--;
mach.stack._float[mach.sp] = a->literal;
break;
case slang_asm_float_deref:
case slang_asm_int_deref:
case slang_asm_bool_deref:
mach.stack._float[mach.sp] = *mach.stack._floatp[mach.sp];
break;
case slang_asm_float_add:
mach.stack._float[mach.sp + 1] += mach.stack._float[mach.sp];
mach.sp++;
break;
case slang_asm_float_multiply:
mach.stack._float[mach.sp + 1] *= mach.stack._float[mach.sp];
mach.sp++;
break;
case slang_asm_float_divide:
mach.stack._float[mach.sp + 1] /= mach.stack._float[mach.sp];
mach.sp++;
break;
case slang_asm_float_negate:
mach.stack._float[mach.sp] = -mach.stack._float[mach.sp];
break;
case slang_asm_float_less:
mach.stack._float[mach.sp + 1] =
mach.stack._float[mach.sp + 1] < mach.stack._float[mach.sp] ? 1.0f : 0.0f;
mach.sp++;
break;
case slang_asm_float_equal:
mach.sp--;
mach.stack._float[mach.sp] = mach.stack._float[mach.sp + 1 + a->param[0] / 4] ==
mach.stack._float[mach.sp + 1 + a->param[1] / 4] ? 1.0f : 0.0f;
break;
case slang_asm_float_to_int:
mach.stack._float[mach.sp] = (GLfloat) (GLint) mach.stack._float[mach.sp];
break;
case slang_asm_int_to_float:
break;
case slang_asm_int_to_addr:
mach.stack._addr[mach.sp] = (GLuint) (GLint) mach.stack._float[mach.sp];
break;
case slang_asm_addr_copy:
*mach.stack._addrp[mach.sp + 1] = mach.stack._addr[mach.sp];
mach.sp++;
break;
case slang_asm_addr_push:
mach.sp--;
mach.stack._addr[mach.sp] = a->param[0];
break;
case slang_asm_addr_deref:
mach.stack._addr[mach.sp] = *mach.stack._addrp[mach.sp];
break;
case slang_asm_addr_add:
mach.stack._addr[mach.sp + 1] += mach.stack._addr[mach.sp];
mach.sp++;
break;
case slang_asm_addr_multiply:
mach.stack._addr[mach.sp + 1] *= mach.stack._addr[mach.sp];
mach.sp++;
break;
case slang_asm_jump:
mach.ip = a->param[0];
break;
case slang_asm_jump_if_zero:
if (mach.stack._float[mach.sp] == 0.0f)
mach.ip = a->param[0];
mach.sp++;
break;
case slang_asm_enter:
mach.sp--;
mach.stack._addr[mach.sp] = mach.bp;
mach.bp = mach.sp + a->param[0] / 4;
break;
case slang_asm_leave:
mach.bp = mach.stack._addr[mach.sp];
mach.sp++;
break;
case slang_asm_local_alloc:
mach.sp -= a->param[0] / 4;
break;
case slang_asm_local_free:
mach.sp += a->param[0] / 4;
break;
case slang_asm_local_addr:
mach.sp--;
mach.stack._addr[mach.sp] = (GLuint) mach.stack._addr + mach.bp * 4 -
(a->param[0] + a->param[1]) + 4;
break;
case slang_asm_call:
mach.sp--;
mach.stack._addr[mach.sp] = mach.ip;
mach.ip = a->param[0];
break;
case slang_asm_return:
mach.ip = mach.stack._addr[mach.sp];
mach.sp++;
break;
case slang_asm_discard:
mach.kill = 1;
break;
case slang_asm_exit:
mach.exit = 1;
break;
}
}
if (f != NULL)
fclose (f);
return 0;
}
/*
* Mesa 3-D graphics library
* Version: 6.3
*
* Copyright (C) 2005 Brian Paul All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#if !defined SLANG_EXECUTE_H
#define SLANG_EXECUTE_H
#if defined __cplusplus
extern "C" {
#endif
#define SLANG_MACHINE_STACK_SIZE 1024
typedef struct slang_machine_
{
GLuint ip; /* instruction pointer, for flow control */
GLuint sp; /* stack pointer, for stack access */
GLuint bp; /* base pointer, for local variable access */
GLuint kill; /* discard the fragment */
GLuint exit; /* terminate the shader */
union stack_
{
GLfloat _float[SLANG_MACHINE_STACK_SIZE];
GLfloat *_floatp[SLANG_MACHINE_STACK_SIZE];
GLuint _addr[SLANG_MACHINE_STACK_SIZE];
GLuint *_addrp[SLANG_MACHINE_STACK_SIZE];
} stack;
} slang_machine;
int _slang_execute (const slang_assembly_file *);
#ifdef __cplusplus
}
#endif
#endif
/*
* Mesa 3-D graphics library
* Version: 6.3
*
* Copyright (C) 2005 Brian Paul All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#if !defined SLANG_EXECUTE_H
#define SLANG_EXECUTE_H
#if defined __cplusplus
extern "C" {
#endif
#define SLANG_MACHINE_STACK_SIZE 1024
typedef struct slang_machine_
{
GLuint ip; /* instruction pointer, for flow control */
GLuint sp; /* stack pointer, for stack access */
GLuint bp; /* base pointer, for local variable access */
GLuint kill; /* discard the fragment */
GLuint exit; /* terminate the shader */
union stack_
{
GLfloat _float[SLANG_MACHINE_STACK_SIZE];
GLfloat *_floatp[SLANG_MACHINE_STACK_SIZE];
GLuint _addr[SLANG_MACHINE_STACK_SIZE];
GLuint *_addrp[SLANG_MACHINE_STACK_SIZE];
} stack;
} slang_machine;
int _slang_execute (const slang_assembly_file *);
#ifdef __cplusplus
}
#endif
#endif
/*
* Mesa 3-D graphics library
* Version: 6.3
*
* Copyright (C) 2005 Brian Paul All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
/**
* \file slang_preprocess.c
* slang preprocessor
* \author Michal Krol
*/
#include "imports.h"
#include "grammar_mesa.h"
#include "slang_compile.h"
#include "slang_preprocess.h"
static const char *slang_version_syn =
#include "library/slang_version_syn.h"
;
int _slang_preprocess_version (const char *text, unsigned int *version, unsigned int *eaten,
slang_info_log *log)
{
grammar id;
byte *prod, *I;
unsigned int size;
id = grammar_load_from_text ((const byte *) slang_version_syn);
if (id == 0)
{
char buf[1024];
unsigned int pos;
grammar_get_last_error ( (unsigned char*) buf, 1024, (int*) &pos);
slang_info_log_error (log, buf);
return 0;
}
if (!grammar_fast_check (id, (const byte *) text, &prod, &size, 8))
{
char buf[1024];
unsigned int pos;
grammar_get_last_error ( (unsigned char*) buf, 1024, (int*) &pos);
slang_info_log_error (log, buf);
grammar_destroy (id);
return 0;
}
grammar_destroy (id);
/* there can be multiple #version directives - grab the last one */
I = prod;
while (I < prod + size)
{
*version =
(unsigned int) I[0] +
(unsigned int) I[1] * 100;
*eaten =
((unsigned int) I[2]) +
((unsigned int) I[3] << 8) +
((unsigned int) I[4] << 16) +
((unsigned int) I[5] << 24);
I += 6;
}
grammar_alloc_free (prod);
return 1;
}
/*
* Mesa 3-D graphics library
* Version: 6.3
*
* Copyright (C) 2005 Brian Paul All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
/**
* \file slang_preprocess.c
* slang preprocessor
* \author Michal Krol
*/
#include "imports.h"
#include "grammar_mesa.h"
#include "slang_compile.h"
#include "slang_preprocess.h"
static const char *slang_version_syn =
#include "library/slang_version_syn.h"
;
int _slang_preprocess_version (const char *text, unsigned int *version, unsigned int *eaten,
slang_info_log *log)
{
grammar id;
byte *prod, *I;
unsigned int size;
id = grammar_load_from_text ((const byte *) slang_version_syn);
if (id == 0)
{
char buf[1024];
unsigned int pos;
grammar_get_last_error ( (unsigned char*) buf, 1024, (int*) &pos);
slang_info_log_error (log, buf);
return 0;
}
if (!grammar_fast_check (id, (const byte *) text, &prod, &size, 8))
{
char buf[1024];
unsigned int pos;
grammar_get_last_error ( (unsigned char*) buf, 1024, (int*) &pos);
slang_info_log_error (log, buf);
grammar_destroy (id);
return 0;
}
grammar_destroy (id);
/* there can be multiple #version directives - grab the last one */
I = prod;
while (I < prod + size)
{
*version =
(unsigned int) I[0] +
(unsigned int) I[1] * 100;
*eaten =
((unsigned int) I[2]) +
((unsigned int) I[3] << 8) +
((unsigned int) I[4] << 16) +
((unsigned int) I[5] << 24);
I += 6;
}
grammar_alloc_free (prod);
return 1;
}
/*
* Mesa 3-D graphics library
* Version: 6.3
*
* Copyright (C) 2005 Brian Paul All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#if !defined SLANG_PREPROCESS_H
#define SLANG_PREPROCESS_H
#if defined __cplusplus
extern "C" {
#endif
int _slang_preprocess_version (const char *, unsigned int *, unsigned int *, slang_info_log *);
#ifdef __cplusplus
}
#endif
#endif
/*
* Mesa 3-D graphics library
* Version: 6.3
*
* Copyright (C) 2005 Brian Paul All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#if !defined SLANG_PREPROCESS_H
#define SLANG_PREPROCESS_H
#if defined __cplusplus
extern "C" {
#endif
int _slang_preprocess_version (const char *, unsigned int *, unsigned int *, slang_info_log *);
#ifdef __cplusplus
}
#endif
#endif
/*
* Mesa 3-D graphics library
* Version: 6.3
*
* Copyright (C) 2005 Brian Paul All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
/**
* \file slang_utility.c
* slang utilities
* \author Michal Krol
*/
#include "imports.h"
#include "slang_utility.h"
void slang_alloc_free (void *ptr)
{
_mesa_free (ptr);
}
void *slang_alloc_malloc (unsigned int size)
{
return _mesa_malloc (size);
}
void *slang_alloc_realloc (void *ptr, unsigned int old_size, unsigned int size)
{
return _mesa_realloc (ptr, old_size, size);
}
int slang_string_compare (const char *str1, const char *str2)
{
return _mesa_strcmp (str1, str2);
}
char *slang_string_copy (char *dst, const char *src)
{
return _mesa_strcpy (dst, src);
}
char *slang_string_concat (char *dst, const char *src)
{
return _mesa_strcpy (dst + _mesa_strlen (dst), src);
}
char *slang_string_duplicate (const char *src)
{
return _mesa_strdup (src);
}
unsigned int slang_string_length (const char *str)
{
return _mesa_strlen (str);
}
/*
* Mesa 3-D graphics library
* Version: 6.3
*
* Copyright (C) 2005 Brian Paul All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
/**
* \file slang_utility.c
* slang utilities
* \author Michal Krol
*/
#include "imports.h"
#include "slang_utility.h"
void slang_alloc_free (void *ptr)
{
_mesa_free (ptr);
}
void *slang_alloc_malloc (unsigned int size)
{
return _mesa_malloc (size);
}
void *slang_alloc_realloc (void *ptr, unsigned int old_size, unsigned int size)
{
return _mesa_realloc (ptr, old_size, size);
}
int slang_string_compare (const char *str1, const char *str2)
{
return _mesa_strcmp (str1, str2);
}
char *slang_string_copy (char *dst, const char *src)
{
return _mesa_strcpy (dst, src);
}
char *slang_string_concat (char *dst, const char *src)
{
return _mesa_strcpy (dst + _mesa_strlen (dst), src);
}
char *slang_string_duplicate (const char *src)
{
return _mesa_strdup (src);
}
unsigned int slang_string_length (const char *str)
{
return _mesa_strlen (str);
}
/*
* Mesa 3-D graphics library
* Version: 6.3
*
* Copyright (C) 2005 Brian Paul All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#if !defined SLANG_UTILITY_H
#define SLANG_UTILITY_H
#if defined __cplusplus
extern "C" {
#endif
/*
* Mesa 3-D graphics library
* Version: 6.3
*
* Copyright (C) 2005 Brian Paul All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#if !defined SLANG_UTILITY_H
#define SLANG_UTILITY_H
#if defined __cplusplus
extern "C" {
#endif
/* Compile-time assertions. If the expression is zero, try to declare an
* array of size [-1] to cause compilation error.
*/
#define _static_assert(expr) do { int _array[(expr) ? 1 : -1]; _array[0]; } while (0)
void slang_alloc_free (void *);
void *slang_alloc_malloc (unsigned int);
void *slang_alloc_realloc (void *, unsigned int, unsigned int);
int slang_string_compare (const char *, const char *);
char *slang_string_copy (char *, const char *);
char *slang_string_concat (char *, const char *);
char *slang_string_duplicate (const char *);
unsigned int slang_string_length (const char *);
#ifdef __cplusplus
}
#endif
#endif
void slang_alloc_free (void *);
void *slang_alloc_malloc (unsigned int);
void *slang_alloc_realloc (void *, unsigned int, unsigned int);
int slang_string_compare (const char *, const char *);
char *slang_string_copy (char *, const char *);
char *slang_string_concat (char *, const char *);
char *slang_string_duplicate (const char *);
unsigned int slang_string_length (const char *);
#ifdef __cplusplus
}
#endif
#endif
/*
* Mesa 3-D graphics library
* Version: 6.3
*
* Copyright (C) 2005 Brian Paul All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
/**
* \file traverse_wrap.h
* Handy TIntermTraverser class wrapper
* \author Michal Krol
*/
#ifndef __TRAVERSE_WRAP_H__
#define __TRAVERSE_WRAP_H__
#include "Include/intermediate.h"
/*
The original TIntermTraverser class that is used to walk the intermediate tree,
is not very elegant in its design. One must define static functions with
appropriate prototypes, construct TIntermTraverser object, and set its member
function pointers to one's static functions. If traversal-specific data
is needed, a new class must be derived, and one must up-cast the object
passed as a parameter to the static function.
The class below eliminates this burden by providing virtual methods that are
to be overridden in the derived class.
*/
class traverse_wrap: private TIntermTraverser
{
private:
static void _visitSymbol (TIntermSymbol *S, TIntermTraverser *T) {
static_cast<traverse_wrap *> (T)->Symbol (*S);
}
static void _visitConstantUnion (TIntermConstantUnion *U, TIntermTraverser *T) {
static_cast<traverse_wrap *> (T)->ConstantUnion (*U);
}
static bool _visitBinary (bool preVisit, TIntermBinary *B, TIntermTraverser *T) {
return static_cast<traverse_wrap *> (T)->Binary (preVisit, *B);
}
static bool _visitUnary (bool preVisit, TIntermUnary *U, TIntermTraverser *T) {
return static_cast<traverse_wrap *> (T)->Unary (preVisit, *U);
}
static bool _visitSelection (bool preVisit, TIntermSelection *S, TIntermTraverser *T) {
return static_cast<traverse_wrap *> (T)->Selection (preVisit, *S);
}
static bool _visitAggregate (bool preVisit, TIntermAggregate *A, TIntermTraverser *T) {
return static_cast<traverse_wrap *> (T)->Aggregate (preVisit, *A);
}
static bool _visitLoop (bool preVisit, TIntermLoop *L, TIntermTraverser *T) {
return static_cast<traverse_wrap *> (T)->Loop (preVisit, *L);
}
static bool _visitBranch (bool preVisit, TIntermBranch *B, TIntermTraverser *T) {
return static_cast<traverse_wrap *> (T)->Branch (preVisit, *B);
}
public:
traverse_wrap () {
visitSymbol = _visitSymbol;
visitConstantUnion = _visitConstantUnion;
visitBinary = _visitBinary;
visitUnary = _visitUnary;
visitSelection = _visitSelection;
visitAggregate = _visitAggregate;
visitLoop = _visitLoop;
visitBranch = _visitBranch;
}
protected:
virtual void Symbol (const TIntermSymbol &) {
}
virtual void ConstantUnion (const TIntermConstantUnion &) {
}
virtual bool Binary (bool, const TIntermBinary &) {
return true;
}
virtual bool Unary (bool, const TIntermUnary &) {
return true;
}
virtual bool Selection (bool, const TIntermSelection &) {
return true;
}
virtual bool Aggregate (bool, const TIntermAggregate &) {
return true;
}
virtual bool Loop (bool, const TIntermLoop &) {
return true;
}
virtual bool Branch (bool, const TIntermBranch &) {
return true;
}
};
#endif
/*
* Mesa 3-D graphics library
* Version: 6.3
*
* Copyright (C) 2005 Brian Paul All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
/**
* \file traverse_wrap.h
* Handy TIntermTraverser class wrapper
* \author Michal Krol
*/
#ifndef __TRAVERSE_WRAP_H__
#define __TRAVERSE_WRAP_H__
#include "Include/intermediate.h"
/*
The original TIntermTraverser class that is used to walk the intermediate tree,
is not very elegant in its design. One must define static functions with
appropriate prototypes, construct TIntermTraverser object, and set its member
function pointers to one's static functions. If traversal-specific data
is needed, a new class must be derived, and one must up-cast the object
passed as a parameter to the static function.
The class below eliminates this burden by providing virtual methods that are
to be overridden in the derived class.
*/
class traverse_wrap: private TIntermTraverser
{
private:
static void _visitSymbol (TIntermSymbol *S, TIntermTraverser *T) {
static_cast<traverse_wrap *> (T)->Symbol (*S);
}
static void _visitConstantUnion (TIntermConstantUnion *U, TIntermTraverser *T) {
static_cast<traverse_wrap *> (T)->ConstantUnion (*U);
}
static bool _visitBinary (bool preVisit, TIntermBinary *B, TIntermTraverser *T) {
return static_cast<traverse_wrap *> (T)->Binary (preVisit, *B);
}
static bool _visitUnary (bool preVisit, TIntermUnary *U, TIntermTraverser *T) {
return static_cast<traverse_wrap *> (T)->Unary (preVisit, *U);
}
static bool _visitSelection (bool preVisit, TIntermSelection *S, TIntermTraverser *T) {
return static_cast<traverse_wrap *> (T)->Selection (preVisit, *S);
}
static bool _visitAggregate (bool preVisit, TIntermAggregate *A, TIntermTraverser *T) {
return static_cast<traverse_wrap *> (T)->Aggregate (preVisit, *A);
}
static bool _visitLoop (bool preVisit, TIntermLoop *L, TIntermTraverser *T) {
return static_cast<traverse_wrap *> (T)->Loop (preVisit, *L);
}
static bool _visitBranch (bool preVisit, TIntermBranch *B, TIntermTraverser *T) {
return static_cast<traverse_wrap *> (T)->Branch (preVisit, *B);
}
public:
traverse_wrap () {
visitSymbol = _visitSymbol;
visitConstantUnion = _visitConstantUnion;
visitBinary = _visitBinary;
visitUnary = _visitUnary;
visitSelection = _visitSelection;
visitAggregate = _visitAggregate;
visitLoop = _visitLoop;
visitBranch = _visitBranch;
}
protected:
virtual void Symbol (const TIntermSymbol &) {
}
virtual void ConstantUnion (const TIntermConstantUnion &) {
}
virtual bool Binary (bool, const TIntermBinary &) {
return true;
}
virtual bool Unary (bool, const TIntermUnary &) {
return true;
}
virtual bool Selection (bool, const TIntermSelection &) {
return true;
}
virtual bool Aggregate (bool, const TIntermAggregate &) {
return true;
}
virtual bool Loop (bool, const TIntermLoop &) {
return true;
}
virtual bool Branch (bool, const TIntermBranch &) {
return true;
}
};
#endif
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment