Exemple #1
0
LValue *l_func_list_get(LValue *args, LClosure *closure) {
  LValue *list = l_list_get(args, 0);
  LValue *index = l_list_get(args, 1);
  l_assert_is(list, L_LIST_TYPE, L_ERR_MISSING_LIST, closure);
  l_assert_is(index, L_NUM_TYPE, L_ERR_MISSING_INDEX, closure);
  LValue *value = l_list_get(list, mpz_get_si(index->core.num));
  if(value == NULL) value = l_value_new(L_NIL_TYPE, closure);
  return value;
}
Exemple #2
0
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;
}
Exemple #3
0
LValue *l_func_list_add(LValue *args, LClosure *closure) {
  LValue *l1 = l_list_get(args, 0);
  LValue *l2 = l_list_get(args, 1);
  LValue *value = l_value_new(L_LIST_TYPE, closure);
  value->core.list = subvector(l1->core.list, 0, l1->core.list->length);
  int i;
  for(i=0; i<l2->core.list->length; i++) {
    vector_add(value->core.list, l2->core.list->data[i], l2->core.list->sizes[i]);
  }
  return value;
}
Exemple #4
0
LValue *l_func_add(LValue *args, LClosure *closure) {
  LValue *v1 = l_list_get(args, 0);
  LValue *v2 = l_list_get(args, 1);
  if(v1->type == L_LIST_TYPE && v2->type == L_LIST_TYPE) {
    return l_func_list_add(args, closure);
  } else if(v1->type == L_NUM_TYPE && v2->type == L_NUM_TYPE) {
    return l_func_num_add(args, closure);
  } else if(v1->type == L_STR_TYPE && v2->type == L_STR_TYPE) {
    return l_func_str_add(args, closure);
  } else {
    return l_value_new(L_NIL_TYPE, closure);
  }
}
Exemple #5
0
bool l_list_eq(LValue *l1, LValue *l2) {
  if(l1->core.list->length == 0 && l2->core.list->length == 0) {
    return true;
  } else if(l1->core.list->length == l2->core.list->length) {
    int i;
    for(i=0; i<l1->core.list->length; i++) {
      if(!l_eq(l_list_get(l1, i), l_list_get(l2, i))) {
        return false;
      }
    }
    return true;
  }
  return false;
}
Exemple #6
0
LValue *l_func_count(LValue *args, LClosure *closure) {
  LValue *list = l_list_get(args, 0);
  l_assert_is(list, L_LIST_TYPE, L_ERR_MISSING_LIST, closure);
  LValue *value = l_value_new(L_NUM_TYPE, closure);
  mpz_init_set_ui(value->core.num, list->core.list->length);
  return value;
}
Exemple #7
0
// 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;
}
Exemple #8
0
LValue *l_func_rest(LValue *args, LClosure *closure) {
  LValue *list = l_list_get(args, 0);
  l_assert_is(list, L_LIST_TYPE, L_ERR_MISSING_LIST, closure);
  LValue *value = l_value_new(L_LIST_TYPE, closure);
  if(list->core.list->length > 1) {
    value->core.list = subvector(list->core.list, 1, list->core.list->length);
  } else {
    value->core.list = create_vector();
  }
  return value;
}
Exemple #9
0
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;
}
Exemple #10
0
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;
}
Exemple #11
0
LValue *l_func_require(LValue *args, LClosure *closure) {
  if(l_loaded_libs == NULL)
    l_loaded_libs = create_hashmap();
  int i;
  char *p;
  LValue *path;
  closure = l_closure_root(closure);
  for(i=0; i<args->core.list->length; i++) {
    path = l_list_get(args, i);
    l_assert_is(path, L_STR_TYPE, "Path for require must be a string.", closure);
    p = path->core.str->str;
    // TODO search in cwd, then in lib/extra
    if(!hashmap_get(l_loaded_libs, p)) {
      l_eval_path(p, closure);
      hashmap_put(l_loaded_libs, p, p, sizeof(p));
    }
  }
  return args;
}
Exemple #12
0
// 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;
}
Exemple #13
0
char *l_inspect_to_str(LValue *value, char *buf, int bufLen) {
  char *repr;
  switch(value->type) {
    case L_ERR_TYPE:
      snprintf(buf, bufLen-1, "<Err: %s>", value->core.str->str);
      break;
    case L_NUM_TYPE:
      repr = l_str(value);
      snprintf(buf, bufLen-1, "<Num: %s>", repr);
      break;
    case L_STR_TYPE:
      snprintf(buf, bufLen-1, "<Str: %s>", value->core.str->str);
      break;
    case L_LIST_TYPE:
      if(value->core.list->length > 0) {
        repr = l_str(l_list_get(value, 0));
        snprintf(buf, bufLen-1, "<List with %d item(s), first=%s>", (int)value->core.list->length, repr);
      } else {
        snprintf(buf, bufLen-1, "<List with 0 item(s)>");
      }
      break;
    case L_FUNC_TYPE:
      if(value->core.func.ptr != NULL) {
        snprintf(buf, bufLen-1, "<Func Ptr with %d arg(s) and %d expr(s)>", value->core.func.argc, value->core.func.exprc);
      } else {
        snprintf(buf, bufLen-1, "<Func with %d arg(s) and %d expr(s)>", value->core.func.argc, value->core.func.exprc);
      }
      break;
    case L_TRUE_TYPE:
      snprintf(buf, bufLen-1, "<true>");
      break;
    case L_FALSE_TYPE:
      snprintf(buf, bufLen-1, "<false>");
      break;
    case L_NIL_TYPE:
      snprintf(buf, bufLen-1, "<nil>");
      break;
    default:
      snprintf(buf, bufLen-1, "unable to inspect element type %d", value->type);
  }
  return buf;
}