示例#1
0
文件: eval.c 项目: grouzen/fflisp
struct lispobj *eval_let(struct lispobj *exps, struct lispobj *env)
{
    struct lispobj *binds, *body, *vars, *vals, *lambda, *ret, *evals;

    binds = CAR(exps);
    body = CDR(exps);

    if(length(binds) > 0) {
        struct lispobj *tvars, *tvals;
        
        vars = heap_grab(NEW_CONS(NULL, NULL));
        vals = heap_grab(NEW_CONS(NULL, NULL));
        tvars = vars; tvals = vals;
        
        while(binds != NULL) {
            struct lispobj *bind = CAR(binds);

            if(length(bind) != 2) {
                ret = NEW_ERROR("Bad binding in the let exp.\n");
                goto exit;
            }
            
            CAR(tvars) = heap_grab(CAR(bind));
            CAR(tvals) = heap_grab(CADR(bind));
            CDR(tvars) = heap_grab(NEW_CONS(NULL, NULL));
            CDR(tvals) = heap_grab(NEW_CONS(NULL, NULL));
            
            tvars = CDR(tvars);
            tvals = CDR(tvals);
            binds = CDR(binds);
        }

        tvars = NULL;
        tvals = NULL;
    } else {
        return NEW_ERROR("Empty bindgings in the let exp.\n");
    }

    lambda = heap_grab(env_proc_make(vars, body, env));
    
    evals = heap_grab(env_val_list(vals, env));
    if(evals != NULL && OBJ_TYPE(evals) == ERROR) {
        ret = evals;
    } else {
        ret = apply(lambda, evals);
        heap_release(evals);
    }

    heap_release(lambda);
    
    exit:
    heap_release(vals);
    heap_release(vars);

    return ret;
}
示例#2
0
struct lispobj *env_var_define(struct lispobj *var, struct lispobj *val, struct lispobj *env)
{
    struct lispobj *frame, *pair, *cell, *lookup;

    /* Checking on variable existence. */
    lookup = env_var_lookup(var, env);
    /* If variable exists return error. */
    if(OBJ_TYPE(lookup) != ERROR) {
        char error[64];
        
        snprintf(error, 64, "Variable already exists: %s.\n", SYMBOL_VALUE(var));
        return NEW_ERROR(error);
    }
    /* Remove not necessary object. */
    heap_release(lookup);

    /* Get top frame from environment. */
    frame = ENV_FIRST(env);

    /* Creating cell for new variable. */
    cell = NEW_CONS(var, val);
    /* Appending new cell into the frame. */
    pair = NEW_CONS(cell, frame);
    frame = heap_grab(pair);

    /* Appending the frame into the environment. */
    CAR(env) = frame;
    
    return val;
}
示例#3
0
文件: eval.c 项目: grouzen/fflisp
static struct lispobj* eval_cond(struct lispobj *exps, struct lispobj *env)
{
    struct lispobj *ret = OBJ_FALSE;
    
    if(exps != NULL) {
        struct lispobj *cond;
    
        cond = CAR(exps);
        if(cond != NULL && OBJ_TYPE(cond) == CONS) {
            struct lispobj *pred;

            pred = eval(CAR(cond), env);
            if(pred != NULL && OBJ_TYPE(pred) == ERROR) {
                ret = pred;
            } else {
                if(pred) {
                    if(length(cond) == 1) {
                        ret = OBJ_TRUE;
                    } else {
                        ret = eval(CADR(cond), env);
                    }
                } else {
                    ret = eval_cond(CDR(exps), env);
                }
                heap_release(pred);
            }
        } else {
            ret = NEW_ERROR("Bad cond clause.\n");
        }
    }

