mojoshader_assembler.c
changeset 523 699696afd731
parent 522 3c08f4d2aa2e
child 524 03eea2f0762c
equal deleted inserted replaced
522:3c08f4d2aa2e 523:699696afd731
    33     MOJOSHADER_malloc malloc;
    33     MOJOSHADER_malloc malloc;
    34     MOJOSHADER_free free;
    34     MOJOSHADER_free free;
    35     void *malloc_data;
    35     void *malloc_data;
    36     const char *failstr;
    36     const char *failstr;
    37     TokenizerContext tctx;
    37     TokenizerContext tctx;
    38     int started_parsing;
    38     MOJOSHADER_parsePhase parse_phase;
    39     MOJOSHADER_shaderType shader_type;
    39     MOJOSHADER_shaderType shader_type;
    40     uint8 major_ver;
    40     uint8 major_ver;
    41     uint8 minor_ver;
    41     uint8 minor_ver;
    42     uint32 tokenbuf[16];
    42     uint32 tokenbuf[16];
    43     int tokenbufpos;
    43     int tokenbufpos;
  1618 
  1618 
  1619     memset(ctx, '\0', sizeof (Context));
  1619     memset(ctx, '\0', sizeof (Context));
  1620     ctx->malloc = m;
  1620     ctx->malloc = m;
  1621     ctx->free = f;
  1621     ctx->free = f;
  1622     ctx->malloc_data = d;
  1622     ctx->malloc_data = d;
       
  1623     ctx->parse_phase = MOJOSHADER_PARSEPHASE_NOTSTARTED;
  1623     ctx->tctx.source = source;
  1624     ctx->tctx.source = source;
  1624     ctx->tctx.linenum = 1;
  1625     ctx->tctx.linenum = 1;
  1625 
  1626 
  1626     return ctx;
  1627     return ctx;
  1627 } // build_context
  1628 } // build_context
  1659     retval->free = (ctx->free == internal_free) ? NULL : ctx->free;
  1660     retval->free = (ctx->free == internal_free) ? NULL : ctx->free;
  1660     retval->malloc_data = ctx->malloc_data;
  1661     retval->malloc_data = ctx->malloc_data;
  1661     retval->error = ctx->failstr;  // we recycle.  :)
  1662     retval->error = ctx->failstr;  // we recycle.  :)
  1662     ctx->failstr = NULL;  // don't let this get free()'d too soon.
  1663     ctx->failstr = NULL;  // don't let this get free()'d too soon.
  1663 
  1664 
  1664     if (ctx->started_parsing)
  1665     switch (ctx->parse_phase)
  1665         retval->error_position = ctx->tctx.linenum;
  1666     {
  1666     else
  1667         case MOJOSHADER_PARSEPHASE_NOTSTARTED:
  1667         retval->error_position = -1;
  1668             retval->error_position = -2;
       
  1669             break;
       
  1670         case MOJOSHADER_PARSEPHASE_WORKING:
       
  1671             retval->error_position = ctx->tctx.linenum;
       
  1672             break;
       
  1673         case MOJOSHADER_PARSEPHASE_DONE:
       
  1674             retval->error_position = -1;
       
  1675             break;
       
  1676     } // switch
  1668 
  1677 
  1669     return retval;
  1678     return retval;
  1670 } // build_failed_assembly
  1679 } // build_failed_assembly
  1671 
  1680 
       
  1681 
       
  1682 typedef struct CTabTypeInfo
       
  1683 {
       
  1684     uint16 parameter_class;
       
  1685     uint16 parameter_type;
       
  1686     uint16 rows;
       
  1687     uint16 columns;
       
  1688     uint16 elements;
       
  1689     uint16 structMembers;
       
  1690     uint32 structMemberInfo;
       
  1691 } CTabTypeInfo;
       
  1692 
       
  1693 
       
  1694 FUCK THIS CODE.
       
  1695 static void output_ctab(Context *ctx, const MOJOSHADER_symbol *symbols,
       
  1696                         unsigned int symbol_count)
       
  1697 {
       
  1698     if (symbol_count == 0)
       
  1699         return;
       
  1700 
       
  1701     unsigned int i;
       
  1702     uint8 *bytes = NULL;
       
  1703     const char *creator = "MojoShader revision " MOJOSHADER_CHANGESET;
       
  1704     const size_t creatorlen = strlen(creator) + 1;
       
  1705     add_ctab_bytes(ctx, &bytes, &offset, creator, creatorlen);
       
  1706     add_ctab_bytes(ctx, &bytes, &offset, "", 1);  // !!! FIXME: target
       
  1707 
       
  1708     // build all the unique D3DXSHADER_TYPEINFO structs into the bytes.
       
  1709     CTabTypeInfo *tinfo;
       
  1710     tinfo = (CTabTypeInfo *) Malloc(sizeof (CTabTypeInfo) * symbol_count);
       
  1711     if (tinfo == NULL)
       
  1712     {
       
  1713         Free(ctx, bytes);
       
  1714         return;
       
  1715     } // if
       
  1716 
       
  1717     for (i = 0; i < symbol_count; i++)
       
  1718     {
       
  1719         // !!! FIXME: struct packing!
       
  1720         tinfo[i].parameter_class = SWAP16(symbols[i].parameter_class);
       
  1721         tinfo[i].parameter_type = SWAP16(symbols[i].parameter_type);
       
  1722         tinfo[i].rows = SWAP16(symbols[i].rows);
       
  1723         tinfo[i].columns = SWAP16(symbols[i].columns);
       
  1724         tinfo[i].elements = SWAP16(symbols[i].elements);
       
  1725         tinfo[i].structMembers = SWAP16(symbols[i].structMembers);
       
  1726         tinfo[i].structMembersInfo = SWAP32(0);  // !!! FIXME: points to DWORD name, DWORD typeinfo
       
  1727         add_ctab_bytes(ctx, &bytes, &offset, &tinfo[i], sizeof (tinfo[i]));
       
  1728     } // for
       
  1729 
       
  1730 
       
  1731     uint8 ctab = sdfkjsldkfjsdlkf;
       
  1732     uint32 *table = (uint32 *) ctab;
       
  1733     uint32 offset = CTAB_SIZE + (CINFO_SIZE * symbol_count);
       
  1734     uint8 *data = ctab + offset + sizeof (uint32);
       
  1735     union { uint8 *ui8; uint16 *ui16; uint32 *ui32; } info;
       
  1736     info.ui8 = ctab + CTAB_SIZE + sizeof (uint32);
       
  1737 
       
  1738     *(table++) = SWAP32(CTAB_ID);
       
  1739     *(table++) = SWAP32(28);
       
  1740     *(table++) = SWAP32(find_ctab_bytes(ctx, bytes, creator, creatorlen));
       
  1741     *(table++) = SWAP32(ctx->version_token);
       
  1742     *(table++) = SWAP32(((uint32) symbol_count));
       
  1743     *(table++) = SWAP32(CTAB_SIZE);  // info array right after table.
       
  1744     *(table++) = SWAP32(0);
       
  1745     *(table++) = SWAP32(find_ctab_bytes(ctx, bytes, "", 1));  // !!! FIXME: target?
       
  1746 
       
  1747     assert( ((uint8 *) table) == info.ui8 );
       
  1748     for (i = 0; i < symbol_count; i++)
       
  1749     {
       
  1750         const char *name = symbols[i].name;
       
  1751         const size_t namelen = strlen(symbols[i].name) + 1;
       
  1752         add_ctab_bytes(bytes, &offset, name, namelen);
       
  1753         *(info.ui32++) = SWAP32(add_ctab_string(ctx, &data, &offset, symbols[i].name));
       
  1754         *(info.ui16++) = SWAP16((uint16) symbols[i].register_set);
       
  1755         *(info.ui16++) = SWAP16((uint16) symbols[i].register_index);
       
  1756         *(info.ui16++) = SWAP16((uint16) symbols[i].register_count);
       
  1757         *(info.ui16++) = SWAP16(0);  // reserved
       
  1758 
       
  1759     MOJOSHADER_symbolClass parameter_class;
       
  1760     MOJOSHADER_symbolType parameter_type;
       
  1761     unsigned int rows;
       
  1762     unsigned int columns;
       
  1763     unsigned int elements;
       
  1764     unsigned int structMembers;
       
  1765     unsigned int bytes;
       
  1766     void *default_value;
       
  1767 
       
  1768     } // for
       
  1769 
       
  1770     assert( info.ui8 == origdata);
       
  1771 
       
  1772     output_comment_bytes(ctx, ctab, (size_t) (ptr - ctab));
       
  1773 } // output_ctab
       
  1774 
       
  1775 
       
  1776 static void output_comments(Context *ctx, const char **comments,
       
  1777                             unsigned int comment_count,
       
  1778                             const MOJOSHADER_symbol *symbols,
       
  1779                             unsigned int symbol_count)
       
  1780 {
       
  1781     if (isfail(ctx))
       
  1782         return;
       
  1783 
       
  1784     // make error messages sane if CTAB fails, etc.
       
  1785     ctx->parse_phase = MOJOSHADER_PARSEPHASE_NOTSTARTED;
       
  1786 
       
  1787     output_ctab(ctx, symbols, symbol_count);
       
  1788 
       
  1789     int i;
       
  1790     for (i = 0; i < comment_count; i++)
       
  1791         output_comment_string(ctx, comments[i]);
       
  1792 
       
  1793     if (!isfail(ctx))
       
  1794         ctx->parse_phase = MOJOSHADER_PARSEPHASE_WORKING;
       
  1795 } // output_comments
  1672 
  1796 
  1673 
  1797 
  1674 // API entry point...
  1798 // API entry point...
  1675 
  1799 
  1676 const MOJOSHADER_parseData *MOJOSHADER_assemble(const char *source,
  1800 const MOJOSHADER_parseData *MOJOSHADER_assemble(const char *source,
  1685     ctx = build_context(source, m, f, d);
  1809     ctx = build_context(source, m, f, d);
  1686     if (ctx == NULL)
  1810     if (ctx == NULL)
  1687         return &out_of_mem_data;
  1811         return &out_of_mem_data;
  1688 
  1812 
  1689     // Version token always comes first.
  1813     // Version token always comes first.
  1690     ctx->started_parsing = 1;
  1814     ctx->parse_phase = MOJOSHADER_PARSEPHASE_WORKING;
  1691     parse_version_token(ctx);
  1815     parse_version_token(ctx);
  1692 
  1816 
  1693     ctx->started_parsing = 0;  // make error messages sane if CTAB fails, etc.
  1817     ctx->started_parsing = 0;  // make error messages sane if CTAB fails, etc.
  1694     const char *credit = "Generated by MojoShader assembler revision "
  1818     const char *credit = "Generated by MojoShader assembler revision "
  1695                          MOJOSHADER_CHANGESET
  1819                          MOJOSHADER_CHANGESET
  1696                          ", http://icculus.org/mojoshader/";
  1820                          ", http://icculus.org/mojoshader/";
  1697     output_comment_string(ctx, credit);
  1821     output_comment_string(ctx, credit);
  1698 
  1822 
  1699     // !!! FIXME: insert CTAB here.
  1823     // !!! FIXME: insert CTAB here.
  1700 
       
  1701     ctx->started_parsing = 1;
       
  1702 
  1824 
  1703     // parse out the rest of the tokens after the version token...
  1825     // parse out the rest of the tokens after the version token...
  1704     while (nexttoken(ctx, 1, 1, 0, 1) == NOFAIL)
  1826     while (nexttoken(ctx, 1, 1, 0, 1) == NOFAIL)
  1705         parse_token(ctx);
  1827         parse_token(ctx);
  1706 
  1828