fixed ast parents
[bosc.git] / src / ast.h
blobb1d7b5733e830689282e501ef1e6d2cebb581b07
1 #ifndef AST_H
2 #define AST_H
4 #include <string>
5 #include <sstream>
6 #include <vector>
8 #include "logging.h"
10 // utility stuff
12 static inline std::string numtostr(double num)
14 std::stringstream s;
15 s << num;
16 return s.str();
20 /** base class. also works as a noop node. */
21 class ASTNode
23 protected:
24 void setParent(ASTNode* p) { if (p) p->parent = this; }
25 public:
26 ASTNode *parent;
27 ASTNode() : parent(0) {}
28 ASTNode(ASTNode *p) : parent(p) {}
29 virtual const char *getType() const { return "ASTNode"; }
30 virtual std::string toString() const { return std::string("<BasicAstNode/>"); }
33 class Block : public ASTNode {
34 public:
35 std::vector<ASTNode*> list;
36 Block() {};
37 const char *getType() const { return "Block"; }
38 std::string toString() const
40 std::string arg;
41 for (std::vector<ASTNode*>::const_iterator it = list.begin(); it != list.end(); ++it)
42 arg += (*it)->toString();
43 return "<block>" + arg + "</block>";
47 //////////////////////////////////////////////////////////////////////
48 // leafs
49 class Ident : public ASTNode
51 public:
52 std::string name;
53 Ident(std::string ident)
54 : name(ident) {}
56 const char *getType() const { return "Ident"; }
57 std::string toString() const { return "<ident name=\""+name+"\"/>"; }
61 class Number : public ASTNode
63 public:
64 double val;
65 Number(double n): val(n) {}
66 const char *getType() const { return "Number"; }
67 std::string toString() const { return std::string("<number val=\"")+numtostr(val)+"\"/>"; }
70 //////////////////////////////////////////////////////////////////////
71 // nodes
75 // unary ops
78 class UnaryOperator : public ASTNode {
79 public:
80 std::string oper;
81 ASTNode *operand;
82 UnaryOperator(std::string op, ASTNode *e)
83 : oper(op), operand(e)
84 { setParent(operand); }
85 const char *getType() const { return ("UnaryOperator<" + oper + ">").c_str(); }
86 virtual std::string getName() const { return "unaryOp"; }
87 std::string toString() const
88 { return "<" + getName() + " op=\"" + oper + "\">"
89 + operand->toString()
90 + "</" + getName() + ">"; }
93 class Increment : public UnaryOperator
95 public:
96 Increment(ASTNode *node): UnaryOperator("++", node) {}
97 const char *getType() const { return "Increment"; }
98 std::string getName() const { return "incr"; }
101 class Decrement : public UnaryOperator {
102 public:
103 Decrement(ASTNode *node): UnaryOperator("--", node) {}
104 const char *getType() const { return "Decrement"; }
105 std::string getName() const { return "decr"; }
108 class Negation : public UnaryOperator {
109 public:
110 Negation(ASTNode *e)
111 : UnaryOperator("-", e)
113 const char *getType() const { return "Negation"; }
114 std::string getName() const { return "neg"; }
117 class LogicalNot : public UnaryOperator {
118 public:
119 LogicalNot(ASTNode *e)
120 : UnaryOperator("!", e)
122 const char *getType() const { return "LogicalNot"; }
123 std::string getName() const { return "boolnot"; }
126 class BitwiseNot : public UnaryOperator {
127 public:
128 BitwiseNot(ASTNode *e)
129 : UnaryOperator("~", e)
131 const char *getType() const { return "BinaryNot"; }
132 std::string getName() const { return "bitnot"; }
136 // binary ops
139 class BinaryOperator : public ASTNode {
140 public:
141 ASTNode *left, *right;
142 std::string oper;
143 BinaryOperator(std::string op, ASTNode *l, ASTNode *r)
144 : oper(op), left(l), right(r)
145 { setParent(left); setParent(right); }
146 virtual std::string getName() const { return "binaryOp"; }
147 const char *getType() const { return ("BinaryOperator<"+oper+">").c_str(); }
148 std::string toString() const
149 { return "<" + getName() + " op=\"" + oper + "\"><left>"
150 + left->toString() + "</left><right>"
151 + right->toString() + "</right></" + getName() + ">"; }
154 // math
156 class Add : public BinaryOperator {
157 public:
158 Add(ASTNode *l, ASTNode *r)
159 : BinaryOperator("+", l, r) {}
160 const char *getType() const { return "Add"; }
161 std::string getName() const { return "add"; }
164 class Subtract : public BinaryOperator {
165 public:
166 Subtract(ASTNode *l, ASTNode *r)
167 : BinaryOperator("-", l, r) {}
168 const char *getType() const { return "Subtract"; }
169 std::string getName() const { return "sub"; }
172 class Multiply : public BinaryOperator {
173 public:
174 Multiply(ASTNode *l, ASTNode *r)
175 : BinaryOperator("*", l, r) {}
176 const char *getType() const { return "Multiply"; }
177 std::string getName() const { return "mul"; }
180 class Divide : public BinaryOperator {
181 public:
182 Divide(ASTNode *l, ASTNode *r)
183 : BinaryOperator("/", l, r) {}
184 const char *getType() const { return "Divide"; }
185 std::string getName() const { return "div"; }
188 class Modulo : public BinaryOperator {
189 public:
190 Modulo(ASTNode *l, ASTNode *r)
191 : BinaryOperator("%", l, r) {}
192 const char *getType() const { return "Modulo"; }
193 std::string getName() const { return "mod"; }
197 // assignment
199 class Assign : public BinaryOperator {
200 public:
201 Assign(ASTNode *l, ASTNode *r)
202 : BinaryOperator("=", l, r) {}
203 const char *getType() const { return "Assign"; }
204 std::string getName() const { return "assign"; }
207 // relational
209 class LessThan : public BinaryOperator {
210 public:
211 LessThan(ASTNode *l, ASTNode *r)
212 : BinaryOperator("&lt;", l, r) {}
213 const char *getType() const { return "LessThan"; }
214 std::string getName() const { return "lt"; }
217 class GreaterThan : public BinaryOperator {
218 public:
219 GreaterThan(ASTNode *l, ASTNode *r)
220 : BinaryOperator("&gt;", l, r) {}
221 const char *getType() const { return "GreaterThan"; }
222 std::string getName() const { return "gt"; }
225 class LessEqual : public BinaryOperator {
226 public:
227 LessEqual(ASTNode *l, ASTNode *r)
228 : BinaryOperator("&lt;=", l, r) {}
229 const char *getType() const { return "LessEqual"; }
230 std::string getName() const { return "lteq"; }
233 class GreaterEqual : public BinaryOperator {
234 public:
235 GreaterEqual(ASTNode *l, ASTNode *r)
236 : BinaryOperator("&gt;=", l, r) {}
237 const char *getType() const { return "GreaterEqual"; }
238 std::string getName() const { return "gteq"; }
241 class Equal : public BinaryOperator {
242 public:
243 Equal(ASTNode *l, ASTNode *r)
244 : BinaryOperator("==", l, r) {}
245 const char *getType() const { return "Equal"; }
246 std::string getName() const { return "eq"; }
249 class NotEqual : public BinaryOperator {
250 public:
251 NotEqual(ASTNode *l, ASTNode *r)
252 : BinaryOperator("!=", l, r) {}
253 const char *getType() const { return "NotEqual"; }
254 std::string getName() const { return "neq"; }
257 // bitwise
259 class BitwiseAnd : public BinaryOperator {
260 public:
261 BitwiseAnd(ASTNode *l, ASTNode *r)
262 : BinaryOperator("&amp;", l, r) {}
263 const char *getType() const { return "BitwiseAnd"; }
264 std::string getName() const { return "bitand"; }
267 class BitwiseOr : public BinaryOperator {
268 public:
269 BitwiseOr(ASTNode *l, ASTNode *r)
270 : BinaryOperator("|", l, r) {}
271 const char *getType() const { return "BitwiseOr"; }
272 std::string getName() const { return "bitor"; }
275 class BitwiseXor : public BinaryOperator {
276 public:
277 BitwiseXor(ASTNode *l, ASTNode *r)
278 : BinaryOperator("^", l, r) {}
279 const char *getType() const { return "BitwiseXor"; }
280 std::string getName() const { return "bitxor"; }
283 class ShiftLeft : public BinaryOperator {
284 public:
285 ShiftLeft(ASTNode *l, ASTNode *r)
286 : BinaryOperator("&lt;&lt;", l, r) {}
287 const char *getType() const { return "ShiftLeft"; }
288 std::string getName() const { return "shl"; }
291 class ShiftRight : public BinaryOperator {
292 public:
293 ShiftRight(ASTNode *l, ASTNode *r)
294 : BinaryOperator("&gt;&gt;", l, r) {}
295 const char *getType() const { return "ShiftRight"; }
296 std::string getName() const { return "shr"; }
299 // logical
301 class LogicalAnd : public BinaryOperator {
302 public:
303 LogicalAnd(ASTNode *l, ASTNode *r)
304 : BinaryOperator("&amp;&amp;", l, r) {}
305 const char *getType() const { return "LogicalAnd"; }
306 std::string getName() const { return "booland"; }
309 class LogicalOr : public BinaryOperator {
310 public:
311 LogicalOr(ASTNode *l, ASTNode *r)
312 : BinaryOperator("||", l, r) {}
313 const char *getType() const { return "LogicalOr"; }
314 std::string getName() const { return "boolor"; }
317 // other
319 class Comma : public BinaryOperator {
320 public:
321 Comma(ASTNode *l, ASTNode *r)
322 : BinaryOperator(",", l, r) {}
323 const char *getType() const { return "Comma"; }
324 std::string getName() const { return "comma"; }
327 class Semicolon : public BinaryOperator {
328 public:
329 Semicolon(ASTNode *l, ASTNode *r)
330 : BinaryOperator(";", l, r) {}
331 const char *getType() const { return "Semicolon"; }
332 std::string getName() const { return "semicolon"; }
336 // flow control
339 class IfThenElse : public ASTNode
341 public:
342 ASTNode *cond, *trueexp, *falseexp;
343 IfThenElse(ASTNode *c, ASTNode *t, ASTNode *f = 0)
344 : cond(c), trueexp(t), falseexp(f)
346 setParent(cond);
347 setParent(trueexp);
348 setParent(falseexp);
350 const char *getType() const { return "IfThenElse"; }
351 std::string toString() const
352 { return "<cond>"
353 "<if>" + cond->toString() + "</if>"
354 + "<then>" + trueexp->toString() + "</then>"
355 + ( falseexp ? "<else>" + falseexp->toString() + "</else>" : "")
356 + "</cond>"; }
360 /*** Loop node.
362 * pseudocode:
364 * init
365 * loop:
366 * if not precond:
367 * goto end
368 * before
369 * body
370 * after
371 * if not postcond:
372 * goto end
373 * goto loop
374 * end:
377 class Loop : public ASTNode
379 public:
380 /// loop initialization
381 ASTNode *init;
382 /// loop precondition
383 ASTNode *precond;
384 /// loop postcondition
385 ASTNode *postcond;
386 /// execute before any statements
387 ASTNode *before;
388 /// execute after any statements
389 ASTNode *after;
390 /// loop body
391 ASTNode *body;
393 Loop(ASTNode *b, ASTNode *i = 0, ASTNode *pre = 0, ASTNode *post = 0,
394 ASTNode *bef = 0, ASTNode *aft = 0)
395 : init(i), precond(pre), postcond(post), before(bef), after(aft), body(b)
397 setParent(body);
398 setParent(init);
399 setParent(precond);
400 setParent(postcond);
401 setParent(before);
402 setParent(precond);
403 setParent(after);
406 const char *getType() const { return "Loop"; }
407 std::string toString() const
408 { return "<loop>"
409 + ( init ? "<init>" + init->toString() + "</init>" : "")
410 + ( precond ? "<precond>" + precond->toString() + "</precond>" : "")
411 + ( postcond ? "<postcond>" + postcond->toString() + "</postcond>" : "")
412 + ( before ? "<before>" + before->toString() + "</before>" : "")
413 + ( after ? "<after>" + after->toString() + "</after>" : "")
414 + "<body>" + body->toString() + "</body>"
415 + "</loop>"; }
418 class BlockControl : public ASTNode {
419 public:
420 BlockControl() {}
422 ASTNode* findParent(std::string type)
424 if (!parent) return 0;
425 ASTNode *cur = parent;
426 while (cur && cur->getType() != type)
427 cur = cur->parent;
428 return cur;
431 const char *getType() const { return "BlockControl"; }
432 std::string toString() const { return "<blockcontrol/>"; }
435 class LoopControl : public BlockControl {
436 public:
437 LoopControl() {}
438 ASTNode* findParent() { return BlockControl::findParent("Loop"); }
439 const char *getType() const { return "LoopControl"; }
440 std::string toString() const { return "<loopcontrol/>"; }
443 class Continue : public LoopControl {
444 public:
445 Continue() {}
446 const char *getType() const { return "Continue"; }
447 std::string toString() const { return "<continue/>"; }
450 class Break : public LoopControl {
451 public:
452 Break() {}
453 const char *getType() const { return "Break"; }
454 std::string toString() const { return "<break/>"; }
457 class Return : public BlockControl {
458 public:
459 ASTNode *retval;
460 Return(ASTNode *r) : retval(r) { setParent(r);}
461 ASTNode *findParent() { return BlockControl::findParent("Function"); }
462 const char *getType() const { return "Return"; }
463 std::string toString() const
464 { if (!retval) return "<return/>";
465 else return "<return>" + retval->toString() + "</return>"; }
468 class Label : public ASTNode {
469 public:
470 std::string name;
471 ASTNode *rest;
472 Label(std::string n, ASTNode *r): name(n), rest(r) { setParent(r); }
473 const char *getType() const { return "Label"; }
474 std::string toString() const
475 { return "<label name=\"" + name + "\">" + rest->toString() + "</label>"; }
478 class Jump : public ASTNode {
479 public:
480 std::string dest;
481 Jump(const char *d): dest(d) {}
482 const char *getType() const { return "Jump"; }
483 std::string toString() const { return "<jump dest=\"" + dest + "\"/>"; }
486 class CallExpr : public ASTNode {
487 protected:
488 void extractArgs(Comma *args)
491 public:
492 ASTNode *call, *args;
493 CallExpr(ASTNode *c, ASTNode *a): call(c), args(a)
494 { setParent(c);
495 setParent(a); }
496 const char *getType() const { return "CallExpr"; }
497 std::string toString() const
499 if (args) {
500 return "<callexpr><callee>" + call->toString() + "</callee><args>" + args->toString() + "</args></callexpr>";
501 } else {
502 return "<callexpr><callee>" + call->toString() + "</callee></callexpr>";
507 class Call : public ASTNode {
508 protected:
509 void extractArgs(Comma *args)
512 public:
513 std::vector<ASTNode *> argv;
514 std::string name;
515 Call(std::string n): name(n) {}
516 Call(std::string n, ASTNode *arg): name(n) { setParent(arg); argv.push_back(arg); }
517 const char *getType() const { return "Call"; }
518 std::string toString() const
520 if (argv.size() > 0) {
521 std::string args;
522 for (std::vector<ASTNode*>::const_iterator it = argv.begin(); it != argv.end(); ++it)
523 args += "<arg>" + (*it)->toString() + "</arg>";
524 return "<call name=\"" + name + "\">" + args + "</call>";
525 } else {
526 return "<call name=\"" + name + "\"/>";
531 class StartScript : public Call {
532 public:
533 StartScript(std::string n): Call(n) {}
534 StartScript(std::string n, ASTNode *arg): Call(n, arg) {}
536 const char *getType() const { return "StartScript"; }
537 std::string toString() const
539 if (argv.size() > 0) {
540 std::string args;
541 for (std::vector<ASTNode*>::const_iterator it = argv.begin(); it != argv.end(); ++it)
542 args += "<arg>" + (*it)->toString() + "</arg>";
543 return "<startscript name=\"" + name + "\">" + args + "</startscript>";
544 } else {
545 return "<startscript name=\"" + name + "\"/>";
552 class FunctionProto : public ASTNode {
553 public:
554 std::string name;
555 ASTNode *params;
556 FunctionProto(std::string n, ASTNode *p): name(n), params(p)
557 { setParent(p); }
558 const char *getType() const { return "FunctionProto"; }
559 std::string toString() const
561 if (params) return "<functionproto name=\"" + name + "\">"
562 + params->toString() + "</functionproto>";
563 else return "<functionproto name=\"" + name + "\"/>";
569 // TA ops
572 class GetOp : public ASTNode {
573 public:
574 ASTNode *val;
575 ASTNode *args[4];
576 GetOp(ASTNode *v, ASTNode *a=0, ASTNode *b=0, ASTNode* c=0, ASTNode*d = 0)
577 : val(v)
578 { args[0] = a; args[1] = b; args[2] = c; args[3] = d;
579 setParent(a); setParent(b); setParent(c); setParent(d); setParent(v); }
580 const char *getType() const { return "Get"; }
581 std::string toString() const
582 { return "<get><val>" + val->toString() + "</val>"
583 + (args[0] ? "<a1>" + args[0]->toString() + "</a1>" : "")
584 + (args[1] ? "<a2>" + args[1]->toString() + "</a2>" : "")
585 + (args[2] ? "<a3>" + args[2]->toString() + "</a3>" : "")
586 + (args[3] ? "<a4>" + args[3]->toString() + "</a4>" : "")
587 + "</get>"; }
590 class SetOp : public ASTNode {
591 public:
592 ASTNode *key, *val;
593 SetOp(ASTNode *k, ASTNode *v) : key(k), val(v)
594 { setParent(k); setParent(v); }
595 const char *getType() const { return "Get"; }
596 std::string toString() const
597 { return "<set><key>" + key->toString() + "</key>"
598 "<value>" + val->toString() + "</value></set>"; }
602 class Axis : public ASTNode {
603 public:
604 int axis;
605 Axis(int a): axis(a) {}
606 const char *getType() const { return "Axis"; }
607 std::string toString() const { char tmp[] = "x-axis"; tmp[0] += axis; return std::string("<axis name=\"") + std::string(tmp) + std::string("\"/>"); }
610 class TAOperation : public ASTNode {
611 public:
612 std::string name;
613 ASTNode *args[5];
614 TAOperation(std::string n, ASTNode *arg1, ASTNode *arg2 = 0,
615 ASTNode *arg3 = 0, ASTNode *arg4 = 0, ASTNode *arg5 = 0)
616 : name(n)
617 { args[0] = arg1; args[1] = arg2; args[2] = arg3; args[3] = arg4; args[4] = arg5;
618 setParent(arg1); setParent(arg2); setParent(arg3); setParent(arg4); setParent(arg5); }
619 const char *getType() const { return "TAOperation"; }
620 std::string toString() const
621 { return "<operation name=\"" + name + "\">"
622 "<a1>" + args[0]->toString() + "</a1>"
623 + (args[1] ? "<a2>" + args[1]->toString() + "</a2>" : "")
624 + (args[2] ? "<a3>" + args[2]->toString() + "</a3>" : "")
625 + (args[3] ? "<a4>" + args[3]->toString() + "</a4>" : "")
626 + (args[4] ? "<a5>" + args[4]->toString() + "</a5>" : "")
627 + "</operation>"; }
631 class Typename : public ASTNode {
632 public:
633 std::string name;
634 Typename(std::string n): name(n) {}
635 const char *getType() const { return "Typename"; }
636 std::string toString() const
637 { return "<typename name=\"" + name + "\"/>"; }
640 class Declaration : public ASTNode {
641 public:
642 ASTNode *type;
643 ASTNode *list;
644 Declaration(ASTNode *t, ASTNode *l): type(t), list(l)
645 { setParent(t); setParent(l); }
646 const char *getType() const { return "Declaration"; }
647 std::string toString() const
648 { return "<declaration><type>" + type->toString() + "</type>"
649 "<list>" + list->toString() + "</list>"
650 "</declaration>"; }
654 class Pragma : public ASTNode {
655 public:
656 std::string name;
657 std::string value;
658 double number;
659 Pragma(std::string n, double d): name(n), number(d) {}
660 Pragma(std::string n, std::string v): name(n), value(v), number(0) {}
661 const char *getType() const { return "Pragma"; }
662 std::string toString() const { return "<pragma name=\"" + name + "\" value=\"" + value + "\" num=\"" + numtostr(number) + "\"/>"; }
667 class Function : public ASTNode {
668 public:
669 ASTNode *proto;
670 ASTNode *instr;
671 Function(ASTNode *fp, ASTNode *b): proto(fp), instr(b)
672 { setParent(fp); setParent(b); }
673 const char *getType() const { return "Function"; }
674 std::string toString() const
675 { return "<function>" + proto->toString() + instr->toString() + "</function>"; }
678 #endif