summaryrefslogtreecommitdiff
path: root/sheep/alien.c
blob: 4b47a829ad6121f85b3b3da1dbb31fcc4c234a54 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
/*
 * sheep/alien.c
 *
 * Copyright (c) 2009 Johannes Weiner <hannes@cmpxchg.org>
 */
#include <sheep/object.h>
#include <sheep/util.h>
#include <sheep/vm.h>
#include <stdio.h>

#include <sheep/alien.h>

static void alien_free(struct sheep_vm *vm, sheep_t sheep)
{
	sheep_free(sheep_data(sheep));
}

static enum sheep_call alien_call(struct sheep_vm *vm, sheep_t callable,
				unsigned int nr_args, sheep_t *valuep)
{
	struct sheep_alien *alien;
	sheep_t value;

	alien = sheep_data(callable);
	value = alien->function(vm, nr_args);
	if (!value)
		return SHEEP_CALL_FAIL;
	*valuep = value;
	return SHEEP_CALL_DONE;
}

static void alien_format(sheep_t sheep, struct sheep_strbuf *sb, int repr)
{
	struct sheep_alien *alien;

	alien = sheep_data(sheep);
	if (repr)
		sheep_strbuf_addf(sb, "#<alien '%s'>", alien->name);
	else
		sheep_strbuf_add(sb, alien->name);
}

const struct sheep_type sheep_alien_type = {
	.name = "alien",
	.free = alien_free,
	.call = alien_call,
	.format = alien_format,
};

sheep_t sheep_make_alien(struct sheep_vm *vm, sheep_alien_t function,
			const char *name)
{
	struct sheep_alien *alien;

	alien = sheep_malloc(sizeof(struct sheep_alien));
	alien->function = function;
	alien->name = name;
	return sheep_make_object(vm, &sheep_alien_type, alien);
}