bool obj_match_lists(Process *process, Obj *env, Obj *attempt, Obj *value) { //printf("Matching list %s with %s\n", obj_to_string(attempt)->s, obj_to_string(value)->s); Obj *p1 = attempt; Obj *p2 = value; while(p1 && p1->car) { if(obj_eq(process, p1->car, dotdotdot) && p1->cdr && p1->cdr->car) { //printf("Matching & %s against %s\n", obj_to_string(p1->cdr->car)->s, obj_to_string(p2)->s); bool matched_rest = obj_match(process, env, p1->cdr->car, p2); return matched_rest; } else if(!p2 || !p2->car) { return false; } bool result = obj_match(process, env, p1->car, p2->car); if(!result) { return false; } p1 = p1->cdr; p2 = p2->cdr; } if(p2 && p2->car) { return false; } else { //printf("Found end of list, it's a match.\n"); return true; } }
int DoIt( char *in_file, int vg_class, int vg_type, int obj_type, int *match ) { int iret; int readpos; long in_size; char tmp_name[PATH_MAX]; VG_DBStruct el; readpos = 0; *match = 0; cfl_inqr(in_file, NULL, &in_size, tmp_name, &iret); while (!*match && !iret && (readpos < in_size)) { cvg_rdrec(in_file, readpos, &el, &iret); if (!iret) { readpos += el.hdr.recsz; *match = obj_match(&el, vg_class, vg_type, obj_type); } } return iret; }
void match(Process *process, Obj *env, Obj *value, Obj *attempts) { Obj *p = attempts; while(p && p->car) { //printf("\nWill match %s with value %s\n", obj_to_string(p->car)->s, obj_to_string(value)->s); Obj *new_env = obj_new_environment(env); shadow_stack_push(process, new_env); bool result = obj_match(process, new_env, p->car, value); if(result) { //printf("Match found, evaling %s in env\n", obj_to_string(p->cdr->car)->s); //, obj_to_string(new_env)->s); eval_internal(process, new_env, p->cdr->car); // eval the following form using the new environment Obj *pop = shadow_stack_pop(process); // new_env if(eval_error) { return; } assert(pop == new_env); return; } if(!p->cdr) { set_error("Uneven nr of forms in match.", attempts); } p = p->cdr->cdr; Obj *e = shadow_stack_pop(process); // new_env assert(e == new_env); } set_error("Failed to find a suitable match for: ", value); }
bool obj_match_arrays(Process *process, Obj *env, Obj *attempt, Obj *value) { //printf("Matching arrays %s with %s\n", obj_to_string(attempt)->s, obj_to_string(value)->s); int i; for(i = 0; i < attempt->count; i++) { Obj *o = attempt->array[i]; if(obj_eq(process, o, dotdotdot) && ((i + 1) < attempt->count)) { int rest_count = value->count - i; //printf("rest_count: %d\n", rest_count); Obj *rest = obj_new_array(rest_count); for(int j = 0; j < rest_count; j++) { rest->array[j] = value->array[i + j]; // copy the rest of the objects to a smaller array } //printf("rest: %s\n", obj_to_string(rest)->s); Obj *symbol_after_dotdotdot = attempt->array[i + 1]; //printf("symbol_after_dotdotdot: %s\n", obj_to_string(symbol_after_dotdotdot)->s); bool matched_rest = obj_match(process, env, symbol_after_dotdotdot, rest); //printf("%s\n", matched_rest ? "match" : "no match"); return matched_rest; } else if(i >= value->count) { return false; } bool result = obj_match(process, env, o, value->array[i]); if(!result) { return false; } } if(i < value->count) { //printf("The value list is too long.\n"); return false; } else { //printf("Found end of list, it's a match.\n"); return true; } }