Exemplo n.º 1
0
Arquivo: eval.c Projeto: hmarr/skeema
sk_Object *sk_eval(sk_VM *vm, sk_Object *exp)
{
    debug_obj("eval: %s", exp);

    if (sk_object_is(exp, sk_SymbolType)) {
        // direct eval() on symbol means we look it up
        debug_obj("symbol lookup: %s", exp);
        sk_Object *var = sk_dict_get(vm->scope, sk_symbol_cstr(exp));
        if (var == NULL) {
            // symbol not in present in scope
            error_obj("undefined identifier: %s", exp);
        }
        return sk_inc_ref(var);
    }

    if (!sk_object_is(exp, sk_CellType)) {
        // only symbols and cells (lists) are special, return values as is
        debug_obj("atom: %s", exp);
        return sk_inc_ref(exp);
    }

    // special form: def
    if (sk_symbol_is(vm, sk_cell_car(exp), "def")) {
        return sk_eval_def(vm, exp);
    }

    // special form: quote
    if (sk_symbol_is(vm, sk_cell_car(exp), "quote")) {
        return sk_inc_ref(sk_cell_car(sk_cell_cdr(exp)));
    }

    // special form: lambda
    if (sk_symbol_is(vm, sk_cell_car(exp), "lambda") ||
        sk_symbol_is(vm, sk_cell_car(exp), "->")) {
        return sk_eval_lambda(vm->scope, exp);
    }

    // we've got a list, which means function invocation
    // start by resolving the function
    sk_Object *result, *proc = sk_eval(vm, sk_cell_car(exp));
    if (proc == NULL) {
        // function doesn't exists, but they already got an error from above
        result = NULL;
    } else if (sk_object_is(proc, sk_ProcType)) {
        result = sk_proc_apply(vm, proc, sk_cell_cdr(exp));
    } else if (sk_object_is(proc, sk_LambdaType)) {
        result = sk_lambda_apply(vm, proc, sk_cell_cdr(exp));
    } else {
        error_obj("expected procedure, got %s", proc);
        result = NULL;
    }
    sk_dec_ref(proc);

    return result;
}
Exemplo n.º 2
0
Arquivo: eval.c Projeto: hmarr/skeema
sk_Object *sk_eval_lambda(sk_Object *scope, sk_Object *exp)
{
    // format: (lambda (arg1 arg2) (expr))
    exp = sk_cell_cdr(exp);  // advance to the name cell
    sk_Object *args = sk_cell_car(exp);
    if (!sk_object_is(args, sk_CellType)) {
        error("invalid syntax: lambda expects args, not %s", args->type->name);
        return NULL;
    }

    exp = sk_cell_cdr(exp);  // advance to the value cell
    if (sk_cell_cdr(exp) != sk_nil) {
        error_obj("lambda received unexpected value %s", sk_cell_cdr(exp));
        return NULL;
    }

    sk_Object *func_body = sk_cell_car(exp);
    if (!sk_object_is(func_body, sk_CellType)) {
        error("invalid syntax: lambda expects expression, not %s",
              args->type->name);
        return NULL;
    }

    return sk_lambda_new(scope, args, func_body);
}
Exemplo n.º 3
0
sk_Object *sk_builtins_sum(sk_VM *vm, sk_Object *scope, sk_Object *args)
{
    bool return_float = false;
    double float_sum = 0.0;
    long int_sum = 0;

    while (args != sk_nil) {
        sk_Object *item = sk_cell_car(args);
        if (sk_object_is(item, sk_IntType)) {
            int_sum += sk_int_val(item);
        } else if (sk_object_is(item, sk_FloatType)) {
            float_sum += sk_float_val(item);
            return_float = true;
        } else {
            error_obj("invalid argument to sum(): %s", item);
            return NULL;
        }
        args = sk_cell_cdr(args);
    }

    if (return_float) {
        return sk_float_new(float_sum + int_sum);
    }
    return sk_int_new(int_sum);
}
Exemplo n.º 4
0
const json &json::operator[]( size_t idx ) const
{
	precondition( is<json_array>(), "not a json array" );
	const json_array &a = get<json_array>();
	if ( idx < a.size() )
		return a[idx];
	return error_obj();
}
Exemplo n.º 5
0
const json &json::at( size_t idx ) const
{
	precondition( is<json_array>(), "not a json array" );
	const auto &a = get<json_array>();
	if ( idx < a.size() )
		return a.at( idx );
	return error_obj();
}
Exemplo n.º 6
0
Arquivo: eval.c Projeto: hmarr/skeema
sk_Object *sk_lambda_apply(sk_VM *vm, sk_Object *lambda, sk_Object *arg_exp)
{
    // cool, we've got a function
    debug_obj("calling lambda: %s", lambda);

    sk_Object *scope = sk_lambda_scope(lambda);

    sk_Object *arg = arg_exp, *arg_name = sk_lambda_args(lambda);

    while (arg != sk_nil && arg_name != sk_nil) {
        debug_obj("arg: %s", arg);
        debug_obj("arg name: %s", arg_name);
        // eval the arg
        sk_Object *evald_arg = sk_eval(vm, sk_cell_car(arg));
        if (evald_arg == NULL) {
            // something went wrong up the call stack when evalling
            error_obj("got NULL while evalling %s", arg_exp);
            sk_dec_ref(lambda);  // TODO: should this be here?? as above.
            return NULL;
        }

        sk_dict_set(scope, sk_string_cstr(sk_cell_car(arg_name)), evald_arg);
        sk_dec_ref(evald_arg);

        // next arg, repeat the evalling!
        arg = sk_cell_cdr(arg);
        arg_name = sk_cell_cdr(arg_name);
    }

    if (arg != sk_nil) {
        error_obj("too many args provided to %s", lambda);
        return NULL;
    }

    if (arg_name != sk_nil) {
        error_obj("too few args provided to %s", lambda);
        return NULL;
    }

    // we've got our list of evalled args, let's invoke the proc!
    //debug_obj("calling with args: %s", args);
    sk_Object *result = sk_eval(vm, sk_lambda_expr(lambda));

    return result;
}
Exemplo n.º 7
0
const json &json::operator[]( const std::string &name ) const
{
	precondition( is<json_object>(), "not a json object" );
	const json_object &o = get<json_object>();
	auto x = o.find( name );
	if ( x == o.end() )
		return error_obj();
	return x->second;
}
Exemplo n.º 8
0
Arquivo: eval.c Projeto: hmarr/skeema
sk_Object *sk_proc_apply(sk_VM *vm, sk_Object *proc, sk_Object *arg_exp)
{
    // cool, we've got a function
    debug_obj("calling proc: %s", proc);

    // now we need to eval the args, one by one
    sk_Object *args = sk_nil;
    // loop through the list of unevaluated args
    while (arg_exp != sk_nil && sk_object_is(arg_exp, sk_CellType)) {
        // eval the arg
        sk_Object *evald_arg = sk_eval(vm, sk_cell_car(arg_exp));
        if (evald_arg == NULL) {
            // something went wrong up the call stack when evalling
            error_obj("got NULL while evalling %s", arg_exp);
            sk_dec_ref(proc);  // TODO: why is this here?
            return NULL;
        }

        if (args == sk_nil) {
            // start of the arg list, create the first element
            args = sk_cell_new(evald_arg, sk_nil);
        } else {
            // arg list already exists, append to the back
            sk_cell_append(args, evald_arg);
        }
        // evald arg is part of arg list now, doesn't need us any more
        sk_dec_ref(evald_arg);

        // next arg, repeat the evalling!
        arg_exp = sk_cell_cdr(arg_exp);
    }

    // we've got our list of evalled args, let's invoke the proc!
    debug_obj("calling with args: %s", args);
    sk_Object *result = sk_proc_fn(proc)(vm, vm->scope, args);
    // now that's out the way we're done with our args
    sk_dec_ref(args);
    return result;
}