Last active
August 3, 2016 16:08
-
-
Save stevedonovan/71b1e2443602edee308aab07e233854b to your computer and use it in GitHub Desktop.
Revisions
-
stevedonovan revised this gist
Aug 3, 2016 . 1 changed file with 14 additions and 24 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -1,10 +1,9 @@ #include <stdio.h> #include <string.h> #include <ctype.h> #include "lily_api_embed.h" #include "lily_api_alloc.h" #include "lily_api_value.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 }; /** 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_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_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_state *vm) { lily_file_val *filev = lily_arg_file(vm,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_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_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_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_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_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_error(vm, SYM_CLASS_INDEXERROR, "too many format items"); } idx++; // skip '}' lily_value *v = lily_list_value(lv,i); -
stevedonovan revised this gist
Jul 29, 2016 . 1 changed file with 151 additions and 40 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -1,11 +1,11 @@ #include <string.h> #include <ctype.h> #include "lily_vm.h" #include "lily_api_vm.h" #include "lily_api_alloc.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 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,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_val_n(2); lily_list_set_string(lv,0,string_result); lily_list_set_integer(lv,1,index); lily_return_tuple(vm,lv); } /** 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,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; } /** 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,0); read_check(vm,filev); FILE *f = filev->inner_file; lily_return_string(vm, fill_string_from_file(f,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) { 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) { 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); } } /** 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); } /** 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) { 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" -
stevedonovan revised this gist
Jul 14, 2016 . 1 changed file with 13 additions and 30 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal 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"); } #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) { 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_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 = 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) { char *str = lily_arg_string_raw(vm,1); int res = 0; while (*str) { ++res; str += move_table[(uint8_t)*str]; } 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_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_return_string(vm, lily_new_raw_string_sized(buffer,pos)); lily_free_msgbuf(msgbuf); } -
stevedonovan created this gist
Jul 13, 2016 .There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal 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" ) This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal 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" };