Exemple #1
0
int obj_equals(Object a, Object b){
    if(TM_TYPE(a) != TM_TYPE(b)) return 0;
    switch(TM_TYPE(a)){
        case TYPE_NUM:return GET_NUM(a) == GET_NUM(b);
        case TYPE_STR: {
            String* s1 = GET_STR_OBJ(a);
            String* s2 = GET_STR_OBJ(b);
            return s1->value == s2->value || 
                (s1->len == s2->len && strncmp(s1->value, s2->value, s1->len) == 0);
        }
        case TYPE_LIST:    {
            if(GET_LIST(a) == GET_LIST(b)) return 1;
            int i;
            int len = GET_LIST(a)->len;
            Object* nodes1 = GET_LIST(a)->nodes;
            Object* nodes2 = GET_LIST(b)->nodes;
            for(i = 0; i < len; i++){
                if(!obj_equals(nodes1[i], nodes2[i]) ){
                    return 0;
                }
            }
            return 1;
        }
        case TYPE_NONE:return 1;
        case TYPE_DICT:return GET_DICT(a) == GET_DICT(b);
        case TYPE_FUNCTION: return GET_FUNCTION(a) == GET_FUNCTION(b);
        default: {
            const char* ltype = tm_type(a.type);
            const char* rtype = tm_type(b.type);
            tm_raise("equals(): not supported type %d:%s and %d:%s", TM_TYPE(a), ltype, TM_TYPE(b), rtype);
        } 
    }
    return 0;
}
Exemple #2
0
Object obj_add(Object a, Object b) {
    if (TM_TYPE(a) == TM_TYPE(b)) {
        switch (TM_TYPE(a)) {
        case TYPE_NUM:
            GET_NUM(a) += GET_NUM(b);
            return a;
        case TYPE_STR: {
            char* sa = GET_STR(a);
            char* sb = GET_STR(b);
            int la = GET_STR_LEN(a);
            int lb = GET_STR_LEN(b);
            if (la == 0) {return b;    }
            if (lb == 0) {return a;    }
            int len = la + lb;
            Object des = string_alloc(NULL, len);
            char*s = GET_STR(des);
            memcpy(s, sa, la);
            memcpy(s + la, sb, lb);
            return des;
        }
        case TYPE_LIST: {
            return list_add(GET_LIST(a), GET_LIST(b));
        }
        }
    }
    tm_raise("obj_add: can not add %o and %o", (a), (b));
    return NONE_OBJECT;
}
Exemple #3
0
void push_exception(TmFrame* f){
    Object file = get_file_name_obj(f->fnc);
    Object fnc_name = get_func_name_obj(f->fnc);
    Object ex = tm_format("  File %o: in %o , at line %d", file, fnc_name,
            f->lineno);
    list_append(GET_LIST(tm->ex_list), ex);
}
void CLibraryDetailView::OnFindItemA(NMLVFINDITEM* pNotify, LRESULT* pResult)
{
	USES_CONVERSION;
	LPCTSTR pszFind = A2CT( (LPCSTR)pNotify->lvfi.psz );
	
	GET_LIST();
	CQuickLock oLock( Library.m_pSection );

	for ( int nLoop = 0 ; nLoop < 2 ; nLoop++ )
	{
		for ( int nItem = pNotify->iStart ; nItem < pList->GetItemCount() ; nItem++ )
		{
			if ( CLibraryFile* pFile = Library.LookupFile( m_pList[ nItem ].nIndex ) )
			{
				if ( pNotify->lvfi.flags & LVFI_STRING )
				{
					if ( _tcsnicmp( pszFind, pFile->m_sName, _tcslen( pszFind ) ) == 0 )
					{
						*pResult = nItem;
						return;
					}
				}
			}
		}
		pNotify->iStart = 0;
	}

	*pResult = -1;
}
BOOL CLibraryDetailView::Select(DWORD nObject)
{
	GET_LIST();
	
	for ( int nDeselect = -1 ; ; )
	{
		nDeselect = pList->GetNextItem( nDeselect, LVNI_SELECTED );
		if ( nDeselect < 0 ) break;
		pList->SetItemState( nDeselect, 0, LVIS_SELECTED );
	}
	
	LDVITEM* pItem = m_pList;
	
	for ( DWORD nCount = 0 ; nCount < m_nList ; nCount++, pItem++ )
	{
		if ( pItem->nIndex == nObject )
		{
			LV_ITEM pItem;
			
			pItem.mask = LVIF_STATE; pItem.state = 0xFFFFFFFF; pItem.stateMask = LVIS_SELECTED|LVIS_FOCUSED;
			SendMessage( LVM_SETITEMSTATE, nCount, (LPARAM)&pItem );
			PostMessage( LVM_ENSUREVISIBLE, nCount, FALSE );
			
			return TRUE;
		}
	}
	
	return FALSE;
}
DWORD CLibraryDetailView::HitTestIndex(const CPoint& point) const
{
	GET_LIST();
	int nItem = pList->HitTest( point );
	if ( nItem < 0 ) return 0;
	return m_pList[ nItem ].nIndex;
}
int CLibraryDetailView::OnCreate(LPCREATESTRUCT lpCreateStruct) 
{
	if ( CLibraryFileView::OnCreate( lpCreateStruct ) == -1 ) return -1;
	
	SendMessage( LVM_SETEXTENDEDLISTVIEWSTYLE,
		LVS_EX_FULLROWSELECT|LVS_EX_HEADERDRAGDROP,
		LVS_EX_FULLROWSELECT|LVS_EX_HEADERDRAGDROP );
	
	GET_LIST();
	
	pList->InsertColumn( 0, _T("File"), LVCFMT_LEFT, 200, -1 );
	pList->SetCallbackMask( LVIS_SELECTED );
	
	if ( m_nStyle == LVS_REPORT )
	{
		pList->InsertColumn( 1, _T("Extension"), LVCFMT_CENTER, 40, 0 );
		pList->InsertColumn( 2, _T("Size"), LVCFMT_CENTER, 60, 1 );
		pList->InsertColumn( 3, _T("Folder"), LVCFMT_LEFT, 0, 2 );
		pList->InsertColumn( 4, _T("Hits"), LVCFMT_CENTER, 70, 3 );
		pList->InsertColumn( 5, _T("Uploads"), LVCFMT_CENTER, 70, 4 );
		pList->InsertColumn( 6, _T("Modified"), LVCFMT_CENTER, 0, 5 );
		pList->SetImageList( ShellIcons.GetObject( 16 ), LVSIL_SMALL );

		CHeaderCtrl* pHeader = (CHeaderCtrl*)GetWindow( GW_CHILD );
		if ( pHeader ) Skin.Translate( _T("CLibraryWnd"), pHeader );
	}
	else if ( m_nStyle != LVS_ICON )
	{
		pList->SetImageList( ShellIcons.GetObject( 16 ), LVSIL_SMALL );
	}
	else
	{
		pList->SetImageList( ShellIcons.GetObject( 32 ), LVSIL_NORMAL );
	}
	
	pList->SetCallbackMask( LVIS_SELECTED );
	
	m_pList	= NULL;
	m_nList	= m_nBuffer = 0;
	
	CString strSchemaURI = Settings.Library.FilterURI.GetLength() ?
		Settings.Library.FilterURI : Settings.Library.SchemaURI;
	
	if ( CSchema* pSchema = SchemaCache.Get( strSchemaURI ) )
	{
		CPtrList pColumns;
		CSchemaColumnsDlg::LoadColumns( pSchema, &pColumns );
		SetViewSchema( pSchema, &pColumns, FALSE, FALSE );
	}
	else
	{
		SetViewSchema( NULL, NULL, FALSE, FALSE );
	}
	
	m_bCreateDragImage	= FALSE;
	
	return 0;
}
void CLibraryDetailView::CacheSelection()
{
	GET_LIST();
	SelClear( FALSE );
	
	for ( int nItem = -1 ; ( nItem = pList->GetNextItem( nItem, LVNI_SELECTED ) ) >= 0 ; )
	{
		SelAdd( pList->GetItemData( nItem ), FALSE );
	}
}
Exemple #9
0
void tm_raise(char* fmt, ...) {
    va_list a;
    va_start(a, fmt);
    list_clear(GET_LIST(tm->ex_list));
    tm->ex = tm_format_va_list(fmt, a, 0);
    Object file = get_file_name_obj(tm->frame->fnc);
    Object fnc_name = get_func_name_obj(tm->frame->fnc);
    tm->ex_line = tm_format("File %o: in %o at line %d\n  %os", 
        file, fnc_name, tm->frame->lineno, tm->ex);
    va_end(a);
    longjmp(tm->frame->buf, 1);
}
Exemple #10
0
// func Object tm_str(Object a)
Object tm_str(Object a) {
    char buf[100];
    memset(buf, 0, sizeof(buf));
    switch (TM_TYPE(a)) {
    case TYPE_STR:
        return a;
    case TYPE_NUM: {
        char s[20];
        double v = GET_NUM(a);
        number_format(s, a);
        return string_new(s);
    }
    case TYPE_LIST: {
        Object str = string_new("");

        str = string_append_char(str, '[');
        int i, l = LIST_LEN(a);
        for (i = 0; i < l; i++) {
            Object obj = GET_LIST(a)->nodes[i];
            /* reference to self in list */
            if (obj_equals(a, obj)) {
                str = string_append_sz(str, "[...]");
            } else if (obj.type == TYPE_STR) {
                str = string_append_char(str, '"');
                str = string_append_obj(str, obj);
                str = string_append_char(str, '"');
            } else {
                str = string_append_obj(str, obj);
            }
            if (i != l - 1) {
                str = string_append_char(str, ',');
            }
        }
        str = string_append_char(str, ']');
        return str;
    }
    case TYPE_DICT:
        sprintf(buf, "<dict at %p>", GET_DICT(a));
        return string_new(buf);
    case TYPE_FUNCTION:
        function_format(buf, a);
        return string_new(buf);
    case TYPE_NONE:
        return sz_to_string("None");
    case TYPE_DATA:
        return GET_DATA(a)->str(GET_DATA(a));
    default:
        tm_raise("str: not supported type %d", a.type);
    }
    return string_alloc("", 0);
}
Exemple #11
0
void obj_del(Object self, Object k) {
    switch(TM_TYPE(self)) {
        case TYPE_DICT:{
            dict_del(GET_DICT(self), k);
            break;
        }
        case TYPE_LIST:{
            list_del(GET_LIST(self), k);
            break;
        }
        default:
            tm_raise("obj_del: not supported type %s", tm_type(self.type));
    }
}
Exemple #12
0
Object obj_get(Object self, Object k) {
    Object v;
    switch (TM_TYPE(self)) {
    case TYPE_STR: {
        DictNode* node;
        if (TM_TYPE(k) == TYPE_NUM) {
            double d = GET_NUM(k);
            int n = d;
            if (n < 0) {
                n += GET_STR_LEN(self);
            }
            if (n >= GET_STR_LEN(self) || n < 0)
                tm_raise("String_get: index overflow ,len=%d,index=%d, str=%o",
                        GET_STR_LEN(self), n, self);
            return string_chr(0xff & GET_STR(self)[n]);
        } else if ((node = dict_get_node(GET_DICT(tm->str_proto), k)) != NULL) {
            return method_new(node->val, self);
        }
        break;
    }
    case TYPE_LIST:{
        DictNode* node;
        if (TM_TYPE(k) == TYPE_NUM) {
            return list_get(GET_LIST(self), GET_NUM(k));
        } else if ((node = dict_get_node(GET_DICT(tm->list_proto), k))!=NULL) {
            return method_new(node->val, self);
        }
        break;
    }
    case TYPE_DICT:{
        DictNode* node;
        node = dict_get_node(GET_DICT(self), k);
        if (node != NULL) {
            return node->val;
        } else if ((node = dict_get_node(GET_DICT(tm->dict_proto), k))!=NULL) {
            return method_new(node->val, self);
        }
        break;
    }
    case TYPE_FUNCTION:
        return get_func_attr(GET_FUNCTION(self), k);
    case TYPE_DATA:
        return GET_DATA(self)->get(GET_DATA(self), k);
    }
    tm_raise("keyError %o", k);
    return NONE_OBJECT;
}
Exemple #13
0
void obj_set(Object self, Object k, Object v) {
    // gc_mark_single(k); // used between gc scan
    // gc_mark_single(v); // only need to mark single.
    switch (TM_TYPE(self)) {
    case TYPE_LIST: {
        tm_assert_type(k, TYPE_NUM, "obj_set");
        double d = GET_NUM(k);
        tm_assert_int(d, "list_set");
        list_set(GET_LIST(self), (int)d, v);
    }
        return;
    case TYPE_DICT:
        dict_set0(GET_DICT(self), k, v);
        return;
    }
    tm_raise("obj_set: Self %o, Key %o, Val %o", self, k, v);
}
void CLibraryDetailView::OnBeginDrag(NM_LISTVIEW* pNotify, LRESULT* pResult)
{
	GET_LIST();

	CPoint ptAction( pNotify->ptAction );

	m_bCreateDragImage = TRUE;
	CImageList* pImage = CLiveList::CreateDragImage( pList, ptAction );
	m_bCreateDragImage = FALSE;

	if ( pImage == NULL ) return;

	UpdateWindow();

	ClientToScreen( &ptAction );
	DragObjects( pImage, ptAction );
}
void CLibraryDetailView::SortItems(int nColumn)
{
	GET_LIST();
	
	CLiveList::Sort( pList, nColumn );
	nColumn = ( m_nStyle == LVS_REPORT ) ? GetWindowLong( GetSafeHwnd(), GWL_USERDATA ) : -1;

	if ( nColumn != 0 ) 
	{
		m_nSortColumn	= abs( nColumn ) - 1;
		m_bSortFlip		= nColumn < 0;
		m_pThis			= this;
		qsort( m_pList, m_nList, sizeof(m_pList[0]), ListCompare );
	}

	pList->SetItemCount( m_nList );
}
void CLibraryDetailView::SetViewSchema(CSchema* pSchema, CPtrList* pColumns, BOOL bSave, BOOL bUpdate)
{
	GET_LIST();
	
	pList->DeleteAllItems();
	
	if ( m_nStyle != LVS_REPORT )
	{
		if ( bUpdate ) PostUpdate();
		return;
	}

	if ( bSave )
	{
		if ( m_pSchema )
		{
			Settings.SaveList( _T("CLibraryDetailView.") + m_pSchema->m_sSingular, pList );
		}
		else
		{
			Settings.SaveList( _T("CLibraryDetailView"), pList );
		}
	}
	
	m_pColumns.RemoveAll();
	if ( m_pSchema = pSchema ) m_pColumns.AddTail( pColumns );
	
	int nColumn = DETAIL_COLUMNS;
	while ( pList->DeleteColumn( nColumn ) );
	
	for ( POSITION pos = m_pColumns.GetHeadPosition() ; pos ; nColumn++ )
	{
		CSchemaMember* pMember = (CSchemaMember*)m_pColumns.GetNext( pos );
		pList->InsertColumn( nColumn, pMember->m_sTitle, pMember->m_nColumnAlign, pMember->m_nColumnWidth, nColumn - 1 );
	}

	if ( m_pSchema )
		Settings.LoadList( _T("CLibraryDetailView.") + m_pSchema->m_sSingular, pList, 1 );
	else
		Settings.LoadList( _T("CLibraryDetailView"), pList, 1 );

	if ( bUpdate ) PostUpdate();
}
Exemple #17
0
/* parent has child
 * child in parent
 */
int obj_in(Object child, Object parent) {
    switch (TM_TYPE(parent)) {
    case TYPE_LIST: {
        return (list_index(GET_LIST(parent), child) != -1);
    }
    case TYPE_STR: {
        if (TM_TYPE(child) != TYPE_STR)
            return 0;
        return string_index(GET_STR_OBJ(parent), GET_STR_OBJ(child), 0) != -1;
    }
    case TYPE_DICT: {
        DictNode* node = dict_get_node(GET_DICT(parent), child);
        if (node == NULL) {
            return 0;
        }
        return 1;
    }
    }
    return 0;
}
Exemple #18
0
Object obj_append(Object a, Object item) {
    if (IS_LIST(a)) {
        list_append(GET_LIST(a), item);
    }
    return a;
}
Exemple #19
0
/** 
** evaluate byte code.
** @param f: Frame
** @return evaluated value.
*/
Object tm_eval(TmFrame* f) {
    Object* locals    = f->locals;
    Object* top       = f->stack;
    Object cur_fnc    = f->fnc;
    Object globals    = get_globals(cur_fnc);
    // TODO use code cache to replace unsigned char*
    unsigned char* pc = f->pc;
    const char* func_name_sz = get_func_name_sz(cur_fnc);

    Object x, k, v;
    Object ret = NONE_OBJECT;
    int i;

    #if INTERP_DB
        printf("File \"%s\": enter function %s\n",get_func_file_sz(cur_fnc), get_func_name_sz(cur_fnc));
    #endif
    while (1) {
        i = (pc[1] << 8) | pc[2];
        
        #if INTERP_DB
            printf("%30s%2d: %d frame = %d, top = %d\n","", pc[0], i, tm->cur, (int) (top - f->stack));
        #endif    
        switch (pc[0]) {

        case OP_NUMBER: {
            double d = atof((char*)pc + 3);
            pc += i;
            v = tm_number(d);
            /* obj_append(tm->constants,v);*/
            dict_set(tm->constants, v, NONE_OBJECT);
            break;
        }

        case OP_STRING: {
            v = string_alloc((char*)pc + 3, i);
            pc += i;
            /* obj_append(tm->constants,v); */
            dict_set(tm->constants, v, NONE_OBJECT);
            break;
        }

        case OP_IMPORT: {
            // TODO
            // tm_import(globals)
            Object import_func = tm_get_global(globals, "_import");
            arg_start();
            arg_push(globals);
            Object modname, attr;
            
            if (i == 1) {
                modname = TM_POP();
                arg_push(modname); // arg1
            } else {
                attr = TM_POP();
                modname = TM_POP();
                arg_push(modname);
                arg_push(attr);
            }
            call_function(import_func);
            break;
        }
        case OP_CONSTANT: {
            TM_PUSH(GET_CONST(i));
            break;
        }
        
        case OP_NONE: {
            TM_PUSH(NONE_OBJECT);
            break;
        }

        case OP_LOAD_LOCAL: {
            TM_PUSH(locals[i]);
            break;
        }

        case OP_STORE_LOCAL:
            locals[i] = TM_POP();
            break;

        case OP_LOAD_GLOBAL: {
            /* tm_printf("load global %o\n", GET_CONST(i)); */
            int idx = dict_get_attr(GET_DICT(globals), i);
            if (idx == -1) {
                idx = dict_get_attr(GET_DICT(tm->builtins), i);
                if (idx == -1) {
                    tm_raise("NameError: name %o is not defined", GET_CONST(i));
                } else {
                    Object value = GET_DICT(tm->builtins)->nodes[idx].val;
                    // OPTIMIZE
                    // set the builtin to `globals()`
                    obj_set(globals, GET_CONST(i), value);
                    idx = dict_get_attr(GET_DICT(globals), i);
                    pc[0] = OP_FAST_LD_GLO;
                    code16(pc+1, idx);
                    // OPTIMIZE END
                    TM_PUSH(value);
                }
            } else {
                TM_PUSH(GET_DICT(globals)->nodes[idx].val);
                pc[0] = OP_FAST_LD_GLO;
                code16(pc+1, idx);
            }
            break;
        }
        case OP_STORE_GLOBAL: {
            x = TM_POP();
            int idx = dict_set_attr(GET_DICT(globals), i, x);
            pc[0] = OP_FAST_ST_GLO;
            code16(pc+1, idx);
            break;
        }
        case OP_FAST_LD_GLO: {
            TM_PUSH(GET_DICT(globals)->nodes[i].val);
            break;
        }
        case OP_FAST_ST_GLO: {
            GET_DICT(globals)->nodes[i].val = TM_POP();
            break;
        }
        case OP_LIST: {
            TM_PUSH(list_new(2));
            FRAME_CHECK_GC();
            break;
        }
        case OP_APPEND:
            v = TM_POP();
            x = TM_TOP();
            tm_assert(IS_LIST(x), "tm_eval: OP_APPEND require list");
            list_append(GET_LIST(x), v);
            break;
        case OP_DICT_SET:
            v = TM_POP();
            k = TM_POP();
            x = TM_TOP();
            tm_assert(IS_DICT(x), "tm_eval: OP_DICT_SET require dict");
            obj_set(x, k, v);
            break;
        case OP_DICT: {
            TM_PUSH(dict_new());
            FRAME_CHECK_GC();
            break;
        }
        TM_OP(OP_ADD, obj_add)
        TM_OP(OP_SUB, obj_sub)
        TM_OP(OP_MUL, obj_mul)
        TM_OP(OP_DIV, obj_div)
        TM_OP(OP_MOD, obj_mod)
        TM_OP(OP_GET, obj_get)
        case OP_SLICE: {
            Object second = TM_POP();
            Object first = TM_POP();
            *top = obj_slice(*top, first, second);
            break;
        }
        case OP_EQEQ: { *(top-1) = tm_number(obj_equals(*(top-1), *top)); top--; break; }
        case OP_NOTEQ: { *(top-1) = tm_number(!obj_equals(*(top-1), *top)); top--; break; }
        case OP_LT: {
            *(top-1) = tm_number(obj_cmp(*(top-1), *top)<0);
            top--;
            break;
        }
        case OP_LTEQ: {
            *(top-1) = tm_number(obj_cmp(*(top-1), *top)<=0);
            top--;
            break;
        }
        case OP_GT: {
            *(top-1) = tm_number(obj_cmp(*(top-1), *top)>0);
            top--;
            break;
        }
        case OP_GTEQ: {
            *(top-1) = tm_number(obj_cmp(*(top-1), *top)>=0);
            top--;
            break;
        }
        case OP_IN: {
            *(top-1) = tm_number(obj_in(*(top-1), *top));
            top--;
            break;
        }
        case OP_AND: {
            *(top-1) = tm_number(is_true_obj(*(top-1)) && is_true_obj(*top));
            top--;
            break;
        }
        case OP_OR: {
            *(top-1) = tm_number(is_true_obj(*(top-1)) || is_true_obj(*top));
            top--;
            break;
        }
        case OP_NOT:{
            *top = tm_number(!is_true_obj(*top));
            break;
        }
        case OP_SET:
            k = TM_POP();
            x = TM_POP();
            v = TM_POP();
            #if INTERP_DB
                tm_printf("Self %o, Key %o, Val %o\n", x, k, v);
            #endif
            obj_set(x, k, v);
            break;
        case OP_POP: {
            top--;
            break;
        }
        case OP_NEG:
            TM_TOP() = obj_neg(TM_TOP());
            break;
        case OP_CALL: {
            f->top = top;
            top -= i;
            arg_set_arguments(top + 1, i);
            Object func = TM_POP();
            
            TM_PUSH(call_function(func));
            // TM_PUSH(call_function(func));
            tm->frame = f;
            FRAME_CHECK_GC();
            break;
        }
        
        case OP_APPLY: {
            f->top = top;
            Object args = TM_POP();
            tm_assert_type(args, TYPE_LIST, "tm_eval: OP_APPLY");
            arg_set_arguments(LIST_NODES(args), LIST_LEN(args));
            Object func = TM_POP();
            x = call_function(func);
            TM_PUSH(x);
            tm->frame = f;
            FRAME_CHECK_GC();
            break;
        }
        case OP_LOAD_PARAMS: {
            int parg = pc[1];
            int varg = pc[2];
            if (tm->arg_cnt < parg || tm->arg_cnt > parg + varg) {
                tm_raise("ArgError,parg=%d,varg=%d,given=%d", 
                    parg, varg, tm->arg_cnt);
            }
            for(i = 0; i < tm->arg_cnt; i++){
                locals[i] = tm->arguments[i];
            }
            break;
        }
        case OP_LOAD_PARG: {
            int parg = i;
            for (i = 0; i < parg; i++) {
                locals[i] = arg_take_obj(func_name_sz);
            }
            break;
        }
        case OP_LOAD_NARG: {
            int arg_index = i;
            Object list = list_new(tm->arg_cnt);
            while (arg_remains() > 0) {
                obj_append(list, arg_take_obj(func_name_sz));
            }
            locals[arg_index] = list;
            break;
        }
        case OP_ITER: {
            *top = iter_new(*top);
            break;
        }
        case OP_NEXT: {
            Object *next = next_ptr(*top);
            if (next != NULL) {
                TM_PUSH(*next);
                break;
            } else {
                pc += i * 3;
                continue;
            }
            break;
        }
        case OP_DEF: {
            Object mod = GET_FUNCTION(cur_fnc)->mod;
            Object fnc = func_new(mod, NONE_OBJECT, NULL);
            pc = func_resolve(GET_FUNCTION(fnc), pc);
            GET_FUNCTION_NAME(fnc) = GET_CONST(i);
            TM_PUSH(fnc);
            continue;
        }
        case OP_RETURN: {
            ret = TM_POP();
            goto end;
        }
        case OP_ROT: {
            int half = i / 2;
            int j;
            for (j = 0; j < half; j++) {
                Object temp = *(top - j);
                *(top-j) = *(top - i + j + 1);
                *(top-i+j+1) = temp;
            }
            break;
        }
        case OP_UNPACK: {
            x = TM_POP();
            tm_assert_type(x, TYPE_LIST, "tm_eval:UNPACK");
            int j;
            for(j = LIST_LEN(x)-1; j >= 0; j--) {
                TM_PUSH(LIST_GET(x, j));
            }
            break;
        }

        case OP_DEL: {
            k = TM_POP();
            x = TM_POP();
            obj_del(x, k);
            break;
        }

        case OP_POP_JUMP_ON_FALSE: {
            if (!is_true_obj(TM_POP())) {
                pc += i * 3;
                continue;
            }
            break;
        }

        case OP_JUMP_ON_TRUE: {
            if (is_true_obj(TM_TOP())) {
                pc += i * 3;
                continue;
            }
            break;
        }

        case OP_JUMP_ON_FALSE: {
            if (!is_true_obj(TM_TOP())) {
                pc += i * 3;
                continue;
            }
            break;
        }

        case OP_UP_JUMP:
            pc -= i * 3;
            continue;

        case OP_JUMP:
            pc += i * 3;
            continue;

        case OP_EOP:
        case OP_EOF: {
           ret = NONE_OBJECT;
           goto end;
        }

        case OP_LOAD_EX: { top = f->last_top; TM_PUSH(tm->ex); break; }
        case OP_SETJUMP: { f->last_top = top; f->jmp = pc + i * 3; break; }
        case OP_CLR_JUMP: { f->jmp = NULL; break;}
        case OP_LINE: { f->lineno = i; break;}

        case OP_DEBUG: {
            #if 0
            Object fdebug = tm_get_global(globals, "__debug__");
            f->top = top;
            tm_call(0, fdebug, 1, tm_number(tm->frame - tm->frames));        
            break;
            #endif
        }
        
        case OP_FILE: {
            // module name here.
            break;
        }

        default:
            tm_raise("BAD INSTRUCTION, %d\n  globals() = \n%o", pc[0],
                    GET_FUNCTION_GLOBALS(f->fnc));
            goto end;
        }

        pc += 3;
    }

    end:
    /*
    if (top != f->stack) {
        tm_raise("tm_eval: operand stack overflow");
    }*/
    pop_frame();
    return ret;
}
void CLibraryDetailView::Update()
{
	GET_LIST();
	
	CSchema* pSchema	= SchemaCache.Get( Settings.Library.FilterURI );
	DWORD nCookie		= GetFolderCookie();
	
	if ( Settings.Library.ShowVirtual ) pSchema = NULL;
	
	if ( m_nStyle == LVS_REPORT )
	{
		CLibraryTreeItem* pTree = GetFolderSelection();
		
		if ( pTree != NULL && pTree->m_pVirtual != NULL && pTree->m_pSelNext == NULL &&
			 pTree->m_pVirtual->m_pSchema != NULL )
		{
			CString strURI = pTree->m_pVirtual->m_pSchema->GetContainedURI( CSchema::stFile );
			
			if ( strURI.GetLength() && ( m_pSchema == NULL || m_pSchema->m_sURI != strURI ) )
			{
				if ( CSchema* pSchema = SchemaCache.Get( strURI ) )
				{
					CPtrList pColumns;
					CSchemaColumnsDlg::LoadColumns( pSchema, &pColumns );
					SetViewSchema( pSchema, &pColumns, TRUE, FALSE );
				}
			}
		}
	}

	LDVITEM* pItem = m_pList + m_nList - 1;

	for ( DWORD nCount = m_nList ; nCount ; nCount--, pItem-- )
	{
		CLibraryFile* pFile = Library.LookupFile( pItem->nIndex );
		
		if ( pFile && pFile->m_nSelectCookie == nCookie && pFile->IsAvailable() &&
			 ( ! pSchema || pSchema->Equals( pFile->m_pSchema ) ||
			 ( ! pFile->m_pMetadata && pSchema->FilterType( pFile->m_sName ) ) ) )
		{
			pFile->m_nListCookie = nCookie;
		}
		else
		{
			SelRemove( pItem->nIndex );
			CStringArray* pSaved = pItem->pText;
			CopyMemory( pItem, pItem + 1, sizeof(LDVITEM) * ( m_nList - nCount ) );
			pItem[ m_nList - nCount ].pText = pSaved;
			m_nList--;
		}
	}

	for ( POSITION pos = LibraryMaps.GetFileIterator() ; pos ; )
	{
		CLibraryFile* pFile = LibraryMaps.GetNextFile( pos );

		if ( pFile->m_nSelectCookie == nCookie &&
 			 pFile->m_nListCookie != nCookie &&
			 pFile->IsAvailable() &&
			 ( ! pSchema || pSchema->Equals( pFile->m_pSchema ) ||
			 ( ! pFile->m_pMetadata && pSchema->FilterType( pFile->m_sName ) ) ) )
		{
			if ( m_nList == m_nBuffer )	// MUST EQUAL
			{
				m_nBuffer += 64;
				LDVITEM* pList = new LDVITEM[ m_nBuffer ];
				if ( m_nList ) CopyMemory( pList, m_pList, m_nList * sizeof(LDVITEM) );
				if ( m_pList ) delete [] m_pList;
				ZeroMemory( pList + m_nList, ( m_nBuffer - m_nList ) * sizeof(LDVITEM) );
				m_pList = pList;
			}
			
			m_pList[ m_nList ].nIndex		= pFile->m_nIndex;
			m_pList[ m_nList ].nState		&= ~LDVI_SELECTED;
			m_nList++;
			
			pFile->m_nListCookie = nCookie;
		}
	}
	
	m_nListCookie++;
	
	SortItems();
}