예제 #1
0
/*
 * execute a stream of instructions, possibly returning a string
 */
char *
exec_stream( pInstr s ) {
    while ( s != NULL) {
	char *r = exec_instr(s);
	if ( r != NULL ) return r;
	s = s->next;
    }

    return NULL;
}
예제 #2
0
파일: exec_instr_not.c 프로젝트: jclanoe/SH
int                     exec_instr_not(s_instr                  *instr,
                                       s_list_dup               *list_dup,
                                       int                      *error)
{
  s_instr_not           *instr_not = NULL;
  int                   res;

  if (instr == NULL || instr->instr == NULL)
    return (-1);

  instr_not = instr->instr;

  res = exec_instr(instr_not->instr, list_dup, error);
  if (*error != ERROR_NONE)
    return (1);

  if (res == 0)
    return (1);
  else
    return (0);
}
예제 #3
0
int                     exec_instr_pipe(s_instr                 *instr,
                                        s_list_dup              *list_dup,
                                        int                     *error)
{
  s_instr_pipe          *instr_pipe = NULL;
  int                   filedes[2];
  int                   res = 0;
  s_list_dup            *dp = NULL;
  s_list_dup            *dp2 = NULL;
  s_list_instr_item     *list_instr = NULL;
  int                   fd_in = STDIN_FILENO;

  if (instr == NULL || instr->instr == NULL)
    return (-1);

  instr_pipe = instr->instr;

  list_instr = instr_pipe->list_instr->first;
  for (; list_instr != NULL; list_instr = list_instr->next)
  {
    if (list_instr->next != NULL)
      mpipe(filedes);
    if (list_instr->next != NULL)
      dp = list_dup_insert(list_dup, filedes[1], STDOUT_FILENO);

    if (list_instr != instr_pipe->list_instr->first)
      dp2 = list_dup_insert(dp == NULL ? list_dup : dp, fd_in, STDIN_FILENO);

    res = exec_instr(list_instr->elmt, dp2 == NULL ? dp : dp2, error);
    close_fds(&fd_in, filedes, list_instr->next);
    free_and_null(&dp, &dp2);

    CHECK_ERROR()
  }

  return (res);
}
예제 #4
0
파일: metacommand.c 프로젝트: BPaden/garglk
static int run_metacommand(int cnum, int *redir_offset)
/* cnum=command number to run. */
/* *redir_offset=offset of redirect header, if we exit with redirection. */
/* Return 
      0 to go on to next metacommand, 
      1 to stop running metacommands,  and 
      2 to end the turn. 
      3 indicates that redirection has just occured 
      4 indicates a subcall has just occured.
      5 Is used to go on to the next metacommand after a Return.
      -2 means we're doing disambiguation and just hit an action token. */
{
  int ip, oip;  /* ip=Instruction pointer, oip=Old instruction pointer */
  int r;        /* Used to hold return value from token execution */
  int fail_addr;  /* What address to jump to on failure */
  rbool fail;    /* Last token was a conditional token that failed */
  rbool ortrue, blocktrue, orflag; /* OR stuff 
				     orflag: Are we in an OR group? 
				     ortrue: Is current OR group true? 
				     blocktrue: Is current block w/in OR true?
				     */
  static rbool restart=0;  /* Restarting after subroutine?  */
  op_rec currop;          /* Information on the current token and its args */
  
  fail_addr=32000; /* Fall off the end when we fail */
  fail=0;
  ip=0;
  orflag=blocktrue=ortrue=0;
  *redir_offset=1;  /* Default: This is what RedirectTo does.
		       Only XRedirect can send a different value */


  if (restart)  /* finish up Return from subroutine */
    pop_subcall(&cnum,&ip,&fail_addr);

  if (DEBUG_AGT_CMD && !supress_debug) {
    debug_head(cnum);
    if (restart) debugout("   (Resuming after subroutine)\n");
  }

  restart=0;

  
  /* ==========  Main Loop ================= */
  while(ip<command[cnum].cmdsize) {

    oip=ip;
    ip+=decode_instr(&currop,command[cnum].data+ip,command[cnum].cmdsize-ip);

    /* -------  OR Logic --------------- */
    if (currop.op==109) { /* OR */
      if (!orflag) { /* First OR; set things up */
	orflag=1;
	ortrue=0;      
	blocktrue=1; 
      }
      blocktrue=blocktrue && !fail; /* Was the previous token true? */
      fail=0;
      ortrue=ortrue||blocktrue;  /* OR in last block */
      blocktrue=1;  /* New block starts out true. */     
    }
    else if (orflag) {  /* we're in the middle of a block */
      blocktrue=blocktrue&&!fail;  /* Add in previous token */
      fail=0;
      if (currop.endor) {  /* i.e. not a conditional token */
	orflag=0;                  /* End of OR block */
	ortrue=ortrue||blocktrue;  /* OR in last block */
	fail=!ortrue;  /* Success of whole group */
      }
    }

    /* ------------  FAILMESSAGE handling ------------- */
    if (currop.failmsg) {  /* Is the current token a Fail... token? */
      if (!fail) continue;  /* Skip it; look at next instruction */
      /* ErrMessage and ErrStdMessage: set disambiguation score */
      if (do_disambig) {
	if (currop.op==1130 || currop.op==1131) {
	  if (!decode_args(oip,&currop)) return 2;
	  disambig_score=currop.arg1;
	  return 2;
	}
	else return -2; /* FailMessage counts as an action token */
      }
      /* Then run the failmessage, skipping the following step... */
    } 
    /* -------- Failure routines -------------------- */
    else if (fail) {  /* ... and not failmessage */
      /* consequences of failure */
      fail=0;  /* In case fail_addr doesn't point off the edge of the world */
      ip=fail_addr;
      fail_addr=32000; /* Reset fail_addr */
      continue; /* Usually fail_addr will fall off the end, causing this to
		   return 0 */
    }

    /* - Finish decoding arguments and print out debugging message - */
    if (!decode_args(oip,&currop)) {
      if (currop.op<1000) fail=currop.negate ? 0 : 1;
      continue;
      /* return 2;*/
    }

    /* -------- Commands that need to be handled specially -------------- */
    if (currop.op==109) {  /* OR */
      if (DEBUG_AGT_CMD && !supress_debug) debug_newline(op,0);
      continue; /* OR: skip further processing */
    }

    if (currop.op==1037) {  /* DoSubroutine */
      if (!push_subcall(cnum,ip,fail_addr)) {
	writeln("GAME ERROR: Subroutine stack overflow.");
	return 2;
      }
      subcall_arg=currop.arg1;
      if (DEBUG_AGT_CMD && !supress_debug) debugout("--> Call\n");
      return 4;
    }

    if (currop.op==1038) { /* Return */
      restart=1;
      if (DEBUG_AGT_CMD && !supress_debug) debugout("--> Return\n");
      return 5;
    }

    if (currop.op==1149) { /* Goto */
      ip=currop.arg1;
      if (DEBUG_AGT_CMD && !supress_debug) debugout("\n");
      continue;
    }

    if (currop.op==1150) { /* OnFailGoto */
      fail_addr=currop.arg1;
      if (DEBUG_AGT_CMD && !supress_debug) debugout("\n");
      continue;
    }

    if (currop.op==1152)  /* XRedirect */
      *redir_offset=currop.arg1;

    /* ---------- Disambiguation Success -------------- */
    if (do_disambig && currop.disambig) {
      if (DEBUG_AGT_CMD && !supress_debug) debugout("==> ACTION\n");
      return -2;
    }

    /* ---------- Run normal metacommands -------------- */
    switch(r=exec_instr(&currop)) 
      {
      case 0:  /* Normal action token or successful conditional token */
	if (DEBUG_AGT_CMD && !supress_debug) debug_newline(op,0);
	continue;
      case 1: /* Conditional token: fail */
	if (DEBUG_AGT_CMD && !supress_debug) {
	  if (orflag) debugout("  (-->FAIL)\n");
	  else debugout("--->FAIL\n");
	}
	fail=1;
	continue;
      default: /* Return explicit value */
	if (DEBUG_AGT_CMD && !supress_debug) {
	  if (r==103) debugout("-->Redirect\n");
	  else debugout("==> END\n");
	}
	return r-100; 
      }
  }
  return 0;
}
예제 #5
0
/* Appel:
 *   tp [-option]* programme.txt
 * Les options doivent apparaitre avant le nom du fichier du programme.
 * Options: -[eE] -[vV] -[hH?]
 */
