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);
}
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 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 syntaxChk() /* 구문 검사 */
{
  syntaxChk_mode = true;
  for (Pc=1; Pc<(int)intercode.size(); Pc++) {
    code = firstCode(Pc);
    switch (code.kind) {
    case Func: case Option: case Var:                         /* 검사 완료 */
      break;
    case Else: case End: case Exit:
      code = nextCode(); chk_EofLine();
      break;
    case If: case Elif: case While:
      code = nextCode(); (void)get_expression(0, EofLine);            /* 식값 */
      break;
    case For:
      code = nextCode();
      (void)get_memAdrs(code);                              /* 제어 변수 주소 */
      (void)get_expression('=', 0);                                 /* 초깃값 */
      (void)get_expression(To, 0);                                  /* 최종값 */
      if (code.kind == Step) (void)get_expression(Step,0);          /* 증분값 */
      chk_EofLine();
      break;
    case Fcall:                                         /* 대입 없는 함수 호출 */
      fncCall_syntax(code.symNbr);
      chk_EofLine();
      (void)stk.pop();                                          /* 반환 값 불필요 */
      break;
    case Print: case Println:
      sysFncExec_syntax(code.kind);
      break;
    case Gvar: case Lvar:                                           /* 대입문 */
      (void)get_memAdrs(code);                                   /* 좌변 주소 */
      (void)get_expression('=', EofLine);                        /* 우변식 값 */
      break;
    case Return:
      code = nextCode();                                              /* 반환 값 */
      if (code.kind!='?' && code.kind!=EofLine) (void)get_expression();
      if (code.kind == '?') (void)get_expression('?', 0);
      chk_EofLine();
      break;
    case Break:
      code = nextCode();
      if (code.kind == '?') (void)get_expression('?', 0);
      chk_EofLine();
      break;
    case EofLine:
      break;
    default:
      err_exit("잘못된 기술입니다: ", kind_to_s(code.kind));
    }
  }
  syntaxChk_mode = false;
}
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 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 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;
}
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);                                          /* 적당한 반환 값 */
}
Exemple #10
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;
}
// 함수 선언에서 다음의 기본 인수를 지정
// double get_expression(int kind1=0, int kind2=0)
double get_expression(int kind1, int kind2) /* 결과를 반환하는 expression */
{
  expression(kind1, kind2); return stk.pop();
}
void statement() /* 문 */
{
  CodeSet save;
  int top_line, end_line, varAdrs;
  double wkVal, endDt, stepDt;

  if (Pc>maxLine || exit_Flg) return;                     /* 프로그램 종료 */
  code = save = firstCode(Pc);
  top_line = Pc; end_line = code.jmpAdrs;          /* 제어 범위의 시작과 끝 */
  if (code.kind == If ) end_line = endline_of_If(Pc);     /* if문일 때의 끝 */

  switch (code.kind) {
  case If:
    // if
    if (get_expression(If, 0)) {                          /*   참(TRUE)이면    */
      ++Pc; block(); Pc = end_line + 1;                   /*   실행하고     */
      return;                                             /*   종료        */
    }
    Pc = save.jmpAdrs;                                    /*   다음으로         */
    // elif
    while (lookCode(Pc) == Elif) {
      save = firstCode(Pc); code = nextCode();
      if (get_expression()) {                             /*   참(TRUE)이면     */
        ++Pc; block(); Pc = end_line + 1;                 /*   실행하고    */
        return;                                           /*   종료         */
      }
      Pc = save.jmpAdrs;                                  /*   다음으로         */
    }
    // else
    if (lookCode(Pc) == Else) {                           /* else를       */
      ++Pc; block(); Pc = end_line + 1;                   /*   실행하고      */
      return;                                             /* 종료         */
    }
    // end
    ++Pc;
    break;
  case While:
    for (;;) {                                           /*                   */
      if (!get_expression(While, 0)) break;              /*   false 종료   */
      ++Pc; block();                                     /*        [실행]      */
      if (break_Flg || return_Flg || exit_Flg) {         /*                  */
        break_Flg = false; break;                        /*        중단        */
      }                                                  /*                   */
      Pc = top_line; code = firstCode(Pc);               /*   맨 앞으로        */
    }                                                    /*                   */
    Pc = end_line + 1;                                   /*                   */
    break;
  case For:										/* for 제어변수, 초깃값, 최종값, 증분식 */
    save = nextCode();
    varAdrs = get_memAdrs(save);                    /* 제이변수 주소 구하기  */

    expression('=', 0);                                             /* 초깃값   */
    set_dtTyp(save, DBL_T);                                         /* 형 확정  */
    Dmem.set(varAdrs, stk.pop());                             /*   초깃값을 설정  */

    endDt = get_expression(To, 0);                            /* 최종값을 보존   */
                                                              /* 증분값을 보존   */
    if (code.kind == Step) stepDt = get_expression(Step, 0); else stepDt = 1.0;
    for (;; Pc=top_line) {                               /*                   */
      if (stepDt >= 0) {                                 /*   증가 루프         */
        if (Dmem.get(varAdrs) > endDt) break;            /* 거짓이면 종료        */
      } else {                                           /*   감소 루프         */
        if (Dmem.get(varAdrs) < endDt) break;            /* 거짓이면 종료        */
      }                                                  /*                   */
      ++Pc; block();                                     /*   [ 실행 ]         */
      if (break_Flg || return_Flg || exit_Flg) {         /*                   */
        break_Flg = false; break;                        /*    중단            */
      }                                                  /*                   */
      Dmem.add(varAdrs, stepDt);                         /* 값 갱신             */
    }                                                    /*                   */
    Pc = end_line + 1;                                   /*                    */
    break;
  case Fcall:                                           /* 대입이 없는 함수 호출 */
    fncCall(code.symNbr);
    (void)stk.pop();                                            /* 반환 값 불필요 */
    ++Pc;
    break;
  case Func:                                            /* 함수 정의는 건너뀜 */
    Pc = end_line + 1;
    break;
  case Print: case Println:
    sysFncExec(code.kind);
    ++Pc;
    break;
  case Gvar: case Lvar:                                             /* 대입문 */
    varAdrs = get_memAdrs(code);
    expression('=', 0);
    set_dtTyp(save, DBL_T);                                 /* 대입할 때 형 확정*/
    Dmem.set(varAdrs, stk.pop());
    ++Pc;
    break;
  case Return:
    wkVal = returnValue;
    code = nextCode();
    if (code.kind!='?' && code.kind!=EofLine)   /* '식'이 있으면 반환 값을 계산 */
      wkVal = get_expression();
    post_if_set(return_Flg);                                /* ?가 있으면 처리 */
    if (return_Flg) returnValue = wkVal;
    if (!return_Flg) ++Pc;
    break;
  case Break:
    code = nextCode(); post_if_set(break_Flg);              /* ? 가 있으면 처리 */
    if (!break_Flg) ++Pc;
    break;
  case Exit:
    code = nextCode(); exit_Flg = true;
    break;
  case Option: case Var: case EofLine:                        /* 실행 시는 무시 */
    ++Pc;
    break;
  default:
    err_exit("잘못된 기술입니다: ", kind_to_s(code.kind));
  }
}