Esempio n. 1
0
/* stack operator
**nest**  
> Creates a fresh stack with current TOS on it. Saves current dstack onto
> rstack.
*/
bvm_cache *nest(bvm_cache *this_bvm){ // nest#

    mword *nest_body = dstack_get(this_bvm,0);
//    mword *new_stack = dstack_get(this_bvm,1);
    mword *save_TOS = dstack_get(this_bvm,1);

    popd(this_bvm);
    popd(this_bvm);

    mword *save_dstack = (mword*)icar(this_bvm->dstack_ptr);
    mword *save_ustack = (mword*)icar(this_bvm->ustack_ptr);

    clear(this_bvm); // clear the stack

    //rgive(this_bvm, new_stack);
    pushd(this_bvm, save_TOS, IMMORTAL);

    mword *nest_return = (mword*)icdr(icar(this_bvm->code_ptr));

    mword *nest_rstack_entry = consa2(this_bvm, save_dstack,
                                    consa2(this_bvm, save_ustack,
                                        consa2(this_bvm, nest_return, nil)));

    pushr(this_bvm, nest_rstack_entry, _hash8(C2B("/babel/tag/nest")));

    this_bvm->code_ptr = consa2(this_bvm, nest_body,nil);

    icar(this_bvm->advance_type) = BVM_CONTINUE;

    return this_bvm;    

}
Esempio n. 2
0
void main()
{
    char prefix[50],ch,str[50],operand1[50],operand2[50],oper_ator[2];
    int i=0,k=0,opndcnt=0;
    clrscr();
    printf("\t\t\t * Prefix to Postfix *");
    printf("\n\nEnter the Prefix Expression : ");
    gets(prefix);

    while((ch=prefix[i++])!='\0')
    {
	if(isalnum(ch))
	{
	    str[0]=ch;
	    str[1]='\0';
	    pushd(str);
	    operand_count++;
	    if(operand_count>=2)
	    {
		strcpy(operand2,popd());
		strcpy(operand1,popd());
		strcpy(str,operand1);
		strcat(str,operand2);
		ch=popr();
		oper_ator[0]=ch;
		oper_ator[1]='\0';
		strcat(str,oper_ator);
		pushd(str);
		operand_count-=1;
	    }
	}
	else
	{
	    pushr(ch);
	    /* operator followed by single operand*/
	    if(operand_count==1)
	    operand_count=0;
	}
    }

    if(!empty(topd))
    {
	strcpy(operand2,popd());
	strcpy(operand1,popd());
	strcpy(str,operand1);
	strcat(str,operand2);
	ch=popr();
	oper_ator[0]=ch;
	oper_ator[1]='\0';
	strcat(str,oper_ator);
	pushd(str);
    }
    printf("The Postfix Expression is : ");
    puts(opnds[topd]);
getch();
}
Esempio n. 3
0
File: rpn.c Progetto: pcpa/lightning
/* This function does all of lexing, parsing, and picking a good
   order of evaluation...  Needless to say, this is not the best
   possible design, but it avoids cluttering everything with globals. */
