aboutsummaryrefslogtreecommitdiffstats
path: root/builtins.c
blob: cda7a9309e2cf3c1d54f0c749cdc1b411b4f21f5 (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
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
#include "builtins.h"
#include "stack.h"

extern char *str_func;

int ifunc_set(interpreter *it);
int ifunc_label(interpreter *it);
int ifunc_end(interpreter *it);
int ifunc_if(interpreter *it);
int ifunc_do(interpreter *it);
int ifunc_while(interpreter *it);
int ifunc_ret(interpreter *it);

void iload_core(interpreter *interp)
{
	inew_cfunc(interp, "set", ifunc_set);
	inew_cfunc(interp, "func", ifunc_label);
	inew_cfunc(interp, "end", ifunc_end);
	inew_cfunc(interp, "if", ifunc_if);
	inew_cfunc(interp, "do", ifunc_do);
	inew_cfunc(interp, "while", ifunc_while);
	inew_cfunc(interp, "ret", ifunc_ret);
}

int ifunc_set(interpreter *it)
{
	variable *n = igetarg(it, 0);
	variable *v = igetarg(it, 1);

	if (n == 0)
		return -1;

	n->valtype = v->valtype;
	n->value = v->value;
	n->svalue = v->svalue;
	return 0;
}

int ifunc_label(interpreter *it)
{
	variable *n = igetarg(it, 0);
	
	if (n == 0)
		return -1;

	n->valtype = FUNC;
	n->value = it->lnidx;
	n->svalue = str_func;
	it->indent++;
	return 0;
}

int ifunc_if(interpreter *it)
{
	int v = igetarg_integer(it, 0);
	if (v == 0) {
		it->indent++;
	} else {
		void *tmp = ipop(it);
		ipush(it, (void *)-1);
		ipush(it, tmp);
	}
	return 0;
}

int ifunc_end(interpreter *it)
{
	uint32_t lnidx = (uint32_t)ipop(it) + 1;
	if (lnidx != 0)
		it->lnidx = lnidx;
	return 0;
}

int ifunc_do(interpreter *it)
{
	ipush(it, (void *)it->lnidx);
	return 0;
}

int ifunc_while(interpreter *it)
{
	int c = igetarg_integer(it, 0);
	ipop(it);
	int nidx = (int)ipop(it);
	if (c != 0) {
		ipush(it, (void *)nidx);
		it->lnidx = nidx;
	}
	ipush(it, 0);
	return 0;
}

int ifunc_ret(interpreter *it)
{
	variable *v = igetarg(it, 0);
	switch (v->valtype) {
	case INTEGER:
		inew_integer(it, "RET", INT(v));
		break;
	case FLOAT:
		inew_float(it, "RET", FLOAT(v));
		break;
	case STRING:
		inew_string(it, "RET", v->svalue);
		break;
	default:
		return -1;
		break;
	}
	if (it->ret != 0) {
		it->ret->valtype = v->valtype;
		it->ret->value = v->value;
		it->ret->svalue = v->svalue;
		it->ret = 0;
	}
	return 0;
}