void sysFncExec(TknKind kd) /* 내장함수실행 */
{
  double d;
  string s;

  switch (kd) {
  case Toint:
       code = nextCode();
       stk.push((int)get_expression('(', ')'));               /* 끝수 버림 */
       break;
  case Input:
       nextCode(); nextCode(); code = nextCode();       /* input ( ) 건너뜀 */
       getline(cin, s);                                        /* 1행 읽기  */
       stk.push(atof(s.c_str()));                   /* 숫자로 변환해서 저장 */
       break;
  case Print: case Println:
       do {
         code = nextCode();
         if (code.kind == String) {                             /* 문자열 출력 */
           cout << code.text; code = nextCode();
         } else {
           d = get_expression();             /* 함수 내에서 exit 가능성이 있다 */
           if (!exit_Flg) cout << d;                              /* 수치 출력 */
         }
       } while (code.kind == ',');               /* , 라면 파라미터가 계속된다 */
       if (kd == Println) cout << endl;                  /* println이면 줄바꿈 */
       break;
  }
}
void binaryExpr(TknKind op) /* 이항 연산 */
{
  double d = 0, d2 = stk.pop(), d1 = stk.pop();

  if ((op==Divi || op==Mod || op==IntDivi) && d2==0)
    err_exit("0으로 나누었습니다.");

	switch (op) {
		case Plus:			 d = d1 + d2;  break;
		case Minus:			 d = d1 - d2;  break;
		case Multi:			 d = d1 * d2;  break;
		case Divi:			 d = d1 / d2;  break;
		case Mod:			 d = (int)d1 % (int)d2; break;
		case IntDivi:		 d = (int)d1 / (int)d2; break;
		case Less:			 d = d1 <  d2; break;
		case LessEq:		 d = d1 <= d2; break;
		case Great:			 d = d1 >  d2; break;
		case GreatEq:		d = d1 >= d2; break;
		case Equal:			d = d1 == d2; break;
		case NotEq:			 d = d1 != d2; break;
		case And:			 d = d1 && d2; break;
		case Or:		    d = d1 || d2; break;
		case ExclusiveOr:	d = (int)d1 ^ (int)d2; break;	// Custom
		case Power:			d = (double)MyPower((int)d1, (int)d2); break;	// Custom
		case GCD:			d = (double)MyGCD((int)d1, (int)d2); break;	// Custom AND Push

  }
  stk.push(d);
}
Beispiel #3
0
int main()
{
	Mystack<int> ms;
	ms.push(5);
	ms.push(4);
	ms.push(2);
	ms.push(3);
	ms.push(4);
	cout << ms.min() << endl;
	ms.pop();
	cout << ms.min() << endl;
	ms.pop();
	cout << ms.min() << endl;
	ms.pop(); 
	cout << ms.min() << endl;
	ms.pop();
	cout << ms.min() << endl;
	getchar();
	return 0;
}
void factor() /* 인자 */
{
  TknKind kd = code.kind;

  if (syntaxChk_mode) {                                          /* 구문 chk 시 */
    switch (kd) {
    case Not: case Minus: case Plus:
         code = nextCode(); factor(); stk.pop(); stk.push(1.0);
         break;
    case Lparen:
         expression('(', ')');
         break;
    case IntNum: case DblNum:
         stk.push(1.0); code = nextCode();
         break;
    case Gvar: case Lvar:
         (void)get_memAdrs(code); stk.push(1.0);
         break;
    case Toint: case Input:
         sysFncExec_syntax(kd);
         break;
    case Fcall:
         fncCall_syntax(code.symNbr);
         break;
    case EofLine:
         err_exit("식이 바르지 않습니다.");
    default:
         err_exit("식 오류:", kind_to_s(code));            /* a + = 등에서 발생 */
    }
    return;
  }

  switch (kd) {                                                     /* 실행시 */
  case Not: case Minus: case Plus:
       code = nextCode(); factor();                         /* 다음 값을 획득 */
       if (kd == Not) stk.push(!stk.pop());                      /* !처리한다 */
       if (kd == Minus) stk.push(-stk.pop());                    /* -처리한다 */
       break;                                /* 단항 +는 아무것도 하지 않는다 */
  case Lparen:
       expression('(', ')');
       break;
  case IntNum: case DblNum:
       stk.push(code.dblVal); code = nextCode();
       break;
  case Gvar: case Lvar:
       chk_dtTyp(code);                                 /* 값 설정을 마친 변수인가 */
       stk.push(Dmem.get(get_memAdrs(code)));
       break;
  case Toint: case Input:
       sysFncExec(kd);
       break;
  case Fcall:
       fncCall(code.symNbr);
       break;
  }
}
void term(int n) /* n은 우선 순위 */
{
  TknKind op;
  if (n == 7) { factor(); return; }
  term(n+1);
  while (n == opOrder(code.kind)) {                /* 우선 순위가 같은 연산자가 연속된다 */
    op = code.kind;
    code = nextCode(); term(n+1);
    if (syntaxChk_mode) { stk.pop(); stk.pop(); stk.push(1.0); }   /* 구문 chk 시 */
    else binaryExpr(op);
  }
}
void sysFncExec_syntax(TknKind kd) /* 내장 함수 검사*/
{
  switch (kd) {
  case Toint:
       code = nextCode(); (void)get_expression('(', ')');
       stk.push(1.0);
       break;
  case Input:
       code = nextCode();
       code = chk_nextCode(code, '('); code = chk_nextCode(code, ')');
       stk.push(1.0);                                             /* 적당한 값 */
       break;
  case Print: case Println:
       do {
         code = nextCode();
         if (code.kind == String) code = nextCode();        /* 문자열 출력 확인 */
         else (void)get_expression();                           /* 값 출력 확인 */
       } while (code.kind == ',');                /* , 라면 파라미터가 계속된다 */
       chk_EofLine();
       break;
  }
}
void fncCall_syntax(int fncNbr) /* 함수 호출 검사 */
{
  int argCt = 0;

  code = nextCode(); code = chk_nextCode(code, '(');
  if (code.kind != ')') {                                       /* 인수가 있다 */
    for (;; code=nextCode()) {
      (void)get_expression(); ++argCt;                /* 인수식 처리와 인수 개수 */
      if (code.kind != ',') break;                     /* , 이면 인수가 계속된다 */
    }
  }
  code = chk_nextCode(code, ')');                                /* ) 일 것 */
  if (argCt != Gtable[fncNbr].args)                       /* 인수 개수 검사 */
    err_exit(Gtable[fncNbr].name, " 함수의 인수 개수가 잘못되었습니다");
  stk.push(1.0);                                          /* 적당한 반환 값 */
}
void fncCall(int fncNbr) /* 함수 호출 */
{
  int  n, argCt = 0;
  vector<double> vc;

  // 실인수 저장
  nextCode(); code = nextCode();                         /* 함수명 ( 건너뜀 */
  if (code.kind != ')') {                                    /* 인수가 있다 */
    for (;; code=nextCode()) {
      expression(); ++argCt;                     /* 인수식 처리와 인수 개수 */
      if (code.kind != ',') break;                 /* ,라면 인수가 계속된다 */
    }
  }
  code = nextCode();                                            /* ) 건너뜀 */

  // 인수 저장 순서 변경
  for (n=0; n<argCt; n++) vc.push_back(stk.pop());  /* 뒤에서부터 인수 저장으로 수정*/
  for (n=0; n<argCt; n++) { stk.push(vc[n]); }

  fncExec(fncNbr);                                                /* 함수 실행 */
}
void fncExec(int fncNbr) /* 함수 실행 */
{
  // 함수입구처리1
  int save_Pc = Pc;                                     /* 현재 실행행을 저장 */
  int save_baseReg = baseReg;                          /* 현재 baseReg를 저장 */
  int save_spReg = spReg;                                /* 현재 spReg를 저장 */
  char *save_code_ptr = code_ptr;         /* 현재 실행행 분석용 포인터를 저장 */
  CodeSet save_code = code;                               /* 현재 code를 저장 */

  // 함수입구처리2
  Pc = Gtable[fncNbr].adrs;                                 /* 새로운 Pc 설정 */
  baseReg = spReg;                             /* 새로운 베이스 레지스터 설정 */
  spReg += Gtable[fncNbr].frame;                               /* 프레임 확보 */
  Dmem.auto_resize(spReg);                           /* 메모리 유효 영역 확보 */
  returnValue = 1.0;                                     /* 반환 값의 기본값  */
  code = firstCode(Pc);                                     /* 시작 코드 획득 */

  // 인수 저장 처리
  nextCode(); code = nextCode();                           /* Func ( 건너뜀   */
  if (code.kind != ')') {                                        /* 인수 있음 */
    for (;; code=nextCode()) {
      set_dtTyp(code, DBL_T);                               /* 대입 시 형 확정 */
      Dmem.set(get_memAdrs(code), stk.pop());                /* 실인수 값 저장 */
      if (code.kind != ',') break;                                /* 인수 종료 */
    }
  }
  code = nextCode();                                            /* ) 건너뜀 */

  // 함수 본체 처리
  ++Pc; block(); return_Flg = false;                          /* 함수 본체 처리 */

  // 함수 출구 처리
  stk.push(returnValue);                                        /* 반환 값 설정 */
  Pc       = save_Pc;                                    /* 호출 전 환경을 복원 */
  baseReg  = save_baseReg;
  spReg    = save_spReg;
  code_ptr = save_code_ptr;
  code     = save_code;
}