Beispiel #1
0
ClassItem::ClashType ClassItem::clashWith(ClassItem *other)
{
	qfLogFuncFrame() << data().className() << "vs" << other->data().className();
	auto dt = data();
	auto odt = other->data();
	int t1 = dt.startTimeMin();
	int t2 = t1 + durationMin();
	int ot1 = odt.startTimeMin();
	int ot2 = ot1 + other->durationMin();
	if(ot1 < t2 && ot2 > t1) {
		// overlap
		if(dt.courseId() == odt.courseId()) {
			qfDebug() << "\t ret: CourseOverlap";
			return ClashType::CourseOverlap;
		}
		if(dt.firstCode() == odt.firstCode()) {
			int si = dt.startIntervalMin();
			int osi = odt.startIntervalMin();
			if(si > 0 && osi > 0) {
				int si_gcd = gcd(si, osi);
				if((t1 % si_gcd) == (ot1 % si_gcd)) {
					qfDebug() << "\t ret: 2RunnersOverlap";
					return ClashType::RunnersOverlap;
				}
			}
		}
	}
	qfDebug() << "\t ret: NONE";
	return ClashType::None;
}
Beispiel #2
0
void ClassItem::updateToolTip()
{
	auto dt = data();
	QString tool_tip;
	// HTML tooltip can cause word wrap
	tool_tip = "<html><body>";
	tool_tip += tr("class: <b>%1</b>, %2 runners + %3 vacants<br/>").arg(dt.className()).arg(dt.runsCount()).arg(runsAndVacantCount() - dt.runsCount());
	tool_tip += tr("first code <b>%1</b>, course %2 - %3<br/>").arg(dt.firstCode()).arg(dt.courseId()).arg(dt.courseName());
	tool_tip += tr("vacants before: %1, every: %2, after: %3<br/>").arg(dt.vacantsBefore()).arg(dt.vacantEvery()).arg(dt.vacantsAfter());
	tool_tip += tr("class start: %1, interval: %2, duration: %3, end: %4<br/>").arg(dt.startTimeMin()).arg(dt.startIntervalMin()).arg(durationMin()).arg(dt.startTimeMin() + durationMin());
	tool_tip += tr("map count: %1").arg(dt.mapCount());
	//if(dt.minStartTimeSec() != ClassData::INVALID_START_TIME_SEC || dt.maxStartTimeSec() != ClassData::INVALID_START_TIME_SEC) {
	//	tool_tip += tr("competitors start first: %1, last: %2<br/>").arg(dt.minStartTimeSec() / 60).arg(dt.maxStartTimeSec() / 60);
	//}
	auto clst = clashingClasses();
	if(clst.count()) {
		QStringList sl;
		for(auto *cl : clst) {
			sl << cl->data().className();
		}
		tool_tip += tr("clash with: %1<br/>").arg(sl.join(", "));
	}
	tool_tip += "</body></html>";
	tool_tip.replace(' ', "&nbsp;");
	setToolTip(tool_tip);
}
int endline_of_If(int line) /* if 문에 대응하는 end 위치 */
{
  CodeSet cd;
  char *save = code_ptr;

  
  cd = firstCode(line);
  for (;;) {
    line = cd.jmpAdrs;
    cd = firstCode(line);
    if (cd.kind==Elif || cd.kind==Else) continue;
    if (cd.kind == End) break;
  }
  code_ptr = save;
  return line;
}
Beispiel #4
0
QColor ClassItem::color() const
{
	auto dt = data();
	int hue = dt.firstCode() % 100;
	QColor c;
	c.setHsvF(hue / 100., 1, 1);
	return c;
}
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 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 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));
  }
}