pifi
compile_rpn (char *expr)
{
  struct stack_element stack[32];
  int sp = 0;
  int curr_tos = -1;		/* stack element currently in R0 */
  int spill_base, spill_sp;

  pifi fn;
  int ofs;
  fn = (pifi) (jit_get_ip ().iptr);
  jit_leaf (1);
  ofs = jit_arg_i ();

  spill_sp = spill_base = jit_allocai (32 * sizeof (int));

  while (*expr)
    {
      int with_imm;
      int imm;
      int tok;
      int src1, src2;

      /* This is the lexer.  */
      switch (*expr)
	{
	case ' ': case '\t':
	  expr++;
	  continue;

	case '0': case '1': case '2': case '3': case '4':
	case '5': case '6': case '7': case '8': case '9':
	  stack[sp].kind = IMM;
	  stack[sp++].imm = strtol (expr, &expr, 0);
	  continue;

	case 'x':
	  expr++;
	  stack[sp++].kind = ARG;
	  continue;

	case '~':
	  /* NOT.  Implemented as a XOR with -1.  */
	  stack[sp].kind = IMM;
	  stack[sp++].imm = ~0;
	  tok = '^';
	  break;

	case '_':
	  /* Unary minus.  Transform to 0 - X and go on.
	     Also used to enter negative constants (32_ = -32).  */
	  expr++;
	  stack[sp] = stack[sp - 1];

	  /* Ensure CURR_TOS is correct.  */
	  if (curr_tos == sp - 1)
	    curr_tos = sp;

	  stack[sp - 1].kind = IMM;
	  stack[sp - 1].imm = 0;
	  sp++;
	  tok = '-';
	  break;

	case '+':
	case '-':
	case '*':
	case '/':
	case '%':
	case '&':
	case '|':
	case '^':
	case '=':
	  tok = *expr++;
	  break;

	case '!':
	  /* Get != */
	  expr++;
	  assert (*expr == '=');
	  tok = NE;
	  break;

	case '<':
	  /* Get <, <<, <= */
	  if (expr[1] == '=')
	    expr += 2, tok = LE;
	  else if (expr[1] == '<')
	    expr += 2, tok = LSH;
	  else
	    expr++, tok = '<';
	  break;

	case '>':
	  /* Get >, >>, >>>, >= */
	  if (expr[1] == '=')
	    expr += 2, tok = GE;
	  else if (expr[1] == '>' && expr[2] == '>')
	    expr += 3, tok = RSHU;
	  else if (expr[1] == '>')
	    expr += 2, tok = RSH;
	  else
	    expr++, tok = '>';
	  break;

	default:
	  abort ();
	}

      assert (sp >= 2);

      /* Constant folding.  */
      if (stack[sp - 1].kind == IMM && stack[sp - 2].kind == IMM)
	{
	  stack[sp - 2].imm =
	    fold (stack[sp - 2].imm, stack[sp - 1].imm, tok);
	  sp--;
	  continue;
	}

      /* If possible, ensure that the constant is the RHS, possibly
	 by changing TOK (if it is a comparison).  */
      if (stack[sp - 2].kind == IMM)
	{
	  int swapped_operation = swap_op (tok);
          if (swapped_operation)
	    {
	      tok = swapped_operation;
	      stack[sp - 2].kind = stack[sp - 1].kind;
	      stack[sp - 1].kind = IMM;
	      stack[sp - 1].imm = stack[sp - 2].imm;

	      /* Ensure CURR_TOS is correct.  */
	      if (curr_tos == sp - 1)
	        curr_tos = sp - 2;
	    }
        }

      /* Get the second argument into a register, if not an immediate.
         Also decide which argument will be prepared into JIT_R0 and
         which will be prepared into JIT_V0.  */
      with_imm = 0;
      src1 = JIT_R0;
      src2 = JIT_V0;
      switch (stack[sp - 1].kind)
	{
	case IMM:
	  /* RHS is an immediate, use an immediate instruction.  */
	  with_imm = 1;
	  imm = stack[sp - 1].imm;
	  break;

	case EXPR:
	  /* RHS is an expression, check if it is already in JIT_R0.  */
	  if (curr_tos == sp - 1)
	    {
	      /* Invert the two sources.  */
	      src1 = JIT_V0;
	      src2 = JIT_R0;
	    }
	  else
	    popr (JIT_V0, &spill_sp);

	  curr_tos = -1;
	  break;

	case ARG:
	  jit_getarg_i (JIT_V0, ofs);
	  break;
	}

      /* Get the first argument into a register indicated by SRC1.  */
      switch (stack[sp - 2].kind)
	{
	case IMM:
	  /* LHS is an immediate, check if we must spill the top of stack.  */
	  if (curr_tos != -1)
	    {
	      pushr (JIT_R0, &spill_sp);
	      curr_tos = -1;
	    }

	  jit_movi_i (src1, stack[sp - 2].imm);
	  break;

	case EXPR:
	  /* LHS is an expression, check if it is already in JIT_R0.  */
	  if (curr_tos != sp - 2)
	    {
	      popr (src1, &spill_sp);
	      curr_tos = -1;
	    }
	  else
	    assert (src1 == JIT_R0);
	  break;

	case ARG:
	  if (curr_tos != -1)
	    {
	      pushr (JIT_R0, &spill_sp);
	      curr_tos = -1;
	    }

	  jit_getarg_i (src1, ofs);
	  break;
	}

      /* Set up the new stack entry, which is cached in R0.  */
      sp -= 2;
      curr_tos = sp;
      stack[sp++].kind = EXPR;

      /* Perform the computation.  */
      if (with_imm)
	gen_reg_imm (src1, imm, tok);
      else
	gen_reg_reg (src1, src2, tok);
    }

  assert (sp == 1);
  switch (stack[0].kind)
    {
    case IMM:
      jit_movi_i (JIT_RET, stack[0].imm);
      break;

    case EXPR:
      assert (curr_tos == 0);
      jit_movr_i (JIT_RET, JIT_R0);
      break;

    case ARG:
      jit_getarg_i (JIT_V0, ofs);
      break;
    }

  jit_ret ();
  jit_flush_code ((char *) fn, jit_get_ip ().ptr);

#ifdef LIGHTNING_DISASSEMBLE
  disassemble (stderr, (char *) fn, jit_get_ip ().ptr);
#endif
  return fn;
}