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); }
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; }