started the parser
[antikythera] / src / mparser.cc
1 #include <vector>
2 #include "mparser.h"
3 #include "machine.h"
4
5 enum ASTNodeType {
6         AST_MACHINE,
7         AST_GEAR,
8         AST_STATEMENT,
9         AST_IDENT,
10         AST_NUMBER,
11         AST_VECTOR,
12         AST_FCALL
13 };
14
15 struct ASTNode {
16         std::vector<ASTNode*> children;
17 };
18
19 struct ParserState {
20         FILE *fp;
21         const char *fname;
22         Machine *mcn;
23
24         int nextc;
25         int savedc;
26
27         bool error;
28 };
29
30 static bool machine(ParserState *ps);
31 static bool expect(ParserState *ps, char c);
32 static bool expect_alpha(ParserState *ps);
33 static bool expect_digit(ParserState *ps);
34 static bool expect_alnum(ParserState *ps);
35 static bool match_str(ParserState *ps, const char *str);
36 static bool match_char(ParserState *ps, char c);
37 static bool mstatement(ParserState *ps);
38 static bool ident(ParserState *ps, std::string *s);
39 static bool gear(ParserState *ps);
40 static bool expression(ParserState *ps);
41
42 static bool nextchar(ParserState *ps);
43 static void putback(ParserState *ps, char c);
44
45 bool parse_machine(Machine *mcn, const char *fname)
46 {
47         FILE *fp = fopen(fname, "rb");
48         if(!fp) return false;
49
50         ParserState pstate;
51         pstate.fname = fname;
52         pstate.fp = fp;
53         pstate.mcn = mcn;
54         pstate.savedc = -1;
55         pstate.nextc = fgetc(fp);       // prime the parser
56         pstate.error = false;
57
58         bool res = machine(&pstate);
59         fclose(fp);
60         return res;
61 }
62
63 static bool machine(ParserState *ps)
64 {
65         matchstr(ps, "machine");
66         expect(ps, '{');
67
68         while(mstatement(ps));
69
70         expect(ps, '}');
71         return true;
72 }
73
74 static bool expect(ParserState *ps, int c)
75 {
76         if(c != ps->nextc) {
77                 ps->error = true;
78                 return false;
79         }
80         nextchar(ps);
81         return true;
82 }
83
84 static bool expect_alpha(ParserState *ps)
85 {
86         if(!isalpha(ps->nextc)) {
87                 ps->error = true;
88                 return false;
89         }
90         nextchar(ps);
91         return true;
92 }
93
94 static bool expect_digit(ParserState *ps)
95 {
96         if(!isdigit(ps->nextc)) {
97                 ps->error = true;
98                 return false;
99         }
100         nextchar(ps);
101         return true;
102 }
103
104 static bool expect_alnum(ParserState *ps)
105 {
106         if(!isalnum(ps->nextc)) {
107                 ps->error = true;
108                 return false;
109         }
110         nextchar(ps);
111         return true;
112 }
113
114 static bool match_str(ParserState *ps, const char *str)
115 {
116         while(*str && match_char(ps, *str++));
117         return !feof(ps->fp);
118 }
119
120 static bool match_char(ParserState *ps, int c)
121 {
122         if(ps->nextc != c) {
123                 return false;
124         }
125         nextchar(ps);
126         return true;
127 }
128
129 static bool expression(ParserState *ps);
130
131 #define CHECK(x) if(!(x)) return false
132
133 static bool mstatement(ParserState *ps)
134 {
135         std::string id;
136
137         CHECK(ident(ps, &id));
138         if(id == "gear") {
139                 gear(ps);
140         } else {
141                 expect(ps, '=');
142                 expression(ps);
143         }
144 }
145
146 static bool expression(ParserState *ps)
147 {
148 }
149
150 static bool ident(ParserState *ps, std::string *s)
151 {
152         CHECK(expect_alpha(ps));
153         while(isalnum(ps->nextc) || ps->nextc == '_') {
154                 s->append((char)ps->nextc);
155                 CHECK(nextchar(ps));
156         }
157         return true;
158 }
159
160 static bool skip_line(FILE *fp)
161 {
162         int c;
163         while((c = fgetc(fp)) != -1 && c != '\n');
164         return c != -1;
165 }
166
167 static bool nextchar(ParserState *ps)
168 {
169         if(ps->savedc != -1) {
170                 ps->nextc = ps->savedc;
171                 ps->savedc = -1;
172                 return true;
173         }
174
175         while((ps->nextc = fgetc(ps->fp)) != -1) {
176                 if(ps->nextc == '#') {
177                         CHECK(skip_line(ps->fp));
178                 }
179                 if(!isspace(ps->nextc)) {
180                         break;
181                 }
182         }
183
184         return ps->nextc != -1;
185 }
186
187 static void putback(ParserState *ps, char c)
188 {
189         ps->savedc = ps->nextc;
190         ps->nextc = c;
191 }