struct ast* rlength(struct ast* a) {
  switch (a->node_type) {
    case N_STRING_1: {
                           return new_integer_node(strlen(string_value(a)));
                           break;
    };
    case N_STRING_2: {
                           return new_integer_node(strlen(string_value(a)));
                           break;
    };
    case N_IDENTIFIER: {
                           return rlength(eval_ast(a));
                           break;
    };
    case N_ARRAY: {
                           return new_integer_node(array_tree_size(a->left));
                           break;
    };
    case N_ARRAY_CONTENT: {
                           return rlength(eval_ast(a->left));
                           break;
    };
     default: {
                          no_method_error("length", a);
		                      break;
		 };
  };
  return new_nil_node();
};
struct ast* eval_instance_native_method(struct ast* m) {
	if (m != NULL){
    char* method_name;

    if (m->node_type == N_METHOD_CALL_1) {
      method_name = strdup(((struct method_call_node*)m)->method_name);
    };

		if (!strcmp(method_name, LENGTH)) {
      struct method_call_node* mc = (struct method_call_node*)m;
      return rlength(eval_ast(mc->left_ast));

    } else if (!strcmp(method_name, EACH_ITERATOR)) {
      struct method_call_node* mc = (struct method_call_node*)m;
      return reach(eval_ast(mc->left_ast), mc->opt_block);

    } else if (!strcmp(method_name, RESPOND_TO)) {
      struct method_call_node* mc = (struct method_call_node*)m;
      struct list_node* arg_node = mc->args;
      if (list_length(arg_node) != 1){
        wrong_arguments_error(list_length(arg_node), 1);
      }
      return rrespond_to(eval_ast(mc->left_ast), strdup(string_value(eval_ast(arg_node->arg))));

    } else if (!strcmp(method_name, NIL_METHOD)) {
      return rnil((struct method_call_node*)m);

    } else if (!strcmp(method_name, OBJECT_ID)) {
      return robject_id((struct method_call_node*)m);
    };
	};
  return new_nil_node();
};
Exemplo n.º 3
0
static int insert(bintree_t *t, struct bintree_node *root, void *value)
{
    int cmp_res = 0;

    if (is_nil(root))
    {
        root->left  = new_nil_node(root);
        root->right = new_nil_node(root);
        root->value = value;

        return 0;
    }

    cmp_res = t->cmp(root->value, value, t->ctx);

    if (cmp_res > 0)
        return insert(t, root->left, value);
    else if (cmp_res < 0)
        return insert(t, root->right, value);
    return -EINVAL;
}
Exemplo n.º 4
0
bintree_t *bintree_new(bintree_cmp_func cmp, void *ctx)
{
    bintree_t *t = (bintree_t*)calloc(1, sizeof(*t));

    if (!t)
        return NULL;

    t->root = new_nil_node(NULL);
    t->cmp  = cmp;
    t->ctx  = ctx;

    return t;
}
struct ast* eval_native_method(struct ast* m){
	if (m != NULL){
    char* method_name;
    if (m->node_type == N_METHOD_CALL_2) {
      method_name = strdup(((struct method_call_node*)m)->method_name);
    } else if (m->node_type == N_IDENTIFIER) {
      method_name = strdup(((struct identifier_node*)m)->name);
    };

		if (!strcmp(method_name, PUTS)) {
			return rputs(m);
    } else if (!strcmp(method_name, GETS)) {
      return rgets();
    };
	};
  return new_nil_node();
};
struct ast* rputs(struct ast* a){

  if (a->node_type == N_METHOD_CALL_0 || a->node_type == N_METHOD_CALL_1 || a->node_type == N_METHOD_CALL_2) {
    struct method_call_node* m = (struct method_call_node*)a;
    struct list_node* arg_node = m->args;

    // caso especial: puts() sin parámetros imprime salto de línea
    if (arg_node == NULL) {
      printf("\n");

    // comportamiento normal
    } else {  
      while(arg_node != NULL){
        struct ast* evaluated = eval_ast(arg_node->arg);
        rputs(evaluated);
        arg_node = arg_node->next;
      };
    };

  } else if (a->node_type == N_ARRAY) {
    int arr_size = array_tree_size(a->left);
    struct ast* result[arr_size];
    struct ast* ptr = a->left;
    int i;
    for (i = 0; i < arr_size; i++) {
      result[i] = ptr;
      ptr = ptr->right;
    };

    ptr = result[arr_size-1];
    for (i = arr_size-1; i >= 0; i--) {
      rputs(eval_ast(result[i]));
    };

  } else if (a->node_type == N_ARRAY_CONTENT) {
    rputs(eval_ast(a->left));

  } else if (a->node_type == N_STRING_1) {
    printf("%s\n", string_value(a));

  } else if (a->node_type == N_STRING_2) {

    char * str = malloc(sizeof( strlen(string_value(a)) ));
    strcpy(str, string_value(a));
    str = build_end_of_lines(str);
    printf("%s\n", str);

  } else if (a->node_type == N_INTEGER) {
    printf("%d\n", int_value(a));

  } else if (a->node_type == N_DOUBLE) {
    double d = double_value(a);
    if ( d - floor(d) == 0.0 ) {
      printf( "%g.0\n", d );
    } else {
      printf( "%g\n", d );
    };

  } else if (a->node_type == N_BOOL) {
    printf("%s\n", bool_value(a) ? "true" : "false");

  } else if (a->node_type == N_NIL) {
    printf("\n");

  } else if (a->node_type == N_OBJECT) {
    struct object_node * object = (struct object_node *) a;
    printf("<#%s:%p>\n", object->class_ptr->name, (void *)object);

  } else {
    printf("Puts doesn't support %s type, sorry :D\n", type_name(a->node_type));
  };
  return new_nil_node();
};