Skip to content

Instantly share code, notes, and snippets.

@stevedonovan
Last active August 3, 2016 16:08
Show Gist options
  • Save stevedonovan/71b1e2443602edee308aab07e233854b to your computer and use it in GitHub Desktop.
Save stevedonovan/71b1e2443602edee308aab07e233854b to your computer and use it in GitHub Desktop.

Revisions

  1. stevedonovan revised this gist Aug 3, 2016. 1 changed file with 14 additions and 24 deletions.
    38 changes: 14 additions & 24 deletions lily_xstr.c
    Original file line number Diff line number Diff line change
    @@ -1,10 +1,9 @@
    #include <stdio.h>
    #include <string.h>
    #include <ctype.h>
    #include "lily_vm.h"
    #include "lily_api_vm.h"
    #include "lily_api_embed.h"
    #include "lily_api_alloc.h"
    #include "lily_api_value.h"
    #include "lily_api_value_flags.h"
    #include "lily_api_msgbuf.h"

    /**
    @@ -36,15 +35,6 @@ static const char move_table[256] =
    /* F */ 4, 4, 4, 4, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
    };

    static void read_check(lily_vm_state *vm, lily_file_val *filev)
    {
    if (filev->inner_file == NULL)
    lily_vm_raise(vm, SYM_CLASS_IOERROR, "IO operation on closed file.\n");

    if (filev->read_ok == 0)
    lily_vm_raise(vm, SYM_CLASS_IOERROR, "File not open for reading.\n");
    }

    /**
    define next(s: String, index: Integer): Tuple[String,Integer]
    @@ -54,7 +44,7 @@ the character at the index, and the index of the next character.
    The returned index is -1 for the last character; thereafter ["",-1]
    is returned.
    */
    void lily_xstr__next(lily_vm_state *vm, uint16_t argc, uint16_t *code)
    void lily_xstr__next(lily_state *vm)
    {
    const char *input = lily_arg_string_raw(vm,0);
    int index = lily_arg_integer(vm,1);
    @@ -83,7 +73,7 @@ define size (s: String): Integer
    Number of _characters_ in a string
    */
    void lily_xstr__size(lily_vm_state *vm, uint16_t argc, uint16_t *code)
    void lily_xstr__size(lily_state *vm)
    {
    char *str = lily_arg_string_raw(vm,0);
    int res = 0;
    @@ -127,28 +117,27 @@ define readall (f: File): String
    Read the whole of a file as a string.
    Does not check whether the resulting string is valid UTF-8.
    */
    void lily_xstr__readall(lily_vm_state *vm, uint16_t argc, uint16_t *code)
    void lily_xstr__readall(lily_state *vm)
    {
    lily_file_val *filev = lily_arg_file(vm,0);
    read_check(vm,filev);
    FILE *f = filev->inner_file;
    lily_return_string(vm, fill_string_from_file(f,0));
    lily_file_ensure_readable(vm,filev);
    lily_return_string(vm, fill_string_from_file(lily_file_get_raw(filev),0));
    }

    /**
    define shell (cmd: String): String
    Read all the output of a shell command using popen
    */
    void lily_xstr__shell(lily_vm_state *vm, uint16_t argc, uint16_t *code)
    void lily_xstr__shell(lily_state *vm)
    {
    const char *cmd = lily_arg_string_raw(vm,0);
    FILE *f = popen(cmd,"r");
    lily_return_string(vm, fill_string_from_file(f,1));
    pclose(f);
    }

    static void concat(lily_vm_state *vm, lily_msgbuf *msgbuf, char ch, lily_list_val *lv)
    static void concat(lily_state *vm, lily_msgbuf *msgbuf, char ch, lily_list_val *lv)
    {
    int i;
    lily_mb_flush(msgbuf);
    @@ -165,7 +154,7 @@ define print (values:1...)
    Print several values
    */
    void lily_xstr__print(lily_vm_state *vm, uint16_t argc, uint16_t *code)
    void lily_xstr__print(lily_state *vm)
    {
    lily_list_val *lv = lily_arg_list(vm,0);

    @@ -181,7 +170,7 @@ define concat(delim: String, values:1...):String
    Concatenate some arbitrary values using the single-character delimiter
    */
    void lily_xstr__concat(lily_vm_state *vm, uint16_t argc, uint16_t *code)
    void lily_xstr__concat(lily_state *vm)
    {
    const char *delim = lily_arg_string_raw(vm,0);
    lily_list_val *lv = lily_arg_list(vm,1);
    @@ -212,10 +201,11 @@ define format(fmt: String, values:1...):String
    A simplified Python-style formatter
    */
    void lily_xstr__format(lily_vm_state *vm, uint16_t argc, uint16_t *code)
    void lily_xstr__format(lily_state *vm)
    {
    const char *fmt = lily_arg_string_raw(vm,0);
    lily_list_val *lv = lily_arg_list(vm,1);

    int lsize = lily_list_num_values(lv);
    lily_msgbuf *msgbuf = lily_vm_msgbuf(vm);
    lily_mb_flush(msgbuf);
    @@ -236,7 +226,7 @@ void lily_xstr__format(lily_vm_state *vm, uint16_t argc, uint16_t *code)
    i = i_def++;
    }
    if (i >= lsize) {
    lily_vm_raise(vm, SYM_CLASS_INDEXERROR, "too many format items");
    lily_error(vm, SYM_CLASS_INDEXERROR, "too many format items");
    }
    idx++; // skip '}'
    lily_value *v = lily_list_value(lv,i);
  2. stevedonovan revised this gist Jul 29, 2016. 1 changed file with 151 additions and 40 deletions.
    191 changes: 151 additions & 40 deletions lily_xstr.c
    Original file line number Diff line number Diff line change
    @@ -1,11 +1,11 @@
    #include <string.h>
    #include "lily_core_types.h"
    #include "lily_symtab.h"
    #include "lily_parser.h"
    #include <ctype.h>
    #include "lily_vm.h"
    #include "lily_api_vm.h"
    #include "lily_api_alloc.h"
    #include "lily_api_value_ops.h"
    #include "lily_api_value.h"
    #include "lily_api_value_flags.h"
    #include "lily_api_msgbuf.h"

    /**
    package xstr
    @@ -45,10 +45,8 @@ static void read_check(lily_vm_state *vm, lily_file_val *filev)
    lily_vm_raise(vm, SYM_CLASS_IOERROR, "File not open for reading.\n");
    }

    #define lily_list_set_integer(lv,index,ival) lily_move_integer((lv)->elems[index],ival)

    /**
    function next(s: String, index: Integer): Tuple[String,Integer]
    define next(s: String, index: Integer): Tuple[String,Integer]
    Grab the following character at index. Returns a tuple containing
    the character at the index, and the index of the next character.
    @@ -58,8 +56,8 @@ is returned.
    */
    void lily_xstr__next(lily_vm_state *vm, uint16_t argc, uint16_t *code)
    {
    const char *input = lily_arg_string_raw(vm,1);
    int index = lily_arg_integer(vm,2);
    const char *input = lily_arg_string_raw(vm,0);
    int index = lily_arg_integer(vm,1);

    // how many chars in this character?
    int to_copy = index > -1 ? move_table[(uint8_t)input[index]] : 0;
    @@ -74,20 +72,20 @@ void lily_xstr__next(lily_vm_state *vm, uint16_t argc, uint16_t *code)
    }

    // pack the character and the next index into a tuple
    lily_list_val *lv = lily_new_list_of_n(2);
    lily_list_val *lv = lily_new_list_val_n(2);
    lily_list_set_string(lv,0,string_result);
    lily_list_set_integer(lv,1,index);
    lily_return_tuple(vm,lv);
    }

    /**
    function size (s: String): Integer
    define size (s: String): Integer
    Number of _characters_ in a string
    */
    void lily_xstr__size(lily_vm_state *vm, uint16_t argc, uint16_t *code)
    {
    char *str = lily_arg_string_raw(vm,1);
    char *str = lily_arg_string_raw(vm,0);
    int res = 0;
    while (*str) {
    ++res;
    @@ -96,47 +94,160 @@ void lily_xstr__size(lily_vm_state *vm, uint16_t argc, uint16_t *code)
    lily_return_integer(vm, res);
    }

    static lily_string_val *fill_string_from_file(FILE *f, int drop_lf)
    {
    size_t bufsize = 64;
    char *buffer = lily_malloc(bufsize);
    int pos = 0, nread;
    int nbuf = bufsize/2;
    while (1) {
    nread = fread(buffer+pos,1,nbuf,f);
    pos += nread;
    if (nread < nbuf) {
    if (drop_lf && nread > 0)
    --pos;
    buffer[pos] = '\0';
    break;
    }
    if (pos >= bufsize) {
    nbuf = bufsize;
    bufsize *= 2;
    buffer = lily_realloc(buffer,bufsize);
    }
    }
    lily_string_val *sv = lily_new_raw_string_sized(buffer,pos);
    lily_free(buffer);
    return sv;
    }


    /**
    function readall (f: File): String
    define readall (f: File): String
    Read the whole of a file as a string.
    Does not check whether the resulting string is valid UTF-8.
    */
    void lily_xstr__readall(lily_vm_state *vm, uint16_t argc, uint16_t *code)
    {
    lily_file_val *filev = lily_arg_file(vm,1);
    lily_file_val *filev = lily_arg_file(vm,0);
    read_check(vm,filev);
    FILE *f = filev->inner_file;
    lily_msgbuf *msgbuf = lily_new_msgbuf();
    lily_return_string(vm, fill_string_from_file(f,0));
    }

    int buffer_size = msgbuf->size/2;
    char *buffer = msgbuf->message;
    int pos = 0;
    while (1) {
    int nread = fread(buffer+pos,1, buffer_size,f);
    pos += nread;
    /**
    define shell (cmd: String): String
    if (nread < buffer_size) {
    buffer[pos] = '\0';
    break;
    }
    Read all the output of a shell command using popen
    */
    void lily_xstr__shell(lily_vm_state *vm, uint16_t argc, uint16_t *code)
    {
    const char *cmd = lily_arg_string_raw(vm,0);
    FILE *f = popen(cmd,"r");
    lily_return_string(vm, fill_string_from_file(f,1));
    pclose(f);
    }

    if (pos >= buffer_size) {
    lily_msgbuf_grow(msgbuf);
    buffer = msgbuf->message;
    buffer_size = msgbuf->size/2;
    }
    static void concat(lily_vm_state *vm, lily_msgbuf *msgbuf, char ch, lily_list_val *lv)
    {
    int i;
    lily_mb_flush(msgbuf);
    for (i = 0; i < lily_list_num_values(lv); i++) {
    lily_value *v = lily_list_value(lv,i);
    if (i > 0)
    lily_mb_add_char(msgbuf,ch);
    lily_vm_add_value_to_msgbuf(vm, msgbuf, v);
    }
    }

    }
    lily_return_string(vm, lily_new_raw_string_sized(buffer,pos));
    lily_free_msgbuf(msgbuf);
    /**
    define print (values:1...)
    Print several values
    */
    void lily_xstr__print(lily_vm_state *vm, uint16_t argc, uint16_t *code)
    {
    lily_list_val *lv = lily_arg_list(vm,0);

    lily_msgbuf *msgbuf = lily_vm_msgbuf(vm);
    concat(vm,msgbuf,'\t',lv);
    lily_mb_add_char(msgbuf,'\n');
    fputs(lily_mb_get(msgbuf),stdout);
    lily_mb_flush(msgbuf);
    }

    const char *lily_dynaload_table[] =
    /**
    define concat(delim: String, values:1...):String
    Concatenate some arbitrary values using the single-character delimiter
    */
    void lily_xstr__concat(lily_vm_state *vm, uint16_t argc, uint16_t *code)
    {
    ""
    ,"F\000next\0(String,Integer):Tuple[String,Integer]"
    ,"F\000size\0(String):Integer"
    ,"F\000readall\0(File):String"
    ,"Z"
    };
    const char *delim = lily_arg_string_raw(vm,0);
    lily_list_val *lv = lily_arg_list(vm,1);

    lily_msgbuf *msgbuf = lily_vm_msgbuf(vm);
    concat(vm,msgbuf,delim[0],lv);
    lily_return_string(vm,lily_new_raw_string(lily_mb_get(msgbuf)));
    lily_mb_flush(msgbuf);
    }

    static int char_index(const char *s, int idx, char ch)
    {
    const char *P = strchr(s+idx,ch);
    if (! P)
    return -1;
    else
    return (int)((uintptr_t)P - (uintptr_t)s);
    }

    // note the assumption ;)
    static int convert_i(char d)
    {
    return (int)d - (int)'0';
    }

    /**
    define format(fmt: String, values:1...):String
    A simplified Python-style formatter
    */
    void lily_xstr__format(lily_vm_state *vm, uint16_t argc, uint16_t *code)
    {
    const char *fmt = lily_arg_string_raw(vm,0);
    lily_list_val *lv = lily_arg_list(vm,1);
    int lsize = lily_list_num_values(lv);
    lily_msgbuf *msgbuf = lily_vm_msgbuf(vm);
    lily_mb_flush(msgbuf);

    int idx = 0, last_idx = 0, i_def = 0;
    while (last_idx != -1) {
    idx = char_index(fmt,last_idx,'{');
    if (idx > -1) {
    if (idx > last_idx)
    lily_mb_add_range(msgbuf,fmt,last_idx, idx); // just before {
    // next value
    int i = i_def;
    idx++; // skip '{'
    if (isdigit(fmt[idx])) {
    i = convert_i(fmt[idx]);
    idx++;
    } else {
    i = i_def++;
    }
    if (i >= lsize) {
    lily_vm_raise(vm, SYM_CLASS_INDEXERROR, "too many format items");
    }
    idx++; // skip '}'
    lily_value *v = lily_list_value(lv,i);
    lily_vm_add_value_to_msgbuf(vm, msgbuf, v);
    } else { // end of format string
    lily_mb_add_range(msgbuf,fmt,last_idx, strlen(fmt));
    }
    last_idx = idx;
    }
    lily_return_string(vm,lily_new_raw_string(lily_mb_get(msgbuf)));
    lily_mb_flush(msgbuf);
    }

    #include "dyna_xstr.h"
  3. stevedonovan revised this gist Jul 14, 2016. 1 changed file with 13 additions and 30 deletions.
    43 changes: 13 additions & 30 deletions lily_xstr.c
    Original file line number Diff line number Diff line change
    @@ -5,6 +5,7 @@
    #include "lily_vm.h"
    #include "lily_api_alloc.h"
    #include "lily_api_value_ops.h"
    #include "lily_api_value.h"

    /**
    package xstr
    @@ -44,18 +45,7 @@ static void read_check(lily_vm_state *vm, lily_file_val *filev)
    lily_vm_raise(vm, SYM_CLASS_IOERROR, "File not open for reading.\n");
    }

    static lily_value *new_integer(int64_t n) {
    lily_value *res = lily_new_empty_value();
    lily_move_integer(res, n);
    return res;
    }

    static lily_list_val *new_list(int size) {
    lily_list_val *lv = lily_new_list_val();
    lv->elems = lily_malloc(sizeof(lily_value *) * size);
    lv->num_values = size;
    return lv;
    }
    #define lily_list_set_integer(lv,index,ival) lily_move_integer((lv)->elems[index],ival)

    /**
    function next(s: String, index: Integer): Tuple[String,Integer]
    @@ -68,19 +58,14 @@ is returned.
    */
    void lily_xstr__next(lily_vm_state *vm, uint16_t argc, uint16_t *code)
    {
    lily_value **vm_regs = vm->vm_regs;
    lily_value *string_arg = vm_regs[code[1]];
    lily_value *index_arg = vm_regs[code[2]];
    lily_value *result_reg = vm_regs[code[0]];

    int index = index_arg->value.integer;
    char *input = string_arg->value.string->string;
    const char *input = lily_arg_string_raw(vm,1);
    int index = lily_arg_integer(vm,2);

    // how many chars in this character?
    int to_copy = index > -1 ? move_table[(uint8_t)input[index]] : 0;

    // make a copy!
    lily_value *string_result = lily_new_string_ncpy(input + index, to_copy);
    lily_string_val *string_result = lily_new_raw_string_sized(input + index, to_copy);

    // and let's move onto the next....
    index += to_copy;
    @@ -89,10 +74,10 @@ void lily_xstr__next(lily_vm_state *vm, uint16_t argc, uint16_t *code)
    }

    // pack the character and the next index into a tuple
    lily_list_val *lv = new_list(2);
    lv->elems[0] = string_result;
    lv->elems[1] = new_integer(index);
    lily_move_tuple_f(MOVE_DEREF_SPECULATIVE, result_reg, lv);
    lily_list_val *lv = lily_new_list_of_n(2);
    lily_list_set_string(lv,0,string_result);
    lily_list_set_integer(lv,1,index);
    lily_return_tuple(vm,lv);
    }

    /**
    @@ -102,14 +87,13 @@ Number of _characters_ in a string
    */
    void lily_xstr__size(lily_vm_state *vm, uint16_t argc, uint16_t *code)
    {
    lily_value **vm_regs = vm->vm_regs;
    char *str = vm_regs[code[1]]->value.string->string;
    char *str = lily_arg_string_raw(vm,1);
    int res = 0;
    while (*str) {
    ++res;
    str += move_table[(uint8_t)*str];
    }
    lily_move_integer(vm_regs[code[0]], res);
    lily_return_integer(vm, res);
    }

    /**
    @@ -120,8 +104,7 @@ Does not check whether the resulting string is valid UTF-8.
    */
    void lily_xstr__readall(lily_vm_state *vm, uint16_t argc, uint16_t *code)
    {
    lily_value **vm_regs = vm->vm_regs;
    lily_file_val *filev = vm_regs[code[1]]->value.file;
    lily_file_val *filev = lily_arg_file(vm,1);
    read_check(vm,filev);
    FILE *f = filev->inner_file;
    lily_msgbuf *msgbuf = lily_new_msgbuf();
    @@ -145,7 +128,7 @@ void lily_xstr__readall(lily_vm_state *vm, uint16_t argc, uint16_t *code)
    }

    }
    lily_move_string(vm_regs[code[0]],lily_new_raw_string_sized(buffer,pos));
    lily_return_string(vm, lily_new_raw_string_sized(buffer,pos));
    lily_free_msgbuf(msgbuf);
    }

  4. stevedonovan created this gist Jul 13, 2016.
    9 changes: 9 additions & 0 deletions CMakeLists.txt
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,9 @@
    include_directories("../src/")

    add_library(xstr SHARED lily_xstr.c)
    set_target_properties(
    xstr
    PROPERTIES
    PREFIX ""
    COMPILE_FLAGS "-fPIC -g"
    )
    159 changes: 159 additions & 0 deletions lily_xstr.c
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,159 @@
    #include <string.h>
    #include "lily_core_types.h"
    #include "lily_symtab.h"
    #include "lily_parser.h"
    #include "lily_vm.h"
    #include "lily_api_alloc.h"
    #include "lily_api_value_ops.h"

    /**
    package xstr
    Provides a few extra operations on strings; an iterator, the size of a string
    in characters, and a means to read a whole file.
    */

    // this is private to be core, so let's define it again ;)
    static const char move_table[256] =
    {
    /* 0 1 2 3 4 5 6 7 8 9 A B C D E F */
    /* 0 */ 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
    /* 1 */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
    /* 2 */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
    /* 3 */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
    /* 4 */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
    /* 5 */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
    /* 6 */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
    /* 7 */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
    /* 8 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    /* 9 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    /* A */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    /* B */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    /* C */ 0, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
    /* D */ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
    /* E */ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
    /* F */ 4, 4, 4, 4, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
    };

    static void read_check(lily_vm_state *vm, lily_file_val *filev)
    {
    if (filev->inner_file == NULL)
    lily_vm_raise(vm, SYM_CLASS_IOERROR, "IO operation on closed file.\n");

    if (filev->read_ok == 0)
    lily_vm_raise(vm, SYM_CLASS_IOERROR, "File not open for reading.\n");
    }

    static lily_value *new_integer(int64_t n) {
    lily_value *res = lily_new_empty_value();
    lily_move_integer(res, n);
    return res;
    }

    static lily_list_val *new_list(int size) {
    lily_list_val *lv = lily_new_list_val();
    lv->elems = lily_malloc(sizeof(lily_value *) * size);
    lv->num_values = size;
    return lv;
    }

    /**
    function next(s: String, index: Integer): Tuple[String,Integer]
    Grab the following character at index. Returns a tuple containing
    the character at the index, and the index of the next character.
    The returned index is -1 for the last character; thereafter ["",-1]
    is returned.
    */
    void lily_xstr__next(lily_vm_state *vm, uint16_t argc, uint16_t *code)
    {
    lily_value **vm_regs = vm->vm_regs;
    lily_value *string_arg = vm_regs[code[1]];
    lily_value *index_arg = vm_regs[code[2]];
    lily_value *result_reg = vm_regs[code[0]];

    int index = index_arg->value.integer;
    char *input = string_arg->value.string->string;

    // how many chars in this character?
    int to_copy = index > -1 ? move_table[(uint8_t)input[index]] : 0;

    // make a copy!
    lily_value *string_result = lily_new_string_ncpy(input + index, to_copy);

    // and let's move onto the next....
    index += to_copy;
    if (index > -1 && input[index] == 0) { // ALWAYS nul-terminated...
    index = -1;
    }

    // pack the character and the next index into a tuple
    lily_list_val *lv = new_list(2);
    lv->elems[0] = string_result;
    lv->elems[1] = new_integer(index);
    lily_move_tuple_f(MOVE_DEREF_SPECULATIVE, result_reg, lv);
    }

    /**
    function size (s: String): Integer
    Number of _characters_ in a string
    */
    void lily_xstr__size(lily_vm_state *vm, uint16_t argc, uint16_t *code)
    {
    lily_value **vm_regs = vm->vm_regs;
    char *str = vm_regs[code[1]]->value.string->string;
    int res = 0;
    while (*str) {
    ++res;
    str += move_table[(uint8_t)*str];
    }
    lily_move_integer(vm_regs[code[0]], res);
    }

    /**
    function readall (f: File): String
    Read the whole of a file as a string.
    Does not check whether the resulting string is valid UTF-8.
    */
    void lily_xstr__readall(lily_vm_state *vm, uint16_t argc, uint16_t *code)
    {
    lily_value **vm_regs = vm->vm_regs;
    lily_file_val *filev = vm_regs[code[1]]->value.file;
    read_check(vm,filev);
    FILE *f = filev->inner_file;
    lily_msgbuf *msgbuf = lily_new_msgbuf();

    int buffer_size = msgbuf->size/2;
    char *buffer = msgbuf->message;
    int pos = 0;
    while (1) {
    int nread = fread(buffer+pos,1, buffer_size,f);
    pos += nread;

    if (nread < buffer_size) {
    buffer[pos] = '\0';
    break;
    }

    if (pos >= buffer_size) {
    lily_msgbuf_grow(msgbuf);
    buffer = msgbuf->message;
    buffer_size = msgbuf->size/2;
    }

    }
    lily_move_string(vm_regs[code[0]],lily_new_raw_string_sized(buffer,pos));
    lily_free_msgbuf(msgbuf);
    }

    const char *lily_dynaload_table[] =
    {
    ""
    ,"F\000next\0(String,Integer):Tuple[String,Integer]"
    ,"F\000size\0(String):Integer"
    ,"F\000readall\0(File):String"
    ,"Z"
    };