00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #ifndef __TREE_H
00022 #define __TREE_H
00023
00024 #include "compiler.h"
00025 #include "../common/consts.h"
00026 #include "../utils/FormatableString.h"
00027 #include <vector>
00028 #include <string>
00029 #include <ostream>
00030 #include <climits>
00031 #include <cassert>
00032
00033
00034 namespace Aseba
00035 {
00038
00040 std::wstring binaryOperatorToString(AsebaBinaryOperator op);
00041
00043 std::wstring unaryOperatorToString(AsebaUnaryOperator op);
00044
00046 struct Node
00047 {
00049 enum ReturnType
00050 {
00051 TYPE_UNIT = 0,
00052 TYPE_BOOL,
00053 TYPE_INT
00054 };
00055
00057 Node(const SourcePos& sourcePos) : sourcePos(sourcePos) { }
00058 virtual ~Node();
00060 virtual Node* shallowCopy() = 0;
00062 virtual Node* deepCopy();
00063
00065 virtual void checkVectorSize() const;
00067 virtual Node* expandToAsebaTree(std::wostream* dump, unsigned int index = 0);
00069 virtual ReturnType typeCheck() const;
00071 virtual Node* optimize(std::wostream* dump) = 0;
00073 virtual unsigned getStackDepth() const;
00075 virtual void emit(PreLinkBytecode& bytecodes) const = 0;
00076
00078 virtual std::wstring toWString() const = 0;
00080 virtual std::wstring toNodeName() const = 0;
00082 virtual void dump(std::wostream& dest, unsigned& indent) const;
00083
00085 std::wstring typeName(const Node::ReturnType& type) const;
00087 void expectType(const Node::ReturnType& expected, const Node::ReturnType& type) const;
00088
00089 enum MemoryErrorCode
00090 {
00091 E_NOVAL = UINT_MAX
00092 };
00093 virtual unsigned getVectorAddr() const;
00094 virtual unsigned getVectorSize() const;
00095
00097 typedef std::vector<Node *> NodesVector;
00098 NodesVector children;
00099 SourcePos sourcePos;
00100 };
00101
00103 struct BlockNode : Node
00104 {
00106 BlockNode(const SourcePos& sourcePos) : Node(sourcePos) { }
00107 virtual BlockNode* shallowCopy() { return new BlockNode(*this); }
00108
00109 virtual Node* optimize(std::wostream* dump);
00110 virtual void emit(PreLinkBytecode& bytecodes) const;
00111 virtual std::wstring toWString() const { return L"Block"; }
00112 virtual std::wstring toNodeName() const { return L"block"; }
00113 };
00114
00116 struct ProgramNode: BlockNode
00117 {
00119 ProgramNode(const SourcePos& sourcePos) : BlockNode(sourcePos) { }
00120 virtual ProgramNode* shallowCopy() { return new ProgramNode(*this); }
00121
00122 virtual void emit(PreLinkBytecode& bytecodes) const;
00123 virtual std::wstring toWString() const { return L"ProgramBlock"; }
00124 virtual std::wstring toNodeName() const { return L"program block"; }
00125 };
00126
00130 struct AssignmentNode : Node
00131 {
00133 AssignmentNode(const SourcePos& sourcePos) : Node(sourcePos) { }
00134 virtual AssignmentNode* shallowCopy() { return new AssignmentNode(*this); }
00135
00136 virtual void checkVectorSize() const;
00137 virtual Node* expandToAsebaTree(std::wostream* dump, unsigned int index);
00138 virtual ReturnType typeCheck() const;
00139 virtual Node* optimize(std::wostream* dump);
00140 virtual void emit(PreLinkBytecode& bytecodes) const;
00141 virtual std::wstring toWString() const { return L"Assign"; }
00142 virtual std::wstring toNodeName() const { return L"assignment"; }
00143 };
00144
00149 struct IfWhenNode : Node
00150 {
00151 bool edgeSensitive;
00152 unsigned endLine;
00153
00155 IfWhenNode(const SourcePos& sourcePos) : Node(sourcePos) { }
00156 virtual IfWhenNode* shallowCopy() { return new IfWhenNode(*this); }
00157
00158 virtual void checkVectorSize() const;
00159 virtual ReturnType typeCheck() const;
00160 virtual Node* optimize(std::wostream* dump);
00161 virtual void emit(PreLinkBytecode& bytecodes) const;
00162 virtual std::wstring toWString() const;
00163 virtual std::wstring toNodeName() const { return L"if/when"; }
00164 };
00165
00171 struct FoldedIfWhenNode : Node
00172 {
00173 AsebaBinaryOperator op;
00174 bool edgeSensitive;
00175 unsigned endLine;
00176
00178 FoldedIfWhenNode(const SourcePos& sourcePos) : Node(sourcePos) { }
00179 virtual FoldedIfWhenNode* shallowCopy() { return new FoldedIfWhenNode(*this); }
00180
00181 virtual void checkVectorSize() const;
00182 virtual Node* optimize(std::wostream* dump);
00183 virtual unsigned getStackDepth() const;
00184 virtual void emit(PreLinkBytecode& bytecodes) const;
00185 virtual std::wstring toWString() const;
00186 virtual std::wstring toNodeName() const { return L"folded if/when"; }
00187 };
00188
00192 struct WhileNode : Node
00193 {
00195 WhileNode(const SourcePos& sourcePos) : Node(sourcePos) { }
00196 virtual WhileNode* shallowCopy() { return new WhileNode(*this); }
00197
00198 virtual void checkVectorSize() const;
00199 virtual ReturnType typeCheck() const;
00200 virtual Node* optimize(std::wostream* dump);
00201 virtual void emit(PreLinkBytecode& bytecodes) const;
00202 virtual std::wstring toWString() const;
00203 virtual std::wstring toNodeName() const { return L"while"; }
00204 };
00205
00210 struct FoldedWhileNode : Node
00211 {
00212 AsebaBinaryOperator op;
00213
00215 FoldedWhileNode(const SourcePos& sourcePos) : Node(sourcePos) { }
00216 virtual FoldedWhileNode* shallowCopy() { return new FoldedWhileNode(*this); }
00217
00218 virtual void checkVectorSize() const;
00219 virtual Node* optimize(std::wostream* dump);
00220 virtual unsigned getStackDepth() const;
00221 virtual void emit(PreLinkBytecode& bytecodes) const;
00222 virtual std::wstring toWString() const;
00223 virtual std::wstring toNodeName() const { return L"folded while"; }
00224 };
00225
00228 struct EventDeclNode : Node
00229 {
00230 unsigned eventId;
00231
00232 EventDeclNode(const SourcePos& sourcePos, unsigned eventId = 0);
00233 virtual EventDeclNode* shallowCopy() { return new EventDeclNode(*this); }
00234
00235 virtual ReturnType typeCheck() const { return TYPE_UNIT; }
00236 virtual Node* optimize(std::wostream* dump);
00237 virtual void emit(PreLinkBytecode& bytecodes) const;
00238 virtual std::wstring toWString() const;
00239 virtual std::wstring toNodeName() const { return L"event declaration"; }
00240 };
00241
00244 struct EmitNode : Node
00245 {
00246 unsigned eventId;
00247 unsigned arrayAddr;
00248 unsigned arraySize;
00249
00251 EmitNode(const SourcePos& sourcePos) : Node(sourcePos) { }
00252 virtual EmitNode* shallowCopy() { return new EmitNode(*this); }
00253
00254 virtual ReturnType typeCheck() const { return TYPE_UNIT; }
00255 virtual Node* optimize(std::wostream* dump);
00256 virtual void emit(PreLinkBytecode& bytecodes) const;
00257 virtual std::wstring toWString() const;
00258 virtual std::wstring toNodeName() const { return L"emit"; }
00259 };
00260
00263 struct SubDeclNode : Node
00264 {
00265 unsigned subroutineId;
00266
00267 SubDeclNode(const SourcePos& sourcePos, unsigned subroutineId);
00268 virtual SubDeclNode* shallowCopy() { return new SubDeclNode(*this); }
00269
00270 virtual ReturnType typeCheck() const { return TYPE_UNIT; }
00271 virtual Node* optimize(std::wostream* dump);
00272 virtual void emit(PreLinkBytecode& bytecodes) const;
00273 virtual std::wstring toWString() const;
00274 virtual std::wstring toNodeName() const { return L"subroutine declaration"; }
00275 };
00276
00279 struct CallSubNode : Node
00280 {
00281 unsigned subroutineId;
00282
00283 CallSubNode(const SourcePos& sourcePos, unsigned subroutineId);
00284 virtual CallSubNode* shallowCopy() { return new CallSubNode(*this); }
00285
00286 virtual Node* optimize(std::wostream* dump);
00287 virtual void emit(PreLinkBytecode& bytecodes) const;
00288 virtual std::wstring toWString() const;
00289 virtual std::wstring toNodeName() const { return L"subroutine call"; }
00290 };
00291
00295 struct BinaryArithmeticNode : Node
00296 {
00297 AsebaBinaryOperator op;
00298
00299 BinaryArithmeticNode(const SourcePos& sourcePos) : Node(sourcePos) { }
00300 BinaryArithmeticNode(const SourcePos& sourcePos, AsebaBinaryOperator op, Node *left, Node *right);
00301 virtual BinaryArithmeticNode* shallowCopy() { return new BinaryArithmeticNode(*this); }
00302
00303 void deMorganNotRemoval();
00304
00305 virtual Node* expandToAsebaTree(std::wostream* dump, unsigned int index = 0);
00306 virtual ReturnType typeCheck() const;
00307 virtual Node* optimize(std::wostream* dump);
00308 virtual unsigned getStackDepth() const;
00309 virtual void emit(PreLinkBytecode& bytecodes) const;
00310 virtual std::wstring toWString() const;
00311 virtual std::wstring toNodeName() const { return L"binary function"; }
00312
00313 static BinaryArithmeticNode *fromComparison(const SourcePos& sourcePos, Compiler::Token::Type op, Node *left, Node *right);
00314 static BinaryArithmeticNode *fromShiftExpression(const SourcePos& sourcePos, Compiler::Token::Type op, Node *left, Node *right);
00315 static BinaryArithmeticNode *fromAddExpression(const SourcePos& sourcePos, Compiler::Token::Type op, Node *left, Node *right);
00316 static BinaryArithmeticNode *fromMultExpression(const SourcePos& sourcePos, Compiler::Token::Type op, Node *left, Node *right);
00317 static BinaryArithmeticNode *fromBinaryExpression(const SourcePos& sourcePos, Compiler::Token::Type op, Node *left, Node *right);
00318 };
00319
00322 struct UnaryArithmeticNode : Node
00323 {
00324 AsebaUnaryOperator op;
00325
00327 UnaryArithmeticNode(const SourcePos& sourcePos) : Node(sourcePos) { }
00328 UnaryArithmeticNode(const SourcePos& sourcePos, AsebaUnaryOperator op, Node *child);
00329 virtual UnaryArithmeticNode* shallowCopy() { return new UnaryArithmeticNode(*this); }
00330
00331 virtual Node* expandToAsebaTree(std::wostream* dump, unsigned int index = 0);
00332 virtual ReturnType typeCheck() const;
00333 virtual Node* optimize(std::wostream* dump);
00334 virtual void emit(PreLinkBytecode& bytecodes) const;
00335 virtual std::wstring toWString() const;
00336 virtual std::wstring toNodeName() const { return L"unary function"; }
00337 };
00338
00343 struct ImmediateNode : Node
00344 {
00345 int value;
00346
00348 ImmediateNode(const SourcePos& sourcePos, int value) : Node(sourcePos), value(value) { }
00349 virtual ImmediateNode* shallowCopy() { return new ImmediateNode(*this); }
00350
00351 virtual Node* expandToAsebaTree(std::wostream *dump, unsigned int index = 0) { assert(index == 0); return shallowCopy(); }
00352 virtual ReturnType typeCheck() const { return TYPE_INT; }
00353 virtual Node* optimize(std::wostream* dump);
00354 virtual unsigned getStackDepth() const;
00355 virtual void emit(PreLinkBytecode& bytecodes) const;
00356 virtual std::wstring toWString() const;
00357 virtual std::wstring toNodeName() const { return L"constant"; }
00358
00359 virtual unsigned getVectorSize() const { return 1; }
00360 };
00361
00364 struct StoreNode : Node
00365 {
00366 unsigned varAddr;
00367
00369 StoreNode(const SourcePos& sourcePos, unsigned varAddr) : Node(sourcePos), varAddr(varAddr) { }
00370 virtual StoreNode* shallowCopy() { return new StoreNode(*this); }
00371
00372 virtual ReturnType typeCheck() const { return TYPE_UNIT; }
00373 virtual Node* optimize(std::wostream* dump);
00374 virtual void emit(PreLinkBytecode& bytecodes) const;
00375 virtual std::wstring toWString() const;
00376 virtual std::wstring toNodeName() const { return L"variable access (write)"; }
00377
00378 virtual unsigned getVectorAddr() const { return varAddr; }
00379 virtual unsigned getVectorSize() const { return 1; }
00380 };
00381
00384 struct LoadNode : Node
00385 {
00386 unsigned varAddr;
00387
00389 LoadNode(const SourcePos& sourcePos, unsigned varAddr) : Node(sourcePos), varAddr(varAddr) { }
00390 virtual LoadNode* shallowCopy() { return new LoadNode(*this); }
00391
00392 virtual ReturnType typeCheck() const { return TYPE_INT; }
00393 virtual Node* optimize(std::wostream* dump);
00394 virtual unsigned getStackDepth() const;
00395 virtual void emit(PreLinkBytecode& bytecodes) const;
00396 virtual std::wstring toWString() const;
00397 virtual std::wstring toNodeName() const { return L"variable access (read)"; }
00398
00399 virtual unsigned getVectorAddr() const { return varAddr; }
00400 virtual unsigned getVectorSize() const { return 1; }
00401 };
00402
00405 struct ArrayWriteNode : Node
00406 {
00407 unsigned arrayAddr;
00408 unsigned arraySize;
00409 std::wstring arrayName;
00410
00411 ArrayWriteNode(const SourcePos& sourcePos, unsigned arrayAddr, unsigned arraySize, const std::wstring &arrayName);
00412 virtual ArrayWriteNode* shallowCopy() { return new ArrayWriteNode(*this); }
00413
00414 virtual ReturnType typeCheck() const { return TYPE_UNIT; }
00415 virtual Node* optimize(std::wostream* dump);
00416 virtual void emit(PreLinkBytecode& bytecodes) const;
00417 virtual std::wstring toWString() const;
00418 virtual std::wstring toNodeName() const { return L"array access (write)"; }
00419
00420 virtual unsigned getVectorAddr() const { return arrayAddr; }
00421 virtual unsigned getVectorSize() const { return 1; }
00422 };
00423
00426 struct ArrayReadNode : Node
00427 {
00428 unsigned arrayAddr;
00429 unsigned arraySize;
00430 std::wstring arrayName;
00431
00432 ArrayReadNode(const SourcePos& sourcePos, unsigned arrayAddr, unsigned arraySize, const std::wstring &arrayName);
00433 virtual ArrayReadNode* shallowCopy() { return new ArrayReadNode(*this); }
00434
00435 virtual ReturnType typeCheck() const { return TYPE_INT; }
00436 virtual Node* optimize(std::wostream* dump);
00437 virtual void emit(PreLinkBytecode& bytecodes) const;
00438 virtual std::wstring toWString() const;
00439 virtual std::wstring toNodeName() const { return L"array access (read)"; }
00440
00441 virtual unsigned getVectorAddr() const { return arrayAddr; }
00442 virtual unsigned getVectorSize() const { return 1; }
00443 };
00444
00447 struct CallNode : Node
00448 {
00449 unsigned funcId;
00450 std::vector<unsigned> argumentsAddr;
00451
00452 CallNode(const SourcePos& sourcePos, unsigned funcId);
00453 virtual CallNode* shallowCopy() { return new CallNode(*this); }
00454
00455 virtual ReturnType typeCheck() const { return TYPE_UNIT; }
00456 virtual Node* optimize(std::wostream* dump);
00457 virtual unsigned getStackDepth() const;
00458 virtual void emit(PreLinkBytecode& bytecodes) const;
00459 virtual std::wstring toWString() const;
00460 virtual std::wstring toNodeName() const { return L"native function call"; }
00461 };
00462
00465 struct ReturnNode : Node
00466 {
00467 ReturnNode(const SourcePos& sourcePos) : Node(sourcePos) {}
00468 virtual ReturnNode* shallowCopy() { return new ReturnNode(*this); }
00469
00470 virtual ReturnType typeCheck() const { return TYPE_UNIT; }
00471 virtual Node* optimize(std::wostream* dump) { return this; }
00472 virtual unsigned getStackDepth() const { return 0; }
00473 virtual void emit(PreLinkBytecode& bytecodes) const;
00474 virtual std::wstring toWString() const { return L"Return"; }
00475 virtual std::wstring toNodeName() const { return L"return"; }
00476 };
00477
00478
00479
00483 struct AbstractTreeNode : Node
00484 {
00486 AbstractTreeNode(const SourcePos& sourcePos) : Node(sourcePos) {}
00487
00488
00489 virtual ReturnType typeCheck() const { abort(); }
00490 virtual Node* optimize(std::wostream* dump) { abort(); }
00491 virtual unsigned getStackDepth() const { abort(); }
00492 virtual void emit(PreLinkBytecode& bytecodes) const { abort(); }
00493 };
00494
00497 struct TupleVectorNode : AbstractTreeNode
00498 {
00500 TupleVectorNode(const SourcePos& sourcePos) : AbstractTreeNode(sourcePos) {}
00501 TupleVectorNode(const SourcePos& sourcePos, int value) : AbstractTreeNode(sourcePos) { children.push_back(new ImmediateNode(sourcePos, value)); }
00502 virtual TupleVectorNode* shallowCopy() { return new TupleVectorNode(*this); }
00503
00504 virtual Node* expandToAsebaTree(std::wostream* dump, unsigned int index = 0);
00505 virtual std::wstring toWString() const;
00506 virtual std::wstring toNodeName() const { return L"array of constants"; }
00507 virtual void dump(std::wostream& dest, unsigned& indent) const;
00508
00509 virtual unsigned getVectorSize() const;
00510
00511 virtual bool isImmediateVector() const;
00512 virtual int getImmediateValue(unsigned index) const;
00513 virtual void addImmediateValue(int value) { children.push_back(new ImmediateNode(sourcePos, value)); }
00514 };
00515
00524 struct MemoryVectorNode : AbstractTreeNode
00525 {
00526 unsigned arrayAddr;
00527 unsigned arraySize;
00528 std::wstring arrayName;
00529 bool write;
00530
00531 MemoryVectorNode(const SourcePos& sourcePos, unsigned arrayAddr, unsigned arraySize, const std::wstring &arrayName);
00532 virtual MemoryVectorNode* shallowCopy() { return new MemoryVectorNode(*this); }
00533
00534 virtual Node* expandToAsebaTree(std::wostream* dump, unsigned int index = 0);
00535 virtual std::wstring toWString() const;
00536 virtual std::wstring toNodeName() const { return L"vector access"; }
00537
00538 virtual unsigned getVectorAddr() const;
00539 virtual unsigned getVectorSize() const;
00540 bool isAddressStatic() const;
00541
00542 virtual void setWrite(bool write) { this->write = write; }
00543 };
00544
00549 struct ArithmeticAssignmentNode : AbstractTreeNode
00550 {
00551 AsebaBinaryOperator op;
00552
00554 ArithmeticAssignmentNode(const SourcePos& sourcePos, AsebaBinaryOperator op, Node *left, Node *right);
00555 virtual ArithmeticAssignmentNode* shallowCopy() { return new ArithmeticAssignmentNode(*this); }
00556
00557 virtual void checkVectorSize() const;
00558 virtual Node* expandToAsebaTree(std::wostream* dump, unsigned int index = 0);
00559 virtual std::wstring toWString() const;
00560 virtual std::wstring toNodeName() const { return L"arithmetic assignment"; }
00561
00562 static ArithmeticAssignmentNode* fromArithmeticAssignmentToken(const SourcePos& sourcePos, Compiler::Token::Type token, Node *left, Node *right);
00563
00564 protected:
00565 const static AsebaBinaryOperator operatorMap[];
00566 static AsebaBinaryOperator getBinaryOperator(Compiler::Token::Type token);
00567 };
00568
00572 struct UnaryArithmeticAssignmentNode : AbstractTreeNode
00573 {
00574 AsebaBinaryOperator arithmeticOp;
00575
00577 UnaryArithmeticAssignmentNode(const SourcePos& sourcePos, Compiler::Token::Type token, Node *memory);
00578 virtual UnaryArithmeticAssignmentNode* shallowCopy() { return new UnaryArithmeticAssignmentNode(*this); }
00579
00580 virtual Node* expandToAsebaTree(std::wostream* dump, unsigned int index = 0);
00581 virtual std::wstring toWString() const;
00582 virtual std::wstring toNodeName() const { return L"unary arithmetic assignment"; }
00583 };
00584
00587 };
00588
00589 #endif