    return ret;
}
示例#4
0
文件: eval.c 项目: grouzen/fflisp
struct lispobj *apply(struct lispobj *proc, struct lispobj *args)
{    
    if(proc != NULL && OBJ_TYPE(proc) == CONS) {
        struct lispobj *ret;
        
        if(NEW_SYMBOL("SUBR") == CAR(proc)) {
            /* Apply primitive function. */
            struct lispobj *body, *(*subr)(struct lispobj *);

            body = CADR(proc);
            subr = (struct lispobj *) NUMBER_VALUE(body);
            //subr = (struct lispobj *) body;

            ret = heap_grab(subr(args));
        } else if(NEW_SYMBOL("PROC") == CAR(proc)) {
            /* Apply user defined procedure. */
            struct lispobj *body, *params, *penv;

            body = CADDR(proc);
            params = CADR(proc);
            penv = CADDDR(proc);
            
            if(length(params) == length(args)) {
                struct lispobj *env;

                if(params == NULL || params == NEW_SYMBOL("NIL")) {
                    env = penv;

                    ret = eval_progn(body, env);
                } else {
                    env = heap_grab(NEW_CONS(env_frame_make(params, args), penv));

                    ret = eval_progn(body, env);
                    heap_release(env);
                }
            } else {
                char error[64]; 
                snprintf(error,
                         64,
                         "Has recieved wrong number of parameters: %d.\n",
                         length(args));
                ret = heap_grab(NEW_ERROR(error));
            }
        } else {
            goto error;
        }

        return ret;
    }
    
    error:
    return heap_grab(NEW_ERROR("Unknown procedure.\n"));
}
示例#5
0
文件: subr.c 项目: grouzen/fflisp
struct lispobj *subr_equal(struct lispobj *args)
{
    if(length(args) != 2)
        return ERROR_ARGS;

    struct lispobj *obj1, *obj2, *ret;

    obj1 = CAR(args);
    obj2 = CADR(args);

    if(obj1 == NULL && obj2 == NULL) {
        ret = OBJ_TRUE;
    } else if(obj1 != NULL && obj2 != NULL && OBJ_TYPE(obj1) == OBJ_TYPE(obj2)) {
        if(OBJ_TYPE(obj1) == CONS) {
            struct lispobj *args_equal_cars, *args_equal_cdrs;

            args_equal_cars = heap_grab(list(2, CAR(obj1), CAR(obj2)));
            args_equal_cdrs = heap_grab(list(2, CDR(obj1), CDR(obj2)));

            if(subr_equal(args_equal_cars) &&
                    subr_equal(args_equal_cdrs)) {
                ret = OBJ_TRUE;
            } else {
                ret = OBJ_FALSE;
            }

            heap_release(args_equal_cars);
            heap_release(args_equal_cdrs);
        } else {
            struct lispobj *args_eq;

            args_eq = heap_grab(list(2, obj1, obj2));
            ret = subr_eq(args_eq);
            heap_release(args_eq);
        }
    } else
        ret = OBJ_FALSE;

    return ret;
}
示例#6
0
文件: subr.c 项目: grouzen/fflisp
struct lispobj *subr_rplacd(struct lispobj *args)
{
    if(length(args) != 2)
        return ERROR_ARGS;

    struct lispobj *old, *val, *place;
    place = CAR(args);
    val = CADR(args);

    old = CDR(place);
    CDR(place) = heap_grab(val);
    heap_release(old);

    return place;
}
示例#7
0
文件: test.c 项目: Zhouxiaoqing/gbase
int main()
{
    int i;
    int* val;
    int* data;
    int* key;
    struct heap_t* heap;
    
    heap = heap_init(heap_cmp_func);
    assert(heap);

    data = (int*)MALLOC(sizeof(int) * LOOP);
    key = (int*)MALLOC(sizeof(int) * LOOP);
    for(i=0; i<LOOP; i++)
    {
        data[i] = rand() % (LOOP * 2);
        key[i] = heap_insert(heap, &data[i]);
        printf("%d ", data[i]);

        //_heap_debug(heap);
    }
    printf("\n");

    for(i = 0; i < LOOP; i++)
    {
        val = (int*)heap_erase(heap, key[i]);
        printf("%d ", *val);
        //_heap_debug(heap);
    }
/*
    while(heap_count(heap) > 0)
    {
        val = (int*)heap_pop(heap);
        printf("%d ", *val);
        _heap_debug(heap);
    }
    printf("\n");
*/
    FREE(data);
    FREE(key);
    heap_release(heap);

    getchar();
    return 0;
}
示例#8
0
struct lispobj *env_var_assign(struct lispobj *var, struct lispobj *val, struct lispobj *env)
{
    struct lispobj *cell;

    if(var == NULL || OBJ_TYPE(var) != SYMBOL) {
        return NEW_ERROR("Variable name is not a symbol.\n");
    }
    /* Checking on variable existence. */ 
    cell = env_var_lookup(var, env);
    /* If variable not exists return error. */
    if(OBJ_TYPE(cell) == ERROR) {
        return cell;
    }
    /* Remove old value. */
    heap_release(CDR(cell));
    /* Assign new value. */
    CDR(cell) = heap_grab(val);

