git @ Cat's Eye Technologies OpenZz / master src / action.c
master

Tree @master (Download .tar.gz)

action.c @masterraw · history · blame

/* 
    Zz Dynamic Parser Library
    Copyright (C) 1989 - I.N.F.N - S.Cabasino, P.S.Paolucci, G.M.Todesco

    The Zz Library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Lesser General Public
    License as published by the Free Software Foundation; either
    version 2.1 of the License, or (at your option) any later version.

    The Zz Library is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    Lesser General Public License for more details.

    You should have received a copy of the GNU Lesser General Public
    License along with this library; if not, write to the Free Software
    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
*/

#include <stdio.h>
#include <stdint.h>
#include "zz.h"
#include "zlex.h"
#include "rule.h"
#include "err.h"
#include "avl.h"
#include "list.h"
#include "param.h"
#include "trace.h"

/*PROTOTYPES*/
int parse(struct s_nt *);
void pop_source(void);
int source_list(struct s_content *, void *);

struct s_content zz_ret_value = {0,0};

/*--------------------------------------------------------------------------*/

struct s_content* zz_bind_get_ret_value()
{
  return &zz_ret_value;
}

/*--------------------------------------------------------------------------*/

#define MAX_ARGV 100

void action(struct s_rule *rule, struct s_content stack[], struct s_content *ret)
{
  struct s_content cnt,old_zz_ret_value;
  struct s_content argv [MAX_ARGV]; /* allocation issue */
  char *namev[MAX_ARGV];
  int argc;
  int (*caction)();
  int i,j;

  zz_assert(rule);
  zz_assert(stack);
  zz_assert(ret);

  ret->tag=tag_none;
  s_content_value(*ret)=0;
  /* PREPARO I PARAMETRI */
  
  /* rule=rule->top_scope; */
  argc=0;
  for(i=1,j=0;i<rule->bead_n;i++,j++)
    /* push only non-terminals in argv
       to pass it during action execution */
    if(rule->beads[i].cnt.tag==tag_sint)
      {
	zz_assert(argc < MAX_ARGV);
	argv[argc] = stack[j];
	namev[argc] = rule->beads[i].name;
	argc++;
      }
  
  switch(rule->action_type)
    {
    case ACT_T_EXECUTE_PROC:
      caction = (int (*)())s_content_value(rule->action);
      //printf("MIAOOOOOO\n");
      ret->tag = rule->sproc_tag;
      //      if(ret->tag)
      //	printf("zz: EXECUTE_PROC: tag_name=%s\n", ret->tag->name);
      (*caction)(argc,argv,ret);
      break;
    case ACT_T_EXECUTE_SPROC:
      caction = (int (*)())s_content_value(rule->action);
      ret->tag = rule->sproc_tag;
      switch(argc)
	{
        case 0:
	  s_content_value(*ret) = (*caction)();
          break;
        case 1:
	  /*
	    printf("BONBOLO: tag=%p tag_name=%s value=0x%08x\n", 
		 argv[0].tag, argv[0].tag->name, argv[0].value);
	  */
	  s_content_value(*ret) = (*caction)(s_content_value(argv[0]));
          break;
        case 2:
	  s_content_value(*ret) = (*caction)(s_content_value(argv[0]),
					     s_content_value(argv[1]));
          break;
        case 3:
	  s_content_value(*ret) = (*caction)(s_content_value(argv[0]), 
					     s_content_value(argv[1]), 
					     s_content_value(argv[2]));
          break;
        case 4:
	  s_content_value(*ret) = (*caction)(s_content_value(argv[0]), 
					     s_content_value(argv[1]), 
					     s_content_value(argv[2]), 
					     s_content_value(argv[3]));
          break;
        case 5:
	  s_content_value(*ret) = (*caction)(s_content_value(argv[0]), 
					     s_content_value(argv[1]), 
					     s_content_value(argv[2]), 
					     s_content_value(argv[3]),
					     s_content_value(argv[4]));
          break;
        case 6:
	  s_content_value(*ret) = (*caction)(s_content_value(argv[0]), 
					     s_content_value(argv[1]), 
					     s_content_value(argv[2]), 
					     s_content_value(argv[3]),
					     s_content_value(argv[4]), 
					     s_content_value(argv[5]));
          break;
        case 7:
	  s_content_value(*ret) = (*caction)(s_content_value(argv[0]), 
					     s_content_value(argv[1]), 
					     s_content_value(argv[2]), 
					     s_content_value(argv[3]),
					     s_content_value(argv[4]), 
					     s_content_value(argv[5]),
					     s_content_value(argv[6]));
          break;
        case 8:
	  s_content_value(*ret) = (*caction)(s_content_value(argv[0]), 
					     s_content_value(argv[1]), 
					     s_content_value(argv[2]), 
					     s_content_value(argv[3]),
					     s_content_value(argv[4]), 
					     s_content_value(argv[5]),
					     s_content_value(argv[6]), 
					     s_content_value(argv[7]));
          break;
        case 9:
	  s_content_value(*ret) = (*caction)(s_content_value(argv[0]), 
					     s_content_value(argv[1]), 
					     s_content_value(argv[2]), 
					     s_content_value(argv[3]),
					     s_content_value(argv[4]), 
					     s_content_value(argv[5]),
					     s_content_value(argv[6]), 
					     s_content_value(argv[7]),
					     s_content_value(argv[8]));
          break;
        case 10:
	  s_content_value(*ret) = (*caction)(s_content_value(argv[0]), 
					     s_content_value(argv[1]), 
					     s_content_value(argv[2]), 
					     s_content_value(argv[3]),
					     s_content_value(argv[4]), 
					     s_content_value(argv[5]),
					     s_content_value(argv[6]), 
					     s_content_value(argv[7]),
					     s_content_value(argv[8]), 
					     s_content_value(argv[9]));
          break;
        case 11:
	  s_content_value(*ret) = (*caction)(s_content_value(argv[0]), 
					     s_content_value(argv[1]), 
					     s_content_value(argv[2]), 
					     s_content_value(argv[3]),
					     s_content_value(argv[4]), 
					     s_content_value(argv[5]),
					     s_content_value(argv[6]), 
					     s_content_value(argv[7]),
					     s_content_value(argv[8]), 
					     s_content_value(argv[9]),
					     s_content_value(argv[10]));
          break;
        default:
          zz_error(ERROR,"lr_action: too many argument for s-procedure");
       }
     break;
   case ACT_T_EXECUTE_LIST:
     if(rule->action.tag!=tag_list)
       zz_error(ERROR,"lr_action: action list not found");
     else
       {
        static struct s_nt *root_nt=0;
        old_zz_ret_value=zz_ret_value;
        zz_ret_value = *ret;
        push_param_scope();
        for(i=0;i<argc;i++)
          set_param(namev[i],&argv[i]);        
        source_list(&rule->action, NULL);
        if(!root_nt) root_nt=find_nt("root");
	if(zz_trace_mask()&TRACE_ZZACTION)
	  {
	   printz("   @ vvvvvvvvvvvvvvvvvvvv  begin action of %r\n",rule);
	   parse(root_nt);
           printz("   @ ^^^^^^^^^^^^^^^^^^^^  end action of %r\n",rule);
	  }
	else
	  parse(root_nt);
        pop_source();
        pop_param_scope();
        *ret = zz_ret_value;
        zz_ret_value=old_zz_ret_value;
      }
     break;
   case ACT_T_NONE:
     break;
   case ACT_T_RETURN:
     *ret = rule->action;
     if(rule->sproc_tag) ret->tag = rule->sproc_tag;
     break;
   case ACT_T_PASS:
     *ret = argv[0];
     break;
   case ACT_T_RRETURN:
     zz_ret_value = argv[0];
     break;
   case ACT_T_ASSIGN:
     if(argc!=3) zz_error(ERROR,"assign: bad argument number");
     else if(argv[0].tag!=tag_ident) zz_error(ERROR,"assign: bad 1' arg");
     else
       {
	struct s_content value;
	value=argv[1];
	if(argv[2].tag==tag_ident)
	  value.tag = (struct s_tag*)find_tag(s_content_svalue(argv[2]));
        set_param(s_content_svalue(argv[0]),&value);
       }
     break;
   case ACT_T_LIST:
     create_list(ret,10);
     for(i=0;i<argc;i++)
       append_to_list(ret,&argv[i]);
     break;
   case ACT_T_MERGE:
     create_list(ret,10);
     for(i=0;i<argc;i++)
       if(argv[i].tag!=tag_list)
         append_to_list(ret,&argv[i]);
       else 
         merge_list(ret,&argv[i]);
     break;
   case ACT_T_MERGE_ALL:
     create_list(ret,10);
     for(i=0;i<rule->bead_n-1;i++)
       {
        cnt = stack[i];
        if(cnt.tag==tag_list)
          {
           struct s_list *lst;
           lst=(struct s_list*)s_content_value(cnt);
           for(j=0;j<lst->n;j++)
             append_to_list(ret,lst->array+j);
          }
        else       
          append_to_list(ret,&cnt);
       }
     break;
   case ACT_T_APPEND:
     if(argc==0 || argv[0].tag!=tag_list)
       {
        create_list(ret,10);
        for(i=0;i<argc;i++)
          append_to_list(ret,&argv[i]);
       }     
     else
       {
        *ret = argv[0];
        for(i=1;i<argc;i++)
          append_to_list(ret,&argv[i]);
       }
     break;
   default:
     zz_error(WARNING,"lr_action: unknown action type");
     break;  
  }


}

void fprint_action(action)
struct content *action;
{



}

static char rcsid[] = "$Id: action.c,v 1.14 2002/02/13 14:26:28 kibun Exp $ ";