summaryrefslogtreecommitdiff
path: root/eval.c
blob: da49137877b32665e6a6b45d692df0ee1871055d (plain) (blame)
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
#include <u.h>
#include <libc.h>
#include <bio.h>

#include "apl9.h"

Rune *errormsg;

typedef Datum (*evalfn)(Datum, Datum);

Datum strand(Datum, Datum);
Datum monadfun(Datum, Datum);

int bindingstrengths[12][12] = {
/*	A  F  H  MO DO AF (  )  {  }  [  ] */
	2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* A */
	1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* F */
	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* H */
	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* MO */
	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* DO */
	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* FA */
	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* ( */
	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* ) */
	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* { */
	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* } */
	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* [ */
	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* ] */
};

evalfn evalfns[12][12] = {
/*	A  F  H  MO DO AF (  )  {  }  [  ] */
	strand, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* A */
	monadfun, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* F */
	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* H */
	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* MO */
	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* DO */
	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* FA */
	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* ( */
	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* ) */
	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* { */
	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* } */
	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* [ */
	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* ] */
};


Datum *
eval(Datum *tokens, int *ntoks)
{
	while(*ntoks > 1){
		int maxlevel = 0;
		int offset;
		evalfn fn = nil;
		print("CURRENT: %S\n", ppdatums(tokens, *ntoks));
		for(offset = (*ntoks)-1; offset >= 0; offset--){
			int level;
			if(offset == 0)
				level = 0;
			else{
				Datum left = tokens[offset-1];
				Datum right = tokens[offset];
				level = bindingstrengths[left.tag][right.tag];
			}
			if(level < maxlevel){
				Datum left = tokens[offset];
				Datum right = tokens[offset+1];
				fn = evalfns[left.tag][right.tag];
				print("Reducing %S and %S\n", ppdatum(left), ppdatum(right));
				break;
			}else if(level > maxlevel)
				maxlevel = level;
		}
		if(maxlevel == 0){
			errormsg = L"No reduce rule. Syntax error.";
			*ntoks = 0;
		}else{
			tokens[offset] = fn(tokens[offset],tokens[offset+1]);
			for(int i = offset+1; i < (*ntoks)-1; i++)
				tokens[i] = tokens[i+1];
			(*ntoks)--;
		}
	}
	return tokens;
}

Datum
strand(Datum left, Datum right)
{
	print("Stranding\n");
	Datum result;
	result.tag = ArrayTag;
	result.array = fnCatenateFirst(left.array,fnEnclose(right.array));
	return result;
}

Datum
monadfun(Datum left, Datum right)
{
	print("Monadic function application\n");
	Datum result;
	result.tag = ArrayTag;
	/* TODO handle undefined functions here */
	result.array = monadfunctiondefs[left.code](right.array);
	return result;
}