    return val;
}
示例#9
0
struct lispobj *env_val_list(struct lispobj *vars, struct lispobj *env)
{
    if(vars != NULL) {
        struct lispobj *vals, *car, *cdr;
        
        car = eval(CAR(vars), env);
        if(car != NULL && OBJ_TYPE(car) == ERROR) {
            return car;
        }
        vals = NEW_CONS(NULL, NULL);
        CAR(vals) = car;

        cdr = env_val_list(CDR(vars), env);
        if(cdr != NULL && OBJ_TYPE(cdr) == ERROR) {
            heap_release(vals);
            return cdr;
        }
        CDR(vals) = heap_grab(cdr);

        return vals;
    }

    return NULL;
}
示例#10
0
extern "C" int
main(stage2_args *args)
{
	TRACE(("boot(): enter\n"));

	if (heap_init(args) < B_OK)
		panic("Could not initialize heap!\n");

	TRACE(("boot(): heap initialized...\n"));

	// set debug syslog default
#if KDEBUG_ENABLE_DEBUG_SYSLOG
	gKernelArgs.keep_debug_output_buffer = true;
#endif

	add_stage2_driver_settings(args);

	platform_init_video();

	// the main platform dependent initialisation
	// has already taken place at this point.

	if (vfs_init(args) < B_OK)
		panic("Could not initialize VFS!\n");

	dprintf("Welcome to the Haiku boot loader!\n");

	bool mountedAllVolumes = false;

	Directory *volume = get_boot_file_system(args);

	if (volume == NULL || (platform_boot_options() & BOOT_OPTION_MENU) != 0) {
		if (volume == NULL)
			puts("\tno boot path found, scan for all partitions...\n");

		if (mount_file_systems(args) < B_OK) {
			// That's unfortunate, but we still give the user the possibility
			// to insert a CD-ROM or just rescan the available devices
			puts("Could not locate any supported boot devices!\n");
		}

		// ToDo: check if there is only one bootable volume!

		mountedAllVolumes = true;

		if (user_menu(&volume) < B_OK) {
			// user requested to quit the loader
			goto out;
		}
	}

	if (volume != NULL) {
		// we got a volume to boot from!
		status_t status;
		while ((status = load_kernel(args, volume)) < B_OK) {
			// loading the kernel failed, so let the user choose another
			// volume to boot from until it works
			volume = NULL;

			if (!mountedAllVolumes) {
				// mount all other file systems, if not already happened
				if (mount_file_systems(args) < B_OK)
					panic("Could not locate any supported boot devices!\n");

				mountedAllVolumes = true;
			}

			if (user_menu(&volume) < B_OK || volume == NULL) {
				// user requested to quit the loader
				goto out;
			}
		}

		// if everything is okay, continue booting; the kernel
		// is already loaded at this point and we definitely
		// know our boot volume, too
		if (status == B_OK) {
			register_boot_file_system(volume);

			if ((platform_boot_options() & BOOT_OPTION_DEBUG_OUTPUT) == 0)
				platform_switch_to_logo();

			load_modules(args, volume);
			load_driver_settings(args, volume);

			// apply boot settings
			apply_boot_settings();

			// set up kernel args version info
			gKernelArgs.kernel_args_size = sizeof(kernel_args);
			gKernelArgs.version = CURRENT_KERNEL_ARGS_VERSION;

			// clone the boot_volume KMessage into kernel accessible memory
			// note, that we need to 4 byte align the buffer and thus allocate
			// 3 more bytes
			void* buffer = kernel_args_malloc(gBootVolume.ContentSize() + 3);
			if (!buffer) {
				panic("Could not allocate memory for the boot volume kernel "
					"arguments");
			}

			buffer = (void*)(((addr_t)buffer + 3) & ~(addr_t)0x3);
			memcpy(buffer, gBootVolume.Buffer(), gBootVolume.ContentSize());
			gKernelArgs.boot_volume = buffer;
			gKernelArgs.boot_volume_size = gBootVolume.ContentSize();

			// ToDo: cleanup, heap_release() etc.
			platform_start_kernel();
		}
	}

out:
	heap_release(args);
	return 0;
}
示例#11
0
文件: eval.c 项目: grouzen/fflisp
struct lispobj *eval(struct lispobj *obj, struct lispobj *env)
{
    struct lispobj *ret;
    
