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(); }
/* 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; }