Subversion Repositories filter_foundry

Rev

Rev 532 | 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.net
  4.     Copyright (C) 2018-2021 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: https://web.archive.org/web/20041031134219/http://developer.apple.com/tools/mpw-tools/relnotes/carbonstdclib.html
  27.  
  28. //#ifdef TARGET_API_MAC_CARBON
  29. //      /* can't use StdCLib ctype.h, it refers to symbols which aren't in OS X stdclib */
  30. //      int isprint(int);
  31. //#else
  32.         #include <ctype.h>
  33. //#endif
  34.  
  35. #include "node.h"
  36. #include "y.tab.h"
  37. #include "funcs.h"
  38.  
  39. void freenodes(struct node *p);
  40.  
  41. int varused[0x100],allocs; /* one flag per special variable, indicating if it's used */
  42. value_type var[0x100];
  43.  
  44. struct node *node_list;
  45.  
  46. struct node *newnode(int k){
  47.         struct node *p;
  48.         int i;
  49.  
  50.         if( (p = (struct node*)malloc(sizeof(struct node))) ){
  51.                 #ifdef DEBUG
  52.                 //fprintf(stderr,"NEW(%#x)\n",p);
  53.                 ++allocs;
  54.                 #endif
  55.                 p->kind = k;
  56.                 for( i = 0 ; i < MAXCHILDREN ; ++i )
  57.                         p->child[i] = 0;
  58.  
  59.                 /* add this new node to the list of allocated nodes */
  60.                 p->next = node_list;
  61.                 node_list = p;
  62.         }
  63.         return p;
  64. }
  65.  
  66. void freenodes(struct node *p){
  67.         /* undo recorded allocations */
  68.         if(p){
  69.                 freenodes(p->next);
  70.                 free(p);
  71.                 #ifdef DEBUG
  72.                 //fprintf(stderr,"FREE(%#x)\n",p);
  73.                 --allocs;
  74.                 #endif
  75.         }
  76. }
  77. void freeallnodes(void){
  78.         freenodes(node_list);
  79.         node_list = 0;
  80. }
  81.  
  82. /* pretty-print the tree */
  83.  
  84. void dumptree(struct node *root,int level){
  85.         int i;
  86.  
  87.         if(level>20)
  88.                 puts("## dumptree: sorry, not going deeper than this.");
  89.         else
  90.                 if(root){
  91.                         for(i=level;i--;)
  92.                                 putchar('\t');
  93.                         switch(root->kind){
  94.                         case TOK_NUM:
  95.                                 #ifdef FP_VALUE
  96.                                 printf("constant: %g\n",root->v.value);
  97.                                 #else
  98.                                 printf("constant: %d\n",root->v.value);
  99.                                 #endif
  100.                                 break;
  101.                         case TOK_SPECIALVAR:
  102.                                 printf("special variable: %c\n",root->v.specialvar);
  103.                                 break;
  104.                         case TOK_VAR:
  105.                                 #ifdef FP_VALUE
  106.                                 printf("variable: %s (%g)\n",root->v.sym->name,*root->v.sym->pvar);
  107.                                 #else
  108.                                 printf("variable: %s (%d)\n",root->v.sym->name,*root->v.sym->pvar);
  109.                                 #endif
  110.                                 break;
  111.                         case TOK_FN1:
  112.                         case TOK_FN2:
  113.                         case TOK_FN3:
  114.                                 printf("function: %s\n",root->v.sym->name);
  115.                                 break;
  116.                         default:
  117.                                 printf(isprint(root->kind) ? "operator: %c\n" : "operator: %d\n",root->kind);
  118.                                 break;
  119.                         }
  120.                         ++level;
  121.                         for( i = 0 ; i < MAXCHILDREN ; ++i )
  122.                                 dumptree(root->child[i],level);
  123.                 }
  124.  
  125. }
  126.  
  127. /* evaluate the expression tree (using current values of variables) */
  128.  
  129. value_type eval(struct node *root){
  130.         value_type t;
  131.         if(root){
  132.                 switch(root->kind){
  133.                 case TOK_NUM: return root->v.value;
  134.                 case TOK_SPECIALVAR: return var[root->v.specialvar];
  135.                 case TOK_VAR: return *root->v.sym->pvar;
  136.                 case TOK_FN1: return root->v.sym->fn(eval(root->child[0]));
  137.                 case TOK_FN2: return root->v.sym->fn(
  138.                                                      eval(root->child[0]),
  139.                                                      eval(root->child[1]) );
  140.                 case TOK_FN3: return root->v.sym->fn(
  141.                                                      eval(root->child[0]),
  142.                                                      eval(root->child[1]),
  143.                                                      eval(root->child[2]) );
  144.                 case TOK_FN4: return root->v.sym->fn(
  145.                                                      eval(root->child[0]),
  146.                                                      eval(root->child[1]),
  147.                                                      eval(root->child[2]),
  148.                                                      eval(root->child[3]) );
  149.                 case TOK_FN5: return root->v.sym->fn(
  150.                                                      eval(root->child[0]),
  151.                                                      eval(root->child[1]),
  152.                                                      eval(root->child[2]),
  153.                                                      eval(root->child[3]),
  154.                                                      eval(root->child[4]) );
  155.                 case TOK_FN10: return root->v.sym->fn(
  156.                                                      eval(root->child[0]),
  157.                                                      eval(root->child[1]),
  158.                                                      eval(root->child[2]),
  159.                                                      eval(root->child[3]),
  160.                                                      eval(root->child[4]),
  161.                                                      eval(root->child[5]),
  162.                                                      eval(root->child[6]),
  163.                                                      eval(root->child[7]),
  164.                                                      eval(root->child[8]),
  165.                                                      eval(root->child[9]) );
  166.  
  167.                 case '+': return eval(root->child[0]) + eval(root->child[1]);
  168.                 case '-': return eval(root->child[0]) - eval(root->child[1]);
  169.                 case '*': return eval(root->child[0]) * eval(root->child[1]);
  170.                 case '/': t = eval(root->child[1]); return t ? eval(root->child[0]) / t : 0;
  171.                 case '%': t = eval(root->child[1]); return t ? eval(root->child[0]) % t : 0;
  172.                 case EXP: return (value_type)(pow(eval(root->child[0]), eval(root->child[1])));
  173.  
  174.                 case EQ:  return eval(root->child[0]) == eval(root->child[1]);
  175.                 case NE:  return eval(root->child[0]) != eval(root->child[1]);
  176.                 case '<': return eval(root->child[0]) < eval(root->child[1]);
  177.                 case LE:  return eval(root->child[0]) <= eval(root->child[1]);
  178.                 case '>': return eval(root->child[0]) > eval(root->child[1]);
  179.                 case GE:  return eval(root->child[0]) >= eval(root->child[1]);
  180.  
  181.                 case LOGAND: return eval(root->child[0]) && eval(root->child[1]);
  182.                 case LOGOR:  return eval(root->child[0]) || eval(root->child[1]);
  183.                 case '!': return !eval(root->child[0]);
  184.  
  185.                 case '?': return eval(root->child[0]) ? eval(root->child[1]) : eval(root->child[2]);
  186.  
  187.                 case '&': return eval(root->child[0]) & eval(root->child[1]);
  188.                 case '^': return eval(root->child[0]) ^ eval(root->child[1]);
  189.                 case '|': return eval(root->child[0]) | eval(root->child[1]);
  190.                 case SHLEFT:  return eval(root->child[0]) << eval(root->child[1]);
  191.                 case SHRIGHT: return eval(root->child[0]) >> eval(root->child[1]);
  192.                 case '~': return ~eval(root->child[0]);
  193.  
  194.                 case ',': eval(root->child[0]); return eval(root->child[1]);
  195.                 }
  196.         }
  197.         #ifdef FP_VALUE
  198.         return 0.;
  199.         #else
  200.         return 0;
  201.         #endif
  202. }
  203.  
  204. /* free the memory for a tree's nodes */
  205.  
  206. void freetree(struct node *root){
  207.         int i;
  208.  
  209.         if(root){
  210.                 for( i = 0 ; i < MAXCHILDREN ; ++i )
  211.                         freetree(root->child[i]);
  212.                 free(root);
  213.         }
  214. }
  215.  
  216. /* tabulate usage of special variables, or any invocations of src()/rad()/cnv(), in the tree */
  217.  
  218. void checkvars(struct node*p,int f[],int *cnv,int *srcrad /* ,int *mapused */, int *state_changing_funcs_used ){
  219.         int i;
  220.  
  221.         if(p){
  222.                 if(p->kind==TOK_SPECIALVAR)
  223.                         f[p->v.specialvar] = 1;
  224.                 else if(p->kind==TOK_FN3 && (p->v.sym->fn == (pfunc_type)ff_src || p->v.sym->fn == (pfunc_type)ff_rad))
  225.                         *srcrad = 1;
  226.                 else if(p->kind==TOK_FN10 && p->v.sym->fn == (pfunc_type)ff_cnv)
  227.                         *cnv = 1;
  228. //              else if(p->kind==TOK_FN2 && (p->v.sym->fn == (pfunc_type)ff_map))
  229. //                      *mapused = 1;
  230.                 else if ((p->kind==TOK_FN2 && p->v.sym->fn == (pfunc_type)ff_put) ||
  231.                          (p->kind==TOK_FN2 && p->v.sym->fn == (pfunc_type)ff_rnd) ||
  232.                          (p->kind==TOK_FN1 && p->v.sym->fn == (pfunc_type)ff_rst))
  233.                         *state_changing_funcs_used = 1;
  234.                 for( i = 0 ; i < MAXCHILDREN ; ++i )
  235.                         checkvars(p->child[i],f,cnv,srcrad/*,mapused*/,state_changing_funcs_used);
  236.         }
  237. }
  238.