    if(obj == NULL || OBJ_TYPE(obj) == NUMBER ||
       OBJ_TYPE(obj) == ERROR || OBJ_TYPE(obj) == STRING) {
        /* Return self-evaluating object. */
        ret = heap_grab(obj);
    } else if(OBJ_TYPE(obj) == SYMBOL) {
        /* Lookup value of the variable in the env. */
        struct lispobj *val;

        val = env_var_lookup(obj, env);
        if(OBJ_TYPE(val) == ERROR) {
            ret = heap_grab(val);
        } else {
            ret = heap_grab(CDR(val));
        }
    } else if(NEW_SYMBOL("QUOTE") == CAR(obj)) {
        /* (quote whatever) */
        if(length(obj) != 2) {
            ret = heap_grab(ERROR_ARGS);
        } else {
            /* Return quoted object. */
            ret = heap_grab(CADR(obj));
        }
#ifdef __DEBUG_GC__
        printf("eval quote debug:");
        heap_debug_object(ret);
        printf("\n");
#endif
    } else if(NEW_SYMBOL("SETQ") == CAR(obj)) {
        /* (setq var val) */
        if(length(obj) != 3) {
            ret = heap_grab(ERROR_ARGS);
        } else {
            /* Try to assign existing variable. */
            struct lispobj *val;
            
            val = eval(CADDR(obj), env);
            if(val != NULL && OBJ_TYPE(val) == ERROR) {
                ret = val;
            } else {
                ret = heap_grab(env_var_assign(CADR(obj), val, env));
                heap_release(val);
            }
        }
    } else if(NEW_SYMBOL("LABEL") == CAR(obj)) {
        /* (label var val) */
        if(length(obj) != 3) {
            ret = heap_grab(ERROR_ARGS);
        } else {
            /* Try to define new variable. */
            struct lispobj *val;

            val = eval(CADDR(obj), env);
            if(val != NULL && OBJ_TYPE(val) == ERROR) {
                ret = val;
            } else {
                ret = heap_grab(env_var_define(CADR(obj), val, env));
                heap_release(val);
            }
        }
    } else if(NEW_SYMBOL("IF") == CAR(obj)) {
        /* (if predicate consequence alternative) */
        if(length(obj) != 4) {
            ret = heap_grab(ERROR_ARGS);
        } else {
            /* Invoke condition function. */
            struct lispobj *pred;

            pred = eval(CADR(obj), env);
            if(pred != NULL && OBJ_TYPE(pred) == ERROR) {
                ret = pred;
            } else {
                if(pred) {
                    /* Eval consequence. */
                    ret = eval(CADDR(obj), env);
                } else {
                    /* Eval alternative. */
                    ret = eval(CADDDR(obj), env);
                }

                heap_release(pred);
            }
        }
    } else if(NEW_SYMBOL("COND") == CAR(obj)) {
        /* (cond (cond1 ret1) (cond2 ret2)) */
        if(length(obj) < 2) {
            ret = heap_grab(ERROR_ARGS);
        } else {
            ret = eval_cond(CDR(obj), env);
        }
    }
    else if(NEW_SYMBOL("LET") == CAR(obj)) {
        if(length(obj) < 3) {
            ret = heap_grab(ERROR_ARGS);
        } else {
            ret = eval_let(CDR(obj), env);
        }
    } else if(NEW_SYMBOL("PROGN") == CAR(obj)) {
        ret = eval_progn(CDR(obj), env);
    } else if(NEW_SYMBOL("LAMBDA") == CAR(obj)) {
        /* (lambda (var) (proc var var)) */
        if(length(obj) < 3) {
            ret = heap_grab(ERROR_ARGS);
        } else {
            /* Make and return new procedure. */
            ret = heap_grab(env_proc_make(CADR(obj), CDDR(obj), env));
        }
    } else {
        /* Apply case. */
        struct lispobj *proc = eval(CAR(obj), env);
        
        if(proc != NULL && OBJ_TYPE(proc) == ERROR) {
            ret = proc;
        } else {
            struct lispobj *args = heap_grab(env_val_list(CDR(obj), env));

            if(args != NULL && OBJ_TYPE(args) == ERROR) {
                ret = args;
            } else {
                ret = apply(proc, args);
                heap_release(args);
            }
            
            heap_release(proc);
        }
    }
    
    return ret;
}