int main(int argc, char **argv) {
  
  int fi;
  int i, res;
   
  if (argc == 1) {
    fprintf(stderr, "Syntax: zn [-v] program.txt\n");
    exit(USAGE_ERROR);
  }
  
  for(i = 1; i < argc; i++) {
    if (argv[i][0] == '-') {
      switch (argv[i][1]) {
      case 'v': case 'V':
	        verbose = TRUE; continue;  
      case '?': case 'h': case 'H':
	        fprintf(stderr, "Syntax: zn [-v] program.txt\n");
	        exit(USAGE_ERROR);
      default:
	        fprintf(stderr, "Error: Unknown Option: %c\n", argv[i][1]);
	        exit(USAGE_ERROR);
      }
    } else break;
  }

  if (i == argc) {
    fprintf(stderr, "Error: Program file is missing\n");
    exit(USAGE_ERROR);
  }

  if ((fi = open(argv[i++], O_RDONLY)) == -1) {
    fprintf(stderr, "Error: Cannot open %s\n", argv[i-1]);
    exit(USAGE_ERROR);
  }
 
 
                
  /* Initialisations */
  InitializationFinished = FALSE;
  CurrentMethodName = (char*) malloc(128 * sizeof(char));

  initIntegerClass();
  initStringClass();
  initVoidClass();  
  
  initializeScope();
  InitializationFinished = TRUE;
  CurrentClass = NULL;  
  AllDefinedClasses = defaultClassDefsPlus(NULL);
  
  /* redirige l'entree standard sur le fichier.   .. */
  close(0); dup(fi); close(fi);

  /* Lance l'analyse syntaxique de tout le source, en appelant yylex au fur
   * et a mesure. Execute les actions semantiques en parallele avec les
   * reductions.
   * yyparse renvoie 0 si le source est syntaxiquement correct, une valeur
   * differente de 0 en cas d'erreur syntaxique (eventuellement dues a des
   * erreurs lexicales).
   * Comme l'interpretation globale est automatiquement lancee par les actions
   * associees aux reductions, une fois que yyparse a termine il n'y
   * a plus rien a faire (sauf fermer les fichiers)
   * Si le code du programme contient une erreur, on bloque l'evaluation.
   * S'il ny a que des erreurs contextuelles on essaye de ne pas s'arreter
   * a la premiere mais de continuer l'analyse pour en trovuer d'autres, quand
   * c'est possible.
   */
  yydebug = 0;
  res = yyparse();    

  if (fd != NIL(FILE)) fclose(fd);
  if ( !(res == 0 && errorCode == NO_ERROR) )  {
    int res2 = res ? SYNTAX_ERROR : errorCode;
    printf("Error in file. Kind of error: %d\n", res2); 
    return res2;
  }
  
  ProgramTypeAndRedirect(program); 
  InstrTypeAndRedirect(program->instrs, MainScope);
  exec_instr(program->instrs, MainScope);
  
}