home *** CD-ROM | disk | FTP | other *** search
/ PC Pro 2002 April / pcpro0402.iso / essentials / graphics / Gimp / gimp-src-20001226.exe / src / gimp / unofficial-plug-ins / mathmap / cgen.c < prev    next >
Encoding:
C/C++ Source or Header  |  2000-04-21  |  13.8 KB  |  528 lines

  1. /*
  2.  * cgen.c
  3.  *
  4.  * MathMap
  5.  *
  6.  * Copyright (C) 1997-2000 Mark Probst
  7.  *
  8.  * This program is free software; you can redistribute it and/or
  9.  * modify it under the terms of the GNU General Public License
  10.  * as published by the Free Software Foundation; either version 2
  11.  * of the License, or (at your option) any later version.
  12.  *
  13.  * This program is distributed in the hope that it will be useful,
  14.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  16.  * GNU General Public License for more details.
  17.  *
  18.  * You should have received a copy of the GNU General Public License
  19.  * along with this program; if not, write to the Free Software
  20.  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  21.  */
  22.  
  23. #ifdef USE_CGEN
  24.  
  25. #include <stdio.h>
  26. #include <assert.h>
  27. #include <stdlib.h>
  28. #include <gmodule.h>
  29. #include <unistd.h>
  30. #include <string.h>
  31.  
  32. #include "cgen.h"
  33. #include "tags.h"
  34. #include "builtins.h"
  35. #include "overload.h"
  36. #include "userval.h"
  37.  
  38. GModule *module = 0;
  39. mathfunc_t eval_c_code = 0;
  40.  
  41. void
  42. enumerate_tmpvars (exprtree *tree, int *nextone, int force, FILE *out)
  43. {
  44.     if (force != -1)
  45.     tree->tmpvarnum = force;
  46.     else
  47.     {
  48.     tree->tmpvarnum = (*nextone)++;
  49.     fprintf(out, "float tmpvar_%d[%d];\n", tree->tmpvarnum, tree->result.length);
  50.     }
  51.  
  52.     switch (tree->type)
  53.     {
  54.     case EXPR_TUPLE_CONST :
  55.     case EXPR_INTERNAL :
  56.     case EXPR_VARIABLE :
  57.         break;
  58.  
  59.     case EXPR_USERVAL :
  60.         {
  61.         exprtree *arg;
  62.  
  63.         for (arg = tree->val.userval.args; arg != 0; arg = arg->next)
  64.             enumerate_tmpvars(arg, nextone, -1, out);
  65.         }
  66.         break;
  67.  
  68.     case EXPR_TUPLE :
  69.         {
  70.         exprtree *elem;
  71.  
  72.         for (elem = tree->val.tuple.elems; elem != 0; elem = elem->next)
  73.             enumerate_tmpvars(elem, nextone, -1, out);
  74.         }
  75.         break;
  76.  
  77.     case EXPR_SELECT :
  78.         enumerate_tmpvars(tree->val.select.tuple, nextone, -1, out);
  79.         enumerate_tmpvars(tree->val.select.subscripts, nextone, -1, out);
  80.         break;
  81.  
  82.     case EXPR_CAST :
  83.         enumerate_tmpvars(tree->val.cast.tuple, nextone, tree->tmpvarnum, out);
  84.         break;
  85.  
  86.     case EXPR_FUNC :
  87.         {
  88.         exprtree *arg;
  89.  
  90.         for (arg = tree->val.func.args; arg != 0; arg = arg->next)
  91.             enumerate_tmpvars(arg, nextone, -1, out);
  92.         }
  93.         break;
  94.  
  95.     case EXPR_ASSIGNMENT :
  96.         enumerate_tmpvars(tree->val.assignment.value, nextone, tree->tmpvarnum, out);
  97.         break;
  98.  
  99.     case EXPR_SUB_ASSIGNMENT :
  100.         enumerate_tmpvars(tree->val.sub_assignment.subscripts, nextone, -1, out);
  101.         enumerate_tmpvars(tree->val.sub_assignment.value, nextone, tree->tmpvarnum, out);
  102.         break;
  103.  
  104.     case EXPR_SEQUENCE :
  105.         enumerate_tmpvars(tree->val.operator.left, nextone, -1, out);
  106.         enumerate_tmpvars(tree->val.operator.right, nextone, tree->tmpvarnum, out);
  107.         break;
  108.  
  109.     case EXPR_IF_THEN :
  110.         enumerate_tmpvars(tree->val.ifExpr.condition, nextone, -1, out);
  111.         enumerate_tmpvars(tree->val.ifExpr.consequent, nextone, tree->tmpvarnum, out);
  112.         break;
  113.  
  114.     case EXPR_IF_THEN_ELSE :
  115.         enumerate_tmpvars(tree->val.ifExpr.condition, nextone, -1, out);
  116.         enumerate_tmpvars(tree->val.ifExpr.consequent, nextone, tree->tmpvarnum, out);
  117.         enumerate_tmpvars(tree->val.ifExpr.alternative, nextone, tree->tmpvarnum, out);
  118.         break;
  119.  
  120.     case EXPR_WHILE :
  121.     case EXPR_DO_WHILE :
  122.         enumerate_tmpvars(tree->val.whileExpr.invariant, nextone, -1, out);
  123.         enumerate_tmpvars(tree->val.whileExpr.body, nextone, -1, out);
  124.         break;
  125.     }
  126. }
  127.  
  128. void
  129. gen_c_code_recursive (exprtree *tree, FILE *out)
  130. {
  131.     int i;
  132.  
  133.     switch (tree->type)
  134.     {
  135.     case EXPR_TUPLE_CONST :
  136.         for (i = 0; i < tree->val.tuple_const.length; ++i)
  137.         fprintf(out, "tmpvar_%d[%d] = %f;\n", tree->tmpvarnum, i, tree->val.tuple_const.data[i]);
  138.         break;
  139.  
  140.     case EXPR_TUPLE :
  141.         {
  142.         exprtree *elem;
  143.  
  144.         for (i = 0, elem = tree->val.tuple.elems; elem != 0; ++i, elem = elem->next)
  145.         {
  146.             gen_c_code_recursive(elem, out);
  147.             fprintf(out, "tmpvar_%d[%d] = tmpvar_%d[0];\n", tree->tmpvarnum, i, elem->tmpvarnum);
  148.         }
  149.         }
  150.         break;
  151.  
  152.     case EXPR_SELECT :
  153.         gen_c_code_recursive(tree->val.select.tuple, out);
  154.  
  155.         if (tree->val.select.subscripts->type == EXPR_TUPLE_CONST)
  156.         {
  157.         for (i = 0; i < tree->val.select.subscripts->result.length; ++i)
  158.         {
  159.             int index = tree->val.select.subscripts->val.tuple_const.data[i];
  160.  
  161.             if (index < 0 || index >= tree->val.select.tuple->result.length)
  162.             fprintf(out, "tmpvar_%d[%d] = 0.0;\n",
  163.                 tree->tmpvarnum, i);
  164.             else
  165.             fprintf(out, "tmpvar_%d[%d] = tmpvar_%d[%d];\n",
  166.                 tree->tmpvarnum, i,
  167.                 tree->val.select.tuple->tmpvarnum, index);
  168.         }
  169.         }
  170.         else
  171.         {
  172.         exprtree *elem;
  173.  
  174.         assert(tree->val.select.subscripts->type == EXPR_TUPLE);
  175.  
  176.         elem = tree->val.select.subscripts->val.tuple.elems;
  177.         i = 0;
  178.         while (elem != 0)
  179.         {
  180.             if (elem->type == EXPR_TUPLE_CONST)
  181.             {
  182.             int index = elem->val.tuple_const.data[0];
  183.  
  184.             if (index < 0 || index >= tree->val.select.tuple->result.length)
  185.                 fprintf(out, "tmpvar_%d[%d] = 0.0;\n",
  186.                     tree->tmpvarnum, i);
  187.             else
  188.                 fprintf(out, "tmpvar_%d[%d] = tmpvar_%d[%d];\n",
  189.                     tree->tmpvarnum, i,
  190.                     tree->val.select.tuple->tmpvarnum, index);
  191.             }
  192.             else
  193.             {
  194.             gen_c_code_recursive(elem, out);
  195.             fprintf(out,
  196.                 "{\n"
  197.                 "    int index = tmpvar_%d[0];\n"
  198.                 "\n"
  199.                 "    if (index < 0 || index >= %d)\n"
  200.                 "        tmpvar_%d[%d] = 0.0;\n"
  201.                 "    else\n"
  202.                 "        tmpvar_%d[%d] = tmpvar_%d[index];\n"
  203.                 "}\n",
  204.                 elem->tmpvarnum,
  205.                 tree->val.select.tuple->result.length,
  206.                 tree->tmpvarnum, i,
  207.                 tree->tmpvarnum, i, tree->val.select.tuple->tmpvarnum);
  208.             }
  209.  
  210.             elem = elem->next;
  211.             ++i;
  212.         }
  213.         }
  214.         break;
  215.  
  216.     case EXPR_CAST :
  217.         gen_c_code_recursive(tree->val.cast.tuple, out);
  218.         break;
  219.  
  220.     case EXPR_INTERNAL :
  221.         fprintf(out,
  222.             "{\n"
  223.             "tuple_t *tuple = (tuple_t*)%p;\n",
  224.             &tree->val.internal->value);
  225.         for (i = 0; i < tree->result.length; ++i)
  226.         fprintf(out, "tmpvar_%d[%d] = tuple->data[%d];\n", tree->tmpvarnum, i, i);
  227.         fprintf(out, "}\n");
  228.         break;
  229.  
  230.     case EXPR_FUNC :
  231.         {
  232.         exprtree *arg;
  233.         int numargs = 0;
  234.         int *invarnums, *invarlengths;
  235.  
  236.         for (arg = tree->val.func.args; arg != 0; arg = arg->next)
  237.         {
  238.             gen_c_code_recursive(arg, out);
  239.             ++numargs;
  240.         }
  241.  
  242.         invarnums = (int*)malloc(numargs * sizeof(int));
  243.         invarlengths = (int*)malloc(numargs * sizeof(int));
  244.  
  245.         for (i = 0, arg = tree->val.func.args; arg != 0; ++i, arg = arg->next)
  246.         {
  247.             invarnums[i] = arg->tmpvarnum;
  248.             invarlengths[i] = arg->result.length;
  249.         }
  250.  
  251.         fprintf(out, "{\n");
  252.         tree->val.func.entry->v.builtin.generator(out, invarnums, invarlengths,
  253.                               tree->tmpvarnum);
  254.         fprintf(out, "}\n");
  255.         }
  256.         break;
  257.  
  258.     case EXPR_VARIABLE :
  259.         for (i = 0; i < tree->result.length; ++i)
  260.         fprintf(out, "tmpvar_%d[%d] = uservar_%s[%d];\n",
  261.             tree->tmpvarnum, i, tree->val.var->name, i);
  262.         break;
  263.  
  264.     case EXPR_USERVAL :
  265.         if (tree->val.userval.userval->type == USERVAL_SLIDER)
  266.         fprintf(out, "tmpvar_%d[0] = *(float*)%p;\n",
  267.             tree->tmpvarnum, &tree->val.userval.userval->v.slider.value);
  268.         else if (tree->val.userval.userval->type == USERVAL_CURVE)
  269.         {
  270.         gen_c_code_recursive(tree->val.userval.args, out);
  271.         fprintf(out,
  272.             "{\n"
  273.             "  int index = (int)(tmpvar_%d[0] * (%d - 1));\n"
  274.             "\n"
  275.             "  if (index < 0)\n"
  276.             "    index = 0;\n"
  277.             "  else if (index >= %d)\n"
  278.             "    index = %d - 1;\n"
  279.             "  tmpvar_%d[0] = ((float*)%p)[index];\n"
  280.             "}\n",
  281.             tree->val.userval.args->tmpvarnum, USER_CURVE_POINTS,
  282.             USER_CURVE_POINTS,
  283.             USER_CURVE_POINTS,
  284.             tree->tmpvarnum, tree->val.userval.userval->v.curve.values);
  285.         }
  286.         else if (tree->val.userval.userval->type == USERVAL_BOOL)
  287.         fprintf(out, "tmpvar_%d[0] = *(float*)%p;\n",
  288.             tree->tmpvarnum, &tree->val.userval.userval->v.bool.value);
  289.         else if (tree->val.userval.userval->type == USERVAL_COLOR)
  290.         fprintf(out,
  291.             "{\n"
  292.             "  int i;\n"
  293.             "\n"
  294.             "  for (i = 0; i < 4; ++i)\n"
  295.             "    tmpvar_%d[i] = ((float*)%p)[i];\n"
  296.             "}\n",
  297.             tree->tmpvarnum, tree->val.userval.userval->v.color.value.data);
  298.         else if (tree->val.userval.userval->type == USERVAL_IMAGE)
  299.         fprintf(out,
  300.             "tmpvar_%d[0] = *(int*)%p;\n",
  301.             tree->tmpvarnum, &tree->val.userval.userval->v.image.index);
  302.         else
  303.         assert(0);
  304.         break;
  305.  
  306.     case EXPR_ASSIGNMENT :
  307.         gen_c_code_recursive(tree->val.assignment.value, out);
  308.         for (i = 0; i < tree->result.length; ++i)
  309.         fprintf(out, "uservar_%s[%d] = tmpvar_%d[%d];\n",
  310.             tree->val.assignment.var->name, i, tree->val.assignment.value->tmpvarnum, i);
  311.         break;
  312.  
  313.     case EXPR_SUB_ASSIGNMENT :
  314.         gen_c_code_recursive(tree->val.sub_assignment.value, out);
  315.  
  316.         if (tree->val.sub_assignment.subscripts->type == EXPR_TUPLE_CONST)
  317.         {
  318.         for (i = 0; i < tree->result.length; ++i)
  319.         {
  320.             int index = tree->val.sub_assignment.subscripts->val.tuple_const.data[i];
  321.  
  322.             if (index >= 0 && index < tree->val.sub_assignment.var->type.length)
  323.             fprintf(out, "uservar_%s[%d] = tmpvar_%d[%d];\n",
  324.                 tree->val.sub_assignment.var->name, index, tree->val.sub_assignment.value->tmpvarnum, i);
  325.         }
  326.         }
  327.         else
  328.         {
  329.         exprtree *elem;
  330.  
  331.         assert(tree->val.sub_assignment.subscripts->type == EXPR_TUPLE);
  332.  
  333.         elem = tree->val.sub_assignment.subscripts->val.tuple.elems;
  334.         i = 0;
  335.         while (elem != 0)
  336.         {
  337.             if (elem->type == EXPR_TUPLE_CONST)
  338.             {
  339.             int index = elem->val.tuple_const.data[0];
  340.  
  341.             if (index >= 0 && index < tree->val.sub_assignment.var->type.length)
  342.                 fprintf(out, "uservar_%s[%d] = tmpvar_%d[%d];\n",
  343.                     tree->val.sub_assignment.var->name, index, tree->val.sub_assignment.value->tmpvarnum, i);
  344.             }
  345.             else
  346.             {
  347.             gen_c_code_recursive(elem, out);
  348.             fprintf(out,
  349.                 "{\n"
  350.                 "    int index = tmpvar_%d[0];\n"
  351.                 "\n"
  352.                 "    if (index >= 0 || index < %d)\n"
  353.                 "        uservar_%s[index] = tmpvar_%d[%d];\n"
  354.                 "}\n",
  355.                 elem->tmpvarnum,
  356.                 tree->val.sub_assignment.var->type.length,
  357.                 tree->val.sub_assignment.var->name, tree->val.sub_assignment.value->tmpvarnum, i);
  358.             }
  359.  
  360.             elem = elem->next;
  361.             ++i;
  362.         }
  363.         }
  364.         break;
  365.  
  366.     case EXPR_SEQUENCE :
  367.         gen_c_code_recursive(tree->val.operator.left, out);
  368.         gen_c_code_recursive(tree->val.operator.right, out);
  369.         break;
  370.  
  371.     case EXPR_IF_THEN :
  372.         gen_c_code_recursive(tree->val.ifExpr.condition, out);
  373.         fprintf(out,
  374.             "if (tmpvar_%d[0] != 0.0)\n"
  375.             "{\n",
  376.             tree->val.ifExpr.condition->tmpvarnum);
  377.         gen_c_code_recursive(tree->val.ifExpr.consequent, out);
  378.         fprintf(out,
  379.             "}\n"
  380.             "else\n"
  381.             "{\n");
  382.         for (i = 0; i < tree->result.length; ++i)
  383.         fprintf(out, "    tmpvar_%d[%d] = 0.0;\n", tree->tmpvarnum, i);
  384.         fprintf(out, "}\n");
  385.         break;
  386.  
  387.     case EXPR_IF_THEN_ELSE :
  388.         gen_c_code_recursive(tree->val.ifExpr.condition, out);
  389.         fprintf(out,
  390.             "if (tmpvar_%d[0] != 0.0)\n"
  391.             "{\n",
  392.             tree->val.ifExpr.condition->tmpvarnum);
  393.         gen_c_code_recursive(tree->val.ifExpr.consequent, out);
  394.         fprintf(out,
  395.             "}\n"
  396.             "else\n"
  397.             "{\n");
  398.         gen_c_code_recursive(tree->val.ifExpr.alternative, out);
  399.         fprintf(out, "}\n");
  400.         break;
  401.  
  402.     case EXPR_WHILE :
  403.         fprintf(out,
  404.             "while (1)\n"
  405.             "{\n");
  406.         gen_c_code_recursive(tree->val.whileExpr.invariant, out);
  407.         fprintf(out,
  408.             "if (tmpvar_%d[0] == 0.0)\n"
  409.             "    break;\n",
  410.             tree->val.whileExpr.invariant->tmpvarnum);
  411.         gen_c_code_recursive(tree->val.whileExpr.body, out);
  412.         fprintf(out,
  413.             "}\n"
  414.             "tmpvar_%d[0] = 0.0;\n",
  415.             tree->tmpvarnum);
  416.         break;
  417.  
  418.     case EXPR_DO_WHILE :
  419.         fprintf(out,
  420.             "do\n"
  421.             "{\n");
  422.         gen_c_code_recursive(tree->val.whileExpr.body, out);
  423.         gen_c_code_recursive(tree->val.whileExpr.invariant, out);
  424.         fprintf(out,
  425.             "} while (tmpvar_%d[0] != 0.0);\n"
  426.             "tmpvar_%d[0] = 0.0;\n",
  427.             tree->val.whileExpr.invariant->tmpvarnum,
  428.             tree->tmpvarnum);
  429.         break;
  430.  
  431.     default :
  432.         assert(0);
  433.     }
  434. }
  435.  
  436. gboolean
  437. gen_and_load_c_code (exprtree *tree)
  438. {
  439.     FILE *out;
  440.     int numtmpvars = 0, i;
  441.     variable_t *var;
  442.     char *buf;
  443.     int pid = getpid();
  444.  
  445.     if (module != 0)
  446.     {
  447.     g_module_close(module);
  448.     module = 0;
  449.     }
  450.  
  451.     buf = (char*)malloc(MAX(strlen(CGEN_CC), strlen(CGEN_LD)) + 512);
  452.  
  453.     sprintf(buf, "/tmp/mathfunc%d.c", pid);
  454.     out = fopen(buf, "w");
  455.     assert(out != 0);
  456.  
  457.     fprintf(out,
  458.         "#include <math.h>\n"
  459.         "void getOrigValIntersamplePixel(float,float,unsigned char*,int);\n"
  460.         "void getOrigValPixel(float,float,unsigned char*,int);\n"
  461.         "float noise(float,float,float);\n"
  462.         "typedef struct\n"
  463.         "{\n"
  464.         "    float data[%d];\n"
  465.         "    int number;\n"
  466.         "    int length;\n"
  467.         "} tuple_t;\n"
  468.         "extern double user_curve_values[];\n"
  469.         "extern int user_curve_points;\n"
  470.         "extern tuple_t gradient_samples[];\n"
  471.         "extern int num_gradient_samples;\n"
  472.         "typedef void (*builtin_function_t) (void*);\n"
  473.         "extern tuple_t stack[];\n"
  474.         "extern int stackp;\n\n", MAX_TUPLE_LENGTH);
  475.     fprintf(out,
  476.         "tuple_t* mathmapfunc (void)\n"
  477.         "{\n"
  478.         "int dummy;\n");
  479.  
  480.     for (var = firstVariable; var != 0; var = var->next)
  481.     fprintf(out, "float uservar_%s[%d];\n", var->name, var->type.length);
  482.  
  483.     enumerate_tmpvars(tree, &numtmpvars, -1, out);
  484.     gen_c_code_recursive(tree, out);
  485.  
  486.     for (i = 0; i < tree->result.length; ++i)
  487.     fprintf(out,
  488.         "stack[0].data[%d] = tmpvar_%d[%d];\n",
  489.         i, tree->tmpvarnum, i);
  490.  
  491.     fprintf(out,
  492.         "stack[0].length = 4;\n"
  493.         "return &stack[0];\n"
  494.         "}\n");
  495.  
  496.     fclose(out);
  497.  
  498.     sprintf(buf, "%s /tmp/mathfunc%d.o /tmp/mathfunc%d.c", CGEN_CC, pid, pid);
  499.     system(buf);
  500.  
  501.     sprintf(buf, "%s /tmp/mathfunc%d.so /tmp/mathfunc%d.o", CGEN_LD, pid, pid);
  502.     system(buf);
  503.  
  504.     sprintf(buf, "/tmp/mathfunc%d.so", pid);
  505.     module = g_module_open(buf, 0);
  506.     if (module == 0)
  507.     {
  508.     fprintf(stderr, "could not load module: %s\n", g_module_error());
  509.     assert(0);
  510.     }
  511.  
  512.     assert(g_module_symbol(module, "mathmapfunc", (void**)&eval_c_code));
  513.  
  514.     unlink(buf);
  515.  
  516.     sprintf(buf, "/tmp/mathfunc%d.o", pid);
  517.     unlink(buf);
  518.  
  519.     sprintf(buf, "/tmp/mathfunc%d.c", pid);
  520.     unlink(buf);
  521.  
  522.     free(buf);
  523.  
  524.     return TRUE;
  525. }
  526.  
  527. #endif
  528.