示例#1
0
int LineListWrap::find_ypos(unsigned int ypos) {
	wxASSERT(ypos >= 0 && ypos <= height());
	wxASSERT(approxTop >= 0);
	verify();

	if (!size()) return 0;
	wxASSERT(lastLoadedPos != 0 && firstLoadedPos < lastLoadedPos);

	bool do_approx = true;

	while (1) {
		// Often we want one just above or below current window
		if (ypos < (unsigned int)approxTop) {
			// Expand window up a bit
			int recalc = extendwindow(uMinus(firstLoadedPos, WINSIZE/2));

			unsigned int new_ypos = uPluss(ypos, recalc);
			new_ypos = wxMin(new_ypos, height());
			if (new_ypos >= (unsigned int)approxTop) ypos = new_ypos;
		}
		else if (lastValidPos && ypos > yPositions[lastValidPos-1]) {
			// Expand window down a bit
			int recalc = extendwindow(wxMin(last(), lastLoadedPos+(WINSIZE/2)));
			wxASSERT(recalc == 0); // there should be no change of approxTop
		}

		if (ypos >= (unsigned int)approxTop) {
			validate_positions(lastLoadedPos-1); // Make sure lastValidPos is at end of window
			wxASSERT(lastValidPos > 0);

			if (ypos <= yPositions[lastValidPos-1]) { // ypos is inside window
				vector<unsigned int>::iterator posline = lower_bound(yPositions.begin() + firstLoadedPos, yPositions.begin() + lastValidPos, (unsigned int)ypos);
				int index = distance(yPositions.begin(), posline);
				wxASSERT(top(index) <= ypos);
				return index;
			}
			else if (lastValidPos == size()) return last(); // recalc of positions may end up with pos outside text
		}

		// Else we have to find the approximate line
		if (do_approx) {
			wxASSERT(avr_lineheight > 0);
			unsigned int index = ypos / avr_lineheight;
			index = wxMin(index, last());
			extendwindow(index);
			do_approx = false; // only try to approximate once
		}
	}

	wxASSERT(false); // We should never reach here
	return 0; 
}
示例#2
0
int LineListWrap::prepare(int ypos) {
	verify();

	approxDiff = 0;
	if (!size()) return 0;

	if (ypos == -1) {
		validate_positions(last());
	}
	else {
		// adjust ypos a bit so we are sure to get the line above as well
		find_ypos(uMinus(ypos, 100));
	}
	return approxDiff;
}
示例#3
0
int LineListWrap::OnIdle() {
	if (!size()) return 0;
	wxASSERT(lastLoadedPos != 0 && firstLoadedPos < lastLoadedPos);

	//wxLogDebug(wxT("ll.OnIdle %d %d (%d)"), firstLoadedPos, lastLoadedPos, size());

	if (firstLoadedPos > 0) {
		//wxLogDebug("OnIdle 1");
		unsigned int index = uMinus(firstLoadedPos, 100);
		
		// Load positions in extension
		unsigned int line_bottom = 0;
		for (unsigned int i = index; i < firstLoadedPos; ++i) {
			line.SetLine(offset(i), end(i));
			line_bottom = yPositions[i] = line_bottom + line.GetHeight();
		}

		// Calculate new approxTop
		unsigned int new_approxTop = 0;
		if (index) {
			unsigned int loadedheight = yPositions[lastLoadedPos-1] - (firstLoadedPos ? yPositions[firstLoadedPos] : 0);
			avr_lineheight = (yPositions[firstLoadedPos-1] + loadedheight) / (lastLoadedPos - index);
			new_approxTop = index * avr_lineheight;
		}

		// Adjust all positions to new approxTop
		int ext_diff = line_bottom - approxTop;
		for (unsigned int i2 = index; i2 < lastLoadedPos; ++i2) {
			yPositions[i2] += new_approxTop;
			if (i2 >= firstLoadedPos) yPositions[i2] += ext_diff;
		}

		approxTop = new_approxTop;
		firstLoadedPos = index;
		recalc_approx();

/*		int bottom = yPositions[firstLoadedPos];
		for (unsigned int i = firstLoadedPos; i >= index && i <= firstLoadedPos; --i) {
			line.SetLine(offset(i), end(i));
			yPositions[i] = bottom;
			bottom -= line.GetHeight();
		}
		int diff = yPositions[firstLoadedPos-1] - bottom;
		wxASSERT(bottom < (int)yPositions[firstLoadedPos-1]);
		wxASSERT(diff >= 0);
		approxTop -= diff;
		firstLoadedPos = index;
		int aprx = recalc_approx(true);*/
		
		verify();
		return ext_diff;
	}
	else if (lastLoadedPos != size()) {
		//wxLogDebug("OnIdle 2");
		wxASSERT(lastLoadedPos < size());
		int index = wxMin(lastLoadedPos+100, last());
		int top = yPositions[lastLoadedPos-1];
		for (int i = lastLoadedPos; i <= index; ++i) {
			line.SetLine(offset(i), end(i));
			yPositions[i] = top += line.GetHeight();
		}
		if (lastValidPos == lastLoadedPos && posDiff == 0) lastValidPos = index+1;
		lastLoadedPos = index+1;
		int aprx = recalc_approx(); // recalc approximations (below only)
		
		verify();
		return aprx;
	}
	return 0;
}
示例#4
0
int LineListWrap::extendwindow(unsigned int index) {
	wxASSERT(index >= 0 && index < yPositions.size());

	if (size() == 0) return 0;
	if (index >= firstLoadedPos && index < lastLoadedPos) return 0; // in window

	// Check if we can extend current window
	if (index < firstLoadedPos) { // Index above window
		if (WINSIZE > firstLoadedPos || index > firstLoadedPos-WINSIZE) {
			// extend window to index
			index = uMinus(firstLoadedPos, WINSIZE); // do a full block

			// Load positions in extension
			unsigned int line_bottom = 0;
			for (unsigned int i = index; i < firstLoadedPos; ++i) {
				line_bottom = yPositions[i] = line_bottom + line.GetQuickLineHeight(offset(i), end(i));
			}

			// Calculate new approxTop
			unsigned int new_approxTop = 0;
			if (index) {
				unsigned int loadedheight = yPositions[lastLoadedPos-1] - (firstLoadedPos ? yPositions[firstLoadedPos] : 0);
				avr_lineheight = (yPositions[firstLoadedPos-1] + loadedheight) / (lastLoadedPos - index);
				new_approxTop = index * avr_lineheight;
			}

			// Adjust all positions to new approxTop
			int ext_diff = line_bottom - approxTop;
			for (unsigned int i2 = index; i2 < lastLoadedPos; ++i2) {
				yPositions[i2] += new_approxTop;
				if (i2 >= firstLoadedPos) yPositions[i2] += ext_diff;
			}

			approxTop = new_approxTop;
			firstLoadedPos = index;
			recalc_approx();
			return ext_diff;
		}
	}
	else { // Index below window
		if (lastLoadedPos != 0 && index+1 < lastLoadedPos+WINSIZE) {
			// extend window to index
			//index = wxMin(last(), lastLoadedPos+WINSIZE); // do a full block
			int top = yPositions[lastLoadedPos-1];
			for (unsigned int i = lastLoadedPos; i <= index; ++i) {
				yPositions[i] = top += line.GetQuickLineHeight(offset(i), end(i));
			}
			if (lastValidPos == lastLoadedPos) lastValidPos = index+1;
			lastLoadedPos = index+1;

			return recalc_approx(); // recalc approximations (below only)
		}
	}

	// We have to create a new window
	// The window can't go beyond index
	approxDiff = 0;
	int endline = index;
	index = uMinus(index, WINSIZE);

	int top = 0; 
	if (avr_lineheight > 0) top = approxTop = index * avr_lineheight;
	else wxASSERT(approxTop == 0);
	for (int i = index; i <= endline; ++i) {
		top = yPositions[i] = top + line.GetQuickLineHeight(offset(i), end(i));
	}
	firstLoadedPos = index;
	lastValidPos =lastLoadedPos = endline+1;

	wxASSERT(lastValidPos > firstLoadedPos && lastValidPos <= lastLoadedPos);
	wxASSERT(lastValidPos < yPositions.size() || posDiff == 0);

	return recalc_approx(true); // recalc approximations;
}
示例#5
0
obj eval(obj exp){
ev:	assert(!! exp);
    obj rr,lt, rt;
	switch (exp->type) {
	case tInd:
		return doInd(eval(ult(exp)), ul(eval(urt(exp))));
	case LIST:
		return List2v(evalList(ul(exp)));
	case tArray:
		return map_obj(eval, exp);
	case tAnd:
		return prod_eval(ul(exp), mult);
	case MULT:
		return prod_eval(ul(exp), mult);
	case ARITH:
		return prod_eval(ul(exp), add);
	case POW:
		return prod_eval(ul(exp), power);
	case DIVIDE:
		return prod_eval(ul(exp), divide);
	case tRef:
		return retain(uref(exp));
	case tSymbol:
		if( macromode) {
			if(obj rr = search_assoc(car(macro_env), exp)){
				macromode = false;
				// macro lexical scope should be pushed to the stack here
				rr = exec(rr);
				macromode = true;
				return rr;
			}
		}
		return eval_symbol(exp);
	case tMinus:
		lt = eval(uref(exp));
		rr = uMinus(lt);	// releasing
		if(rr) {release(lt); return rr;}
		static obj symumn = Symbol("-");
		rr = udef_op0(symumn, lt);
		if(rr) {release(lt); return rr;}
		error("uMinus: not defined to that type");
	case tReturn:
		if(! uref(exp)) return encap(tSigRet, nil);
		return  encap(tSigRet, eval(uref(exp)));
	case tBreak:
		return retain(exp);
	case CONDITION:
		return evalCond(exp);
	case tOp:
		if(type(ult(exp)) ==tSymbol) {
			lt = search_assoc(curr_interp->types, ult(exp));
			if(lt) return encap((ValueType)vrInt(lt), eval(urt(exp)));}
		lt = eval(ult(exp));
		push(lt);
		switch(lt->type){
		case tCont:
			assert(0);
		case tSpecial:
			rr = ufn(lt)(urt(exp));
			break;
		case tSyntaxLam:
			rr = macro_exec(lt, urt(exp));
			break;
		case tInternalFn:
        case tClosure:
			rt = eval(urt(exp));
			rr = eval_function(lt, rt);
			break;
        default:
			rt = eval(urt(exp));
			rr = call_fn(mult, lt, rt);
			release(rt);
		}
		release(pop(&is));
		return rr;
	case tClosure:
		assert(0);
	case tCurry:
		return eval_curry(exp, em0(exp));
/*		obj vars = Assoc();
		bind_vars(&vars, em0(exp), em2(exp));
		rr = eval_curry(exp, vars);
		release(vars);
		return rr;
*/	case tArrow:
//		return enclose(exp);
/*		if(macromode){
			if(obj rr = search_assoc(car(macro_env), exp)){
			}
		}
*/ 		return render(tClosure, list3(retain(em0(exp)), retain(em1(exp)), retain(env)));
	case tDefine:
		return func_def(em0(exp), em1(exp), em2(exp));
	case tSyntaxDef:
		let(lfind_var(em0(exp)),  render(tSyntaxLam, list3(retain(em1(exp)), retain(em2(exp)), nil)));
		return nil;
	case tExec:
		return exec(exp);
	case tAssign:
		lt = car(exp);
		if(type(lt)==tOp){
			return func_def(ult(lt), urt(lt), cdr(exp));
		} else if(type(lt)==tMinus){
			static obj symumn = Symbol("-");
			return func_def(symumn, uref(lt), cdr(exp));
		} else return do_assign(lt, eval(cdr(exp)));
	case tIf:
		rr = eval(em0(exp));
		if (type(rr) != INT) error("if: Boolean Expected");
		if (vrInt(rr)) {
			rr = em1(exp);
		} else {
			rr = em2(exp);
		}
		return eval(rr);
	case tWhile:
		for(;;) {
			rr = eval(car(exp));
			if (type(rr) != INT) error("while: Boolean expected");
			if(!vrInt(rr)) break;
			rr = exec(cdr(exp));
			if(rr && type(rr)==tSigRet) return rr;
			if(rr && type(rr)==tBreak) {release(rr); break;}
			if(rr) release(rr);
		}
		return nil;
	default:
		return retain(exp);
	}
}