LValue *l_eval_string_node(LNode *node, LClosure *closure) { LValue *value = l_value_new(L_STR_TYPE, closure); if(strchr(node->val, '\\')) { value->core.str = make_stringbuf(""); int i, len = strlen(node->val); char c[] = " "; for(i=0; i<len; i++) { if(node->val[i] == '\\' && i < len-1) { i++; switch(node->val[i]) { case 'a' : c[0] = '\a'; break; case 'b' : c[0] = '\b'; break; case 'f' : c[0] = '\f'; break; case 'n' : c[0] = '\n'; break; case 'r' : c[0] = '\r'; break; case 't' : c[0] = '\t'; break; case 'v' : c[0] = '\v'; break; case '\'': c[0] = '\''; break; case '"' : c[0] = '"' ; break; case '\\': c[0] = '\\'; break; case '?' : c[0] = '?' ; break; } } else { c[0] = node->val[i]; } concat_stringbuf(value->core.str, c); } } else { value->core.str = make_stringbuf(node->val); } return value; }
int main (int argc, char **argv) { // parse args struct arguments arguments; arguments.argc = 0; argp_parse (&argp, argc, argv, 0, 0, &arguments); char *filename = arguments.args[0]; LClosure *closure = l_closure_new(NULL); l_closure_set_funcs(closure); LValue* f = l_value_new(L_STR_TYPE, closure); f->core.str = make_stringbuf((char*)filename); l_closure_set(closure, "-script", f, true); LValue *arg; LValue *args = l_value_new(L_LIST_TYPE, closure); args->core.list = create_vector(); int i; for(i=1; i<arguments.argc; i++) { arg = l_value_new(L_STR_TYPE, closure); arg->core.str = make_stringbuf(arguments.args[i]); vector_add(args->core.list, arg, sizeof(arg)); } l_closure_set(closure, "-args", args, true); l_eval_path(filename, closure); exit(0); }
void l_eval_path(const char *filename, LClosure *closure) { FILE *fp = fopen(filename, "r"); if(fp == NULL) { printf("An error occurred while opening the file %s.\n", filename); exit(1); } LValue* f = l_value_new(L_STR_TYPE, closure); f->core.str = make_stringbuf((char*)filename); l_closure_set(closure, "-filename", f, true); stringbuf *source = make_stringbuf(""); source->str = saferead(fp); l_eval(source->str, filename, closure); }
LValue *l_func_str_add(LValue *args, LClosure *closure) { LValue *v1 = l_list_get(args, 0); LValue *v2 = l_list_get(args, 1); LValue *value = l_value_new(L_STR_TYPE, closure); value->core.str = make_stringbuf(""); concat_stringbuf(value->core.str, v1->core.str->str); concat_stringbuf(value->core.str, v2->core.str->str); return value; }
LValue *l_func_str(LValue *args, LClosure *closure) { LValue *value = l_value_new(L_STR_TYPE, closure); value->core.str = make_stringbuf(""); char *s; int i; for(i=0; i<args->core.list->length; i++) { s = l_str(l_list_get(args, i)); concat_stringbuf(value->core.str, s); } return value; }
LValue *l_eval_var_node(LNode *node, LClosure *closure) { LValue *value = l_closure_get(closure, node->val); if(value != NULL) { return value; } else { value = l_value_new(L_ERR_TYPE, closure); value->core.str = make_stringbuf(node->val); buffer_concat(value->core.str, " not found"); l_handle_error(value, node, closure); return value; } }
LValue *l_func_type(LValue *args, LClosure *closure) { LValue *value = l_list_get(args, 0); char *types[9] = { "nil", "boolean", "boolean", "error", "number", "string", "variable", "list", "function" }; LValue *repr = l_value_new(L_STR_TYPE, closure); repr->core.str = make_stringbuf(types[value->type]); return repr; }
// FIXME this does not work as expected/desired for a multi-character delimiter // since it uses strtok under the hood LValue *l_func_str_split(LValue *args, LClosure *closure) { LValue *string = l_list_get(args, 0); LValue *delim = l_list_get(args, 1); l_assert_is(string, L_STR_TYPE, L_ERR_MISSING_STR, closure); l_assert_is(delim, L_STR_TYPE, L_ERR_MISSING_STR, closure); int i, size; char **strings = str_split(string->core.str->str, delim->core.str->str, &size); LValue *value = l_value_new(L_LIST_TYPE, closure); value->core.list = create_vector(); LValue *s; for(i=0; i<size; i++) { s = l_value_new(L_STR_TYPE, closure); s->core.str = make_stringbuf(strings[i]); vector_add(value->core.list, s, sizeof(s)); } return value; }
// returns a c string representation for the given LValue // (be sure to free the string when you're done) char *l_str(LValue *value) { char *str; stringbuf *str2; switch(value->type) { case L_NUM_TYPE: str = mpz_get_str(NULL, 10, value->core.num); break; case L_STR_TYPE: str = GC_MALLOC(sizeof(char) * (value->core.str->length + 1)); strcpy(str, value->core.str->str); break; case L_LIST_TYPE: str2 = make_stringbuf("["); char *s; int i, len = value->core.list->length; for(i=0; i<len; i++) { s = l_str(l_list_get(value, i)); concat_stringbuf(str2, s); if(i<len-1) buffer_concat(str2, " "); } buffer_concat(str2, "]"); str = GC_MALLOC(sizeof(char) * (str2->length + 1)); strcpy(str, str2->str); destroy_buffer(str2); break; case L_TRUE_TYPE: str = GC_MALLOC(sizeof(char) * 5); strcpy(str, "true"); break; case L_FALSE_TYPE: str = GC_MALLOC(sizeof(char) * 6); strcpy(str, "false"); break; case L_NIL_TYPE: str = GC_MALLOC(sizeof(char) * 4); strcpy(str, "nil"); break; default: str = GC_MALLOC(sizeof(char) * 1); strcpy(str, ""); } return str; }
LValue *l_eval_error_node(LNode *node, LClosure *closure) { LValue *value = l_value_new(L_ERR_TYPE, closure); value->core.str = make_stringbuf(node->val); return value; }