Subversion Repositories filter_foundry

Rev

Rev 185 | Rev 206 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | RSS feed

  1. /*
  2.     This file is part of "Filter Foundry", a filter plugin for Adobe Photoshop
  3.     Copyright (C) 2003-2009 Toby Thain, toby@telegraphics.com.au
  4.     Copyright (C) 2018-2019 Daniel Marschall, ViaThinkSoft
  5.  
  6.     This program is free software; you can redistribute it and/or modify
  7.     it under the terms of the GNU General Public License as published by
  8.     the Free Software Foundation; either version 2 of the License, or
  9.     (at your option) any later version.
  10.  
  11.     This program is distributed in the hope that it will be useful,
  12.     but WITHOUT ANY WARRANTY; without even the implied warranty of
  13.     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14.     GNU General Public License for more details.
  15.  
  16.     You should have received a copy of the GNU General Public License
  17.     along with this program; if not, write to the Free Software
  18.     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  19. */
  20.  
  21. #include <stdlib.h>
  22. #include <stdio.h>
  23. #include <math.h>
  24.  
  25. // The following ugly workaround is obviated by Carbon StdCLib headers;
  26. // see: http://developer.apple.com/tools/mpw-tools/relnotes/carbonstdclib.html
  27. // (via http://developer.apple.com/tools/mpw-tools/updates.html )
  28.  
  29. //#ifdef TARGET_API_MAC_CARBON
  30. //      /* can't use StdCLib ctype.h, it refers to symbols which aren't in OS X stdclib */
  31. //      int isprint(int);
  32. //#else
  33.         #include <ctype.h>
  34. //#endif
  35.  
  36. #include "node.h"
  37. #include "y.tab.h"
  38. #include "funcs.h"
  39.  
  40. void freenodes(struct node *p);
  41.  
  42. int varused[0x100],allocs; /* one flag per special variable, indicating if it's used */
  43. value_type var[0x100];
  44.  
  45. struct node *node_list;
  46.  
  47. struct node *newnode(int k){
  48.         struct node *p;
  49.         int i;
  50.  
  51.         if(NEW(p)){
  52. #ifdef DEBUG
  53. //              fprintf(stderr,"NEW(%#x)\n",p);
  54.                 ++allocs;
  55. #endif
  56.                 p->kind = k;
  57.                 for( i = 0 ; i < MAXCHILDREN ; ++i )
  58.                         p->child[i] = 0;
  59.  
  60.                 /* add this new node to the list of allocated nodes */
  61.                 p->next = node_list;
  62.                 node_list = p;
  63.         }
  64.         return p;
  65. }
  66.  
  67. void freenodes(struct node *p){
  68.         /* undo recorded allocations */
  69.         if(p){
  70.                 freenodes(p->next);
  71.                 free(p);
  72. #ifdef DEBUG
  73. //              fprintf(stderr,"FREE(%#x)\n",p);
  74.                 --allocs;
  75. #endif
  76.         }
  77. }
  78. void freeallnodes(){
  79.         freenodes(node_list);
  80.         node_list = 0;
  81. }
  82.  
  83. /* pretty-print the tree */
  84.  
  85. void dumptree(struct node *root,int level){
  86.         int i;
  87.  
  88.         if(level>20)
  89.                 puts("## dumptree: sorry, not going deeper than this.");
  90.         else
  91.                 if(root){
  92.                         for(i=level;i--;)
  93.                                 putchar('\t');
  94.                         switch(root->kind){
  95.                         case TOK_NUM:
  96. #ifdef FP_VALUE
  97.                                 printf("constant: %g\n",root->v.value);
  98. #else
  99.                                 printf("constant: %ld\n",root->v.value);
  100. #endif
  101.                                 break;
  102.                         case TOK_SPECIALVAR:
  103.                                 printf("special variable: %c\n",root->v.specialvar);
  104.                                 break;
  105.                         case TOK_VAR:
  106. #ifdef FP_VALUE
  107.                                 printf("variable: %s (%g)\n",root->v.sym->name,*root->v.sym->pvar);
  108. #else
  109.                                 printf("variable: %s (%ld)\n",root->v.sym->name,*root->v.sym->pvar);
  110. #endif
  111.                                 break;
  112.                         case TOK_FN1:
  113.                         case TOK_FN2:
  114.                         case TOK_FN3:
  115.                                 printf("function: %s\n",root->v.sym->name);
  116.                                 break;
  117.                         default:
  118.                                 printf(isprint(root->kind) ? "operator: %c\n" : "operator: %d\n",root->kind);
  119.                                 break;
  120.                         }
  121.                         ++level;
  122.                         for( i = 0 ; i < MAXCHILDREN ; ++i )
  123.                                 dumptree(root->child[i],level);
  124.                 }
  125.  
  126. }
  127.  
  128. /* evaluate the expression tree (using current values of variables) */
  129.  
  130. value_type eval(struct node *root){
  131.         value_type t;
  132.         if(root){
  133.                 switch(root->kind){
  134.                 case TOK_NUM: return root->v.value;
  135.                 case TOK_SPECIALVAR: return var[root->v.specialvar];
  136.                 case TOK_VAR: return *root->v.sym->pvar;
  137.                 case TOK_FN1: return root->v.sym->fn(eval(root->child[0]));
  138.                 case TOK_FN2: return root->v.sym->fn(
  139.                                                                 eval(root->child[0]),
  140.                                                                 eval(root->child[1]) );
  141.                 case TOK_FN3: return root->v.sym->fn(
  142.                                                                 eval(root->child[0]),
  143.                                                                 eval(root->child[1]),
  144.                                                                 eval(root->child[2]) );
  145.                 case TOK_FN4: return root->v.sym->fn(
  146.                                                                 eval(root->child[0]),
  147.                                                                 eval(root->child[1]),
  148.                                                                 eval(root->child[2]),
  149.                                                                 eval(root->child[3]) );
  150.                 case TOK_FN5: return root->v.sym->fn(
  151.                                                                 eval(root->child[0]),
  152.                                                                 eval(root->child[1]),
  153.                                                                 eval(root->child[2]),
  154.                                                                 eval(root->child[3]),
  155.                                                                 eval(root->child[4]) );
  156.                 case TOK_FN10: return root->v.sym->fn(
  157.                                                                 eval(root->child[0]),
  158.                                                                 eval(root->child[1]),
  159.                                                                 eval(root->child[2]),
  160.                                                                 eval(root->child[3]),
  161.                                                                 eval(root->child[4]),
  162.                                                                 eval(root->child[5]),
  163.                                                                 eval(root->child[6]),
  164.                                                                 eval(root->child[7]),
  165.                                                                 eval(root->child[8]),
  166.                                                                 eval(root->child[9]) );
  167.  
  168.                 case '+': return eval(root->child[0]) + eval(root->child[1]);
  169.                 case '-': return eval(root->child[0]) - eval(root->child[1]);
  170.                 case '*': return eval(root->child[0]) * eval(root->child[1]);
  171.                 case '/': t = eval(root->child[1]); return t ? eval(root->child[0]) / t : 0;
  172.                 case '%': t = eval(root->child[1]); return t ? eval(root->child[0]) % t : 0;
  173.                 case EXP: return (value_type)(pow(eval(root->child[0]), eval(root->child[1])));
  174.  
  175.                 case EQ:  return eval(root->child[0]) == eval(root->child[1]);
  176.                 case NE:  return eval(root->child[0]) != eval(root->child[1]);
  177.                 case '<': return eval(root->child[0]) < eval(root->child[1]);
  178.                 case LE:  return eval(root->child[0]) <= eval(root->child[1]);
  179.                 case '>': return eval(root->child[0]) > eval(root->child[1]);
  180.                 case GE:  return eval(root->child[0]) >= eval(root->child[1]);
  181.  
  182.                 case LOGAND: return eval(root->child[0]) && eval(root->child[1]);
  183.                 case LOGOR:  return eval(root->child[0]) || eval(root->child[1]);
  184.                 case '!': return !eval(root->child[0]);
  185.  
  186.                 case '?': return eval(root->child[0]) ? eval(root->child[1]) : eval(root->child[2]);
  187.  
  188.                 case '&': return eval(root->child[0]) & eval(root->child[1]);
  189.                 case '^': return eval(root->child[0]) ^ eval(root->child[1]);
  190.                 case '|': return eval(root->child[0]) | eval(root->child[1]);
  191.                 case SHLEFT:  return eval(root->child[0]) << eval(root->child[1]);
  192.                 case SHRIGHT: return eval(root->child[0]) >> eval(root->child[1]);
  193.                 case '~': return ~eval(root->child[0]);
  194.  
  195.                 case ',': eval(root->child[0]); return eval(root->child[1]);
  196.                 }
  197.         }
  198.         #ifdef FP_VALUE
  199.         return 0.;
  200.         #else
  201.         return 0;
  202. #endif
  203. }
  204.  
  205. /* free the memory for a tree's nodes */
  206.  
  207. void freetree(struct node *root){
  208.         int i;
  209.  
  210.         if(root){
  211.                 for( i = 0 ; i < MAXCHILDREN ; ++i )
  212.                         freetree(root->child[i]);
  213.                 free(root);
  214.         }
  215. }
  216.  
  217. /* tabulate usage of special variables, or any invocations of src()/rad()/cnv(), in the tree */
  218.  
  219. void checkvars(struct node*p,int f[],int *cnv,int *srcrad /* ,int *mapused */, int *state_changing_funcs_used ){
  220.         int i;
  221.  
  222.         if(p){
  223.                 if(p->kind==TOK_SPECIALVAR)
  224.                         f[p->v.specialvar] = 1;
  225.                 else if(p->kind==TOK_FN3 && (p->v.sym->fn == (pfunc_type)ff_src || p->v.sym->fn == (pfunc_type)ff_rad))
  226.                         *srcrad = 1;
  227.                 else if(p->kind==TOK_FN10 && p->v.sym->fn == (pfunc_type)ff_cnv)
  228.                         *cnv = 1;
  229. //              else if(p->kind==TOK_FN2 && (p->v.sym->fn == (pfunc_type)ff_map))
  230. //                      *mapused = 1;
  231.                 else if ((p->kind==TOK_FN2 && p->v.sym->fn == (pfunc_type)ff_put) ||
  232.                          (p->kind==TOK_FN1 && p->v.sym->fn == (pfunc_type)ff_rnd) ||
  233.                          (p->kind==TOK_FN1 && p->v.sym->fn == (pfunc_type)ff_rst))
  234.                         *state_changing_funcs_used = 1;
  235.                 for( i = 0 ; i < MAXCHILDREN ; ++i )
  236.                         checkvars(p->child[i],f,cnv,srcrad/*,mapused*/,state_changing_funcs_used);
  237.         }
  238. }
  239.