summaryrefslogtreecommitdiff
path: root/opfuncs.c
blob: 174b1d64b9dc73e044d3fa8de48b4f92ebed827f (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
119
120
121
#include <stddef.h>

#include "opfuncs.h"
#include "parser.h"

int precedence(const char *op){
	switch(op[0]){
		case '!': return op[1]=='='&&!op[2]? 5:-1;
		case '%': return op[1]=='='&&!op[2]? 1:!op[1]?11:-1;
		case '&': return op[1]=='='&&!op[2]? 1:op[1]=='&'&&!op[2]? 4:!op[1]? 9:-1;
		case '(': return op[1]=='-'&&op[2]==')'&&!op[3]?12:op[1]=='!'&&op[2]==')'&&!op[3]?12:op[1]=='~'&&op[2]==')'&&!op[3]?12:-1;
		case '*': return op[1]=='*'&&op[2]=='='&&!op[3]? 1:op[1]=='='&&!op[2]? 1:op[1]=='*'&&!op[2]?13:!op[1]?11:-1;
		case '+': return op[1]=='='&&!op[2]? 1:!op[1]?10:-1;
		case '-': return op[1]=='='&&!op[2]? 1:!op[1]?10:-1;
		case '/': return op[1]=='/'&&op[2]=='='&&!op[3]? 1:op[1]=='='&&!op[2]? 1:op[1]=='/'&&!op[2]?11:!op[1]?11:-1;
		case '<': return op[1]=='='&&!op[2]? 6:!op[1]? 6:-1;
		case '=': return op[1]=='='&&!op[2]? 5:!op[1]? 1:-1;
		case '>': return op[1]=='='&&!op[2]? 6:!op[1]? 6:-1;
		case '^': return op[1]=='='&&!op[2]? 1:op[1]=='^'&&!op[2]? 3:!op[1]? 8:-1;
		case '|': return op[1]=='='&&!op[2]? 1:op[1]=='|'&&!op[2]? 2:!op[1]? 7:-1;
		default: return -1;
	}
}

int precedence_len(const char *op,const int len){
	if(len<=0)return -1;
	switch(op[0]){
		case '!': return len==2&&op[1]=='='? 5:-1;
		case '%': return len==2&&op[1]=='='? 1:len==1?11:-1;
		case '&': return len==2&&op[1]=='='? 1:len==2&&op[1]=='&'? 4:len==1? 9:-1;
		case '(': return len==3&&op[1]=='-'&&op[2]==')'?12:len==3&&op[1]=='!'&&op[2]==')'?12:len==3&&op[1]=='~'&&op[2]==')'?12:-1;
		case '*': return len==3&&op[1]=='*'&&op[2]=='='? 1:len==2&&op[1]=='='? 1:len==2&&op[1]=='*'?13:len==1?11:-1;
		case '+': return len==2&&op[1]=='='? 1:len==1?10:-1;
		case '-': return len==2&&op[1]=='='? 1:len==1?10:-1;
		case '/': return len==3&&op[1]=='/'&&op[2]=='='? 1:len==2&&op[1]=='='? 1:len==2&&op[1]=='/'?11:len==1?11:-1;
		case '<': return len==2&&op[1]=='='? 6:len==1? 6:-1;
		case '=': return len==2&&op[1]=='='? 5:len==1? 1:-1;
		case '>': return len==2&&op[1]=='='? 6:len==1? 6:-1;
		case '^': return len==2&&op[1]=='='? 1:len==2&&op[1]=='^'? 3:len==1? 8:-1;
		case '|': return len==2&&op[1]=='='? 1:len==2&&op[1]=='|'? 2:len==1? 7:-1;
		default: return -1;
	}
}

int associativity(const char *op){
	switch(op[0]){
		case '!': return op[1]=='='&&!op[2]?AS_NONASSOC:-1;
		case '%': return op[1]=='='&&!op[2]?AS_RIGHT   :!op[1]?AS_LEFT    :-1;
		case '&': return op[1]=='='&&!op[2]?AS_RIGHT   :op[1]=='&'&&!op[2]?AS_LEFT    :!op[1]?AS_LEFT    :-1;
		case '(': return op[1]=='-'&&op[2]==')'&&!op[3]?AS_PREFIX  :op[1]=='!'&&op[2]==')'&&!op[3]?AS_PREFIX  :op[1]=='~'&&op[2]==')'&&!op[3]?AS_PREFIX  :-1;
		case '*': return op[1]=='*'&&op[2]=='='&&!op[3]?AS_RIGHT   :op[1]=='='&&!op[2]?AS_RIGHT   :op[1]=='*'&&!op[2]?AS_RIGHT   :!op[1]?AS_LEFT    :-1;
		case '+': return op[1]=='='&&!op[2]?AS_RIGHT   :!op[1]?AS_LEFT    :-1;
		case '-': return op[1]=='='&&!op[2]?AS_RIGHT   :!op[1]?AS_LEFT    :-1;
		case '/': return op[1]=='/'&&op[2]=='='&&!op[3]?AS_RIGHT   :op[1]=='='&&!op[2]?AS_RIGHT   :op[1]=='/'&&!op[2]?AS_LEFT    :!op[1]?AS_LEFT    :-1;
		case '<': return op[1]=='='&&!op[2]?AS_NONASSOC:!op[1]?AS_NONASSOC:-1;
		case '=': return op[1]=='='&&!op[2]?AS_NONASSOC:!op[1]?AS_RIGHT   :-1;
		case '>': return op[1]=='='&&!op[2]?AS_NONASSOC:!op[1]?AS_NONASSOC:-1;
		case '^': return op[1]=='='&&!op[2]?AS_RIGHT   :op[1]=='^'&&!op[2]?AS_LEFT    :!op[1]?AS_LEFT    :-1;
		case '|': return op[1]=='='&&!op[2]?AS_RIGHT   :op[1]=='|'&&!op[2]?AS_LEFT    :!op[1]?AS_LEFT    :-1;
		default: return -1;
	}
}

int associativity_len(const char *op,const int len){
	if(len<=0)return -1;
	switch(op[0]){
		case '!': return len==2&&op[1]=='='?AS_NONASSOC:-1;
		case '%': return len==2&&op[1]=='='?AS_RIGHT   :len==1?AS_LEFT    :-1;
		case '&': return len==2&&op[1]=='='?AS_RIGHT   :len==2&&op[1]=='&'?AS_LEFT    :len==1?AS_LEFT    :-1;
		case '(': return len==3&&op[1]=='-'&&op[2]==')'?AS_PREFIX  :len==3&&op[1]=='!'&&op[2]==')'?AS_PREFIX  :len==3&&op[1]=='~'&&op[2]==')'?AS_PREFIX  :-1;
		case '*': return len==3&&op[1]=='*'&&op[2]=='='?AS_RIGHT   :len==2&&op[1]=='='?AS_RIGHT   :len==2&&op[1]=='*'?AS_RIGHT   :len==1?AS_LEFT    :-1;
		case '+': return len==2&&op[1]=='='?AS_RIGHT   :len==1?AS_LEFT    :-1;
		case '-': return len==2&&op[1]=='='?AS_RIGHT   :len==1?AS_LEFT    :-1;
		case '/': return len==3&&op[1]=='/'&&op[2]=='='?AS_RIGHT   :len==2&&op[1]=='='?AS_RIGHT   :len==2&&op[1]=='/'?AS_LEFT    :len==1?AS_LEFT    :-1;
		case '<': return len==2&&op[1]=='='?AS_NONASSOC:len==1?AS_NONASSOC:-1;
		case '=': return len==2&&op[1]=='='?AS_NONASSOC:len==1?AS_RIGHT   :-1;
		case '>': return len==2&&op[1]=='='?AS_NONASSOC:len==1?AS_NONASSOC:-1;
		case '^': return len==2&&op[1]=='='?AS_RIGHT   :len==2&&op[1]=='^'?AS_LEFT    :len==1?AS_LEFT    :-1;
		case '|': return len==2&&op[1]=='='?AS_RIGHT   :len==2&&op[1]=='|'?AS_LEFT    :len==1?AS_LEFT    :-1;
		default: return -1;
	}
}

int parseoplength(const char *op){
	switch(op[0]){
		case '!': return op[1]=='='?2:-1;
		case '%': return op[1]=='='?2:1;
		case '&': return op[1]=='='?2:op[1]=='&'?2:1;
		case '(': return op[1]=='-'&&op[2]==')'?3:op[1]=='!'&&op[2]==')'?3:op[1]=='~'&&op[2]==')'?3:-1;
		case '*': return op[1]=='*'&&op[2]=='='?3:op[1]=='='?2:op[1]=='*'?2:1;
		case '+': return op[1]=='='?2:1;
		case '-': return op[1]=='='?2:1;
		case '/': return op[1]=='/'&&op[2]=='='?3:op[1]=='='?2:op[1]=='/'?2:1;
		case '<': return op[1]=='='?2:1;
		case '=': return op[1]=='='?2:1;
		case '>': return op[1]=='='?2:1;
		case '^': return op[1]=='='?2:op[1]=='^'?2:1;
		case '|': return op[1]=='='?2:op[1]=='|'?2:1;
		default: return -1;
	}
}

const char* opconststring_len(const char *op,const int len){
	if(len<=0)return NULL;
	switch(op[0]){
		case '!': return len==2&&op[1]=='='?"!=":NULL;
		case '%': return len==2&&op[1]=='='?"%=":len==1?"%":NULL;
		case '&': return len==2&&op[1]=='='?"&=":len==2&&op[1]=='&'?"&&":len==1?"&":NULL;
		case '(': return len==3&&op[1]=='-'&&op[2]==')'?"(-)":len==3&&op[1]=='!'&&op[2]==')'?"(!)":len==3&&op[1]=='~'&&op[2]==')'?"(~)":NULL;
		case '*': return len==3&&op[1]=='*'&&op[2]=='='?"**=":len==2&&op[1]=='='?"*=":len==2&&op[1]=='*'?"**":len==1?"*":NULL;
		case '+': return len==2&&op[1]=='='?"+=":len==1?"+":NULL;
		case '-': return len==2&&op[1]=='='?"-=":len==1?"-":NULL;
		case '/': return len==3&&op[1]=='/'&&op[2]=='='?"//=":len==2&&op[1]=='='?"/=":len==2&&op[1]=='/'?"//":len==1?"/":NULL;
		case '<': return len==2&&op[1]=='='?"<=":len==1?"<":NULL;
		case '=': return len==2&&op[1]=='='?"==":len==1?"=":NULL;
		case '>': return len==2&&op[1]=='='?">=":len==1?">":NULL;
		case '^': return len==2&&op[1]=='='?"^=":len==2&&op[1]=='^'?"^^":len==1?"^":NULL;
		case '|': return len==2&&op[1]=='='?"|=":len==2&&op[1]=='|'?"||":len==1?"|":NULL;
		default: return NULL;
	}
}