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(); };
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; }
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(); };