#ifndef __SYNTREE_H__ #define __SYNTREE_H__ #include #include #include #include using namespace std; #include "llvm/IR/IRBuilder.h" #include "llvm/IR/Module.h" #include "llvm/IR/Verifier.h" #include "llvm/IR/LegacyPassManager.h" #include "llvm/Transforms/Scalar.h" #include "llvm/Support/TargetSelect.h" using namespace llvm; extern Module* theModule; extern LLVMContext theContext; extern map namedValues; extern IRBuilder<> builder; extern legacy::FunctionPassManager* theFPM; // Hijerarhija klasa kojima se predstavlja sintaksno stablo // koje opisuje kod funkcija jezika. // Apstarktna bazna klasa class SynTreeNode { public: virtual ~SynTreeNode() {} // Funkcija vrsi interpretaciju koda za navedene vrednosti lokalnih // promenljivih funkcije virtual int Interpret(map& variables) = 0; virtual Value* Codegen() const = 0; }; // Klasa za predstavljanje brojevnih konstanti class ConstantNode : public SynTreeNode { public: ConstantNode(int value) : _value(value) {} int Interpret(map& variables) { return _value; } Value* Codegen() const; private: // Vrednost brojevne konstante int _value; }; // Klasa za predstavljanje promenljivih class VariableNode : public SynTreeNode { public: VariableNode(const string& name) : _name(name) {} int Interpret(map& variables) { // Vrednost promenljive citamo iz mape map::iterator i = variables.find(_name); // Ukoliko promenljiva nije definisana, podrazumevamo da joj // je vrednost 0 return i == variables.end() ? 0 : i->second; } Value* Codegen() const; private: // Ime promenljive string _name; }; // Apstraktna bazna klasa za predstavljanje operatora class OperatorNode : public SynTreeNode { protected: OperatorNode(SynTreeNode* op1) { _operands.push_back(op1); } OperatorNode(SynTreeNode* op1, SynTreeNode* op2) { _operands.push_back(op1); _operands.push_back(op2); } OperatorNode(SynTreeNode* op1, SynTreeNode* op2, SynTreeNode* op3) { _operands.push_back(op1); _operands.push_back(op2); _operands.push_back(op3); } OperatorNode(const vector& operands) : _operands(operands) {} public: ~OperatorNode() { vector::iterator i; for (i = _operands.begin(); i != _operands.end(); i++) delete *i; } // Operator se interpretira tako sto se izvrsi interpretacija // svih njegovih potomaka, a zatim se vrednost objedini primenom // virtuelne funkcije Operate int Interpret(map& variables) { vector operand_values; vector::iterator i; for (i = _operands.begin(); i != _operands.end(); i++) operand_values.push_back((*i)->Interpret(variables)); return Operate(operand_values); } // Pomocna virtuelna funkcija koja vrsi primenu operatora na dati niz brojeva virtual int Operate(const vector&) { return 0; } protected: // Operandi vector _operands; }; // Operator sabiranja class PlusNode: public OperatorNode { public: PlusNode(SynTreeNode* op1, SynTreeNode* op2) : OperatorNode(op1, op2) {} Value* Codegen() const; protected: int Operate(const vector& v) { return v[0] + v[1]; } }; // Operator mnozenja class TimesNode: public OperatorNode { public: TimesNode(SynTreeNode* op1, SynTreeNode* op2) : OperatorNode(op1, op2) {} Value* Codegen() const; protected: int Operate(const vector& v) { return v[0] * v[1]; } }; // Operator deljenja class DivideNode: public OperatorNode { public: DivideNode(SynTreeNode* op1, SynTreeNode* op2) : OperatorNode(op1, op2) {} Value* Codegen() const; protected: int Operate(const vector& v) { return v[0] / v[1]; } }; // Operator oduzimanja class MinusNode: public OperatorNode { public: MinusNode(SynTreeNode* op1, SynTreeNode* op2) : OperatorNode(op1, op2) {} Value* Codegen() const; protected: int Operate(const vector& v) { return v[0] - v[1]; } }; // Operator poredjenja == class EqNode : public OperatorNode { public: EqNode(SynTreeNode* op1, SynTreeNode* op2) : OperatorNode(op1, op2) {} Value* Codegen() const; protected: int Operate(const vector& v) { return v[0] == v[1]; } }; // Ternarni uslovni operator class QuestionNode : public OperatorNode { public: QuestionNode(SynTreeNode* op1, SynTreeNode* op2, SynTreeNode* op3) : OperatorNode(op1, op2, op3) {} Value* Codegen() const; protected: // Prilikom interpretacije se izvrsava lenjo izracunavanje // Zbog toga je neophodno predefinisati funkciju Interpret int Interpret(map& variables) { return _operands[0]->Interpret(variables) ? _operands[1]->Interpret(variables) : _operands[2]->Interpret(variables); } }; // Klasom se predstavlja operator dodele class AssignmentNode : public SynTreeNode { public: AssignmentNode(const string& name, SynTreeNode* expression) : _var_name(name), _expression(expression) {} ~AssignmentNode() { delete _expression; } int Interpret(map& variables) { // Izracunava se vrednost izraza sa desne strane // A zatim se u mapu koja cuva vrednosti lokalnih promenljivih // ta vrednost pridruzuje promenljivoj sa leve strane return (variables[_var_name] = _expression->Interpret(variables)); } Value* Codegen() const; private: // Ime promenljive kojoj se dodeljuje vrednost string _var_name; // Desna strana dodele SynTreeNode* _expression; }; // Klasa koja prestavlja poziv funkcije class FunctCallNode : public OperatorNode { public: FunctCallNode(const string& name, const vector& operands) : OperatorNode(operands), _name(name) {} Value* Codegen() const; protected: int Operate(const vector& v); private: string _name; }; class PrintNode : public SynTreeNode { public: PrintNode(SynTreeNode* expression) : _expression(expression) {} ~PrintNode() { delete _expression; } int Interpret(map& variables) { cout<<_expression->Interpret(variables)<& v) { return 0; } }; void initializeModuleAndPassManager(); AllocaInst* createEntryBlockAlloca(Function* theFunction, const string& name); #endif