On Feb 12, 4:45 pm, werkt <[email protected]> wrote:
> Please redirect me if this isn't the place for this.
>
> The existing ruby interface only generates Strings in a ruby context,
> and errors if anything more interesting (like a dictionary) is passed
> through eval_to_string.  I've rewritten the vim_evaluate method to be
> a lot smarter about the types it generates, and provide the same level
> of support as the python interface (I've left out the caching map as
> well as depth protection, let me know if its not good enough without
> them).
>
> diff -Nru vim72/src/eval.c vim72.if_ruby_types/src/eval.c
> --- vim72/src/eval.c
> +++ vim72.if_ruby_types/src/eval.c
> @@ -5835,7 +5835,7 @@
>      return item1 == NULL && item2 == NULL;
>  }
>
> -#if defined(FEAT_PYTHON) || defined(PROTO)
> +#if defined(FEAT_RUBY) || defined(FEAT_PYTHON) || defined(PROTO)
>  /*
>   * Return the dictitem that an entry in a hashtable points to.
>   */
> diff -Nru vim72/src/if_ruby.c vim72.if_ruby_types/src/if_ruby.c
> --- vim72/src/if_ruby.c 2007-09-10
> +++ vim72.if_ruby_types/src/if_ruby.c
> @@ -518,20 +518,86 @@
>      return Qnil;
>  }
>
> +#ifdef FEAT_EVAL
> +static VALUE vim_to_ruby(typval_T *tv)
> +{
> +    VALUE result = Qnil;
> +
> +    if (tv->v_type == VAR_STRING)
> +    {
> +        result = rb_str_new2(tv->vval.v_string);
> +    }
> +    else if (tv->v_type == VAR_NUMBER)
> +    {
> +        result = INT2NUM(tv->vval.v_number);
> +    }
> +#ifdef FEAT_FLOAT
> +    else if (tv->v_type == VAR_FLOAT)
> +    {
> +        result = rb_float_new(tv->vval.v_float);
> +    }
> +#endif
> +    else if (tv->v_type == VAR_LIST)
> +    {
> +        list_T      *list = tv->vval.v_list;
> +        listitem_T  *curr;
> +
> +        result = rb_ary_new();
> +
> +        if (list != NULL)
> +        {
> +            for (curr = list->lv_first; curr != NULL; curr = curr->li_next)
>
> +            {
> +                rb_ary_push(result, vim_to_ruby(&curr->li_tv));
> +            }
> +        }
> +    }
> +    else if (tv->v_type == VAR_DICT)
> +    {
> +        result = rb_hash_new();
> +
> +        if (tv->vval.v_dict != NULL)
> +        {
> +            hashtab_T   *ht = &tv->vval.v_dict->dv_hashtab;
> +            long_u      todo = ht->ht_used;
> +            hashitem_T  *hi;
> +            dictitem_T  *di;
> +
> +            for (hi = ht->ht_array; todo > 0; ++hi)
> +            {
> +                if (!HASHITEM_EMPTY(hi))
> +                {
> +                    --todo;
> +
> +                    di = dict_lookup(hi);
> +                    rb_hash_aset(result, rb_str_new2((char *)hi->hi_key), 
> vim_to_ruby(&di->di_tv));
>
> +                }
> +            }
> +        }
> +    } /* else return Qnil; */
> +
> +    return result;
> +}
> +#endif
> +
>  static VALUE vim_evaluate(VALUE self, VALUE str)
>  {
>  #ifdef FEAT_EVAL
> -    char_u *value = eval_to_string((char_u *)STR2CSTR(str), NULL,
> TRUE);
> +    typval_T    *tv;
> +    VALUE       result;
>
> -    if (value != NULL)
> -    {
> -       VALUE val = rb_str_new2((char *)value);
> -       vim_free(value);
> -       return val;
> +    tv = eval_expr((char_u *)STR2CSTR(str), NULL);
> +    if (tv == NULL) {
> +        return Qnil;
>      }
> -    else
> +
> +    result = vim_to_ruby(tv);
> +
> +    free_tv(tv);
> +
> +    return result;
>  #endif
> -       return Qnil;
> +    return Qnil;
>  }
>
>  static VALUE buffer_new(buf_T *buf)
>
> Thanks,
> -werkt

I've put a copy of this up at http://www.csh.rit.edu/~werkt/if_ruby_types.diff,
the post above was somewhat wildly formatted, and the diff should
apply cleanly to 7.2.

Thanks,
-werkt

-- 
You received this message from the "vim_dev" maillist.
For more information, visit http://www.vim.org/maillist.php

Raspunde prin e-mail lui