summaryrefslogtreecommitdiff
path: root/opfuncs.c
diff options
context:
space:
mode:
authortomsmeding <tom.smeding@gmail.com>2016-08-05 20:26:05 +0200
committertomsmeding <tom.smeding@gmail.com>2016-08-06 10:10:32 +0200
commitf67988fbfde6ad8a91466ef5d4227dcf9e5db6ce (patch)
treedb85d3936f717331c3eeed4fae43e5ed43324be9 /opfuncs.c
parente6bb770a52980ef3d85c2d4b93fb240c026ce7f7 (diff)
Working preliminary version of parser
Diffstat (limited to 'opfuncs.c')
-rw-r--r--opfuncs.c127
1 files changed, 127 insertions, 0 deletions
diff --git a/opfuncs.c b/opfuncs.c
new file mode 100644
index 0000000..a5607ae
--- /dev/null
+++ b/opfuncs.c
@@ -0,0 +1,127 @@
+#include <stddef.h>
+
+#include "opfuncs.h"
+#include "parser.h"
+
+int precedence(const char *op){
+ switch(op[0]){
+ case '!': return op[1]=='='&&!op[2]? 5:!op[1]?12:-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]?13:-1;
+ case '*': return op[1]=='*'&&op[2]=='='&&!op[3]? 1:op[1]=='='&&!op[2]? 1:op[1]=='*'&&!op[2]?14:!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;
+ case '~': return !op[1]?12:-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:len==1?12:-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]==')'?13:-1;
+ case '*': return len==3&&op[1]=='*'&&op[2]=='='? 1:len==2&&op[1]=='='? 1:len==2&&op[1]=='*'?14: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;
+ case '~': return len==1?12:-1;
+ default: return -1;
+ }
+}
+
+int associativity(const char *op){
+ switch(op[0]){
+ case '!': return op[1]=='='&&!op[2]?AS_NONASSOC:!op[1]?AS_PREFIX :-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_SUFFIX :-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;
+ case '~': return !op[1]?AS_PREFIX :-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:len==1?AS_PREFIX :-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_SUFFIX :-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;
+ case '~': return len==1?AS_PREFIX :-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:-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;
+ case '~': return 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]=='='?"!=":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==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;
+ case '~': return len==1?"~":NULL;
+ default: return NULL;
+ }
+}