123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558 |
- #ifndef QLOW_SEMANTIC_H
- #define QLOW_SEMANTIC_H
- #include <string>
- #include <map>
- #include "Util.h"
- #include "Ast.h"
- #include "Visitor.h"
- #include "Scope.h"
- #include "Type.h"
- #include "Context.h"
- #include <llvm/IR/Value.h>
- #include <llvm/IR/IRBuilder.h>
- #include <llvm/IR/BasicBlock.h>
- namespace qlow
- {
- namespace sem
- {
- std::pair<std::unique_ptr<Context>, std::unique_ptr<GlobalScope>>
- createFromAst(const qlow::ast::Ast& ast);
- struct Class;
- struct Variable;
- struct Field;
- struct Method;
- struct Statement;
- struct Expression;
-
- struct ThisExpression;
- struct DoEndBlock;
- struct IfElseBlock;
- struct WhileBlock;
- struct FeatureCallStatement;
- struct AssignmentStatement;
- struct ReturnStatement;
-
- struct LocalVariableExpression;
- struct AddressExpression;
- struct ArrayAccessExpression;
- struct Operation;
- struct UnaryOperation;
- struct BinaryOperation;
-
- struct CastExpression;
-
- struct NewExpression;
- struct NewArrayExpression;
- struct MethodCallExpression;
- struct FieldAccessExpression;
-
- struct IntConst;
- }
- class ExpressionCodegenVisitor;
- class LValueVisitor;
- class StatementVisitor;
- namespace gen
- {
- class FunctionGenerator;
- }
- }
- struct qlow::sem::Class : public SemanticObject
- {
- qlow::ast::Class* astNode;
- std::string name;
- bool isReferenceType;
- SymbolTable<Field> fields;
- SymbolTable<Method> methods;
- ClassScope scope;
- Type* classType;
- /// \brief generated during llvm code generation, not availab
- llvm::Type* llvmType;
- inline Class(qlow::ast::Class* astNode,
- GlobalScope& globalScope) :
- SemanticObject{ globalScope.getContext() },
- astNode{ astNode },
- name{ astNode->name },
- isReferenceType{ astNode->isReferenceType },
- scope{ globalScope, this },
- classType{ globalScope.getContext().getClassType(this) },
- llvmType{ nullptr }
- {
- }
- inline Class(const std::string& nativeName,
- GlobalScope& globalScope) :
- SemanticObject{ globalScope.getContext() },
- astNode{ nullptr },
- name{ nativeName },
- scope{ globalScope, this },
- llvmType{ nullptr }
- {
- }
-
- virtual std::string toString(void) const override;
- };
- struct qlow::sem::Variable : public SemanticObject
- {
- Type* type;
- std::string name;
- bool isParameter;
- /// if this is a local variable, this stores a reference to the llvm
- /// instance of this variable. If it is a parameter, the parameter value
- llvm::Value* allocaInst;
-
- inline Variable(Context& context) :
- SemanticObject{ context } {}
- inline Variable(Context& context, Type* type, const std::string& name) :
- SemanticObject{ context },
- type{ type },
- name{ name },
- allocaInst { nullptr }
- {
- }
-
- virtual std::string toString(void) const override;
- };
- struct qlow::sem::Field : public Variable
- {
- inline Field(Context& context) :
- Variable{ context } {}
- int llvmStructIndex;
- virtual std::string toString(void) const override;
- };
- struct qlow::sem::Method : public SemanticObject
- {
- Class* containingClass;
- Type* returnType;
- std::vector<Variable*> arguments;
- std::string name;
- ast::MethodDefinition* astNode;
- ThisExpression* thisExpression;
- std::unique_ptr<DoEndBlock> body;
- bool isExtern;
- LocalScope scope;
- llvm::Function* llvmNode;
- inline Method(Scope& parentScope,
- Type* returnType, bool isExtern) :
- SemanticObject{ parentScope.getContext() },
- containingClass{ nullptr },
- returnType{ returnType },
- thisExpression{ nullptr },
- body{ nullptr },
- isExtern{ isExtern },
- scope{ parentScope, this }
- {
- }
-
-
- inline Method(ast::MethodDefinition* astNode, Scope& parentScope) :
- SemanticObject{ parentScope.getContext() },
- containingClass{ nullptr },
- returnType{ parentScope.getReturnableType() },
- name{ astNode->name },
- astNode{ astNode },
- thisExpression{ nullptr },
- body{ nullptr },
- isExtern{ astNode->isExtern() },
- scope{ parentScope, this }
- {
- }
-
- void generateThisExpression(void);
- std::string getMangledName(void) const;
-
- virtual std::string toString(void) const override;
- };
- struct qlow::sem::ThisExpression : public Variable
- {
- Method* method;
- inline ThisExpression(Method* method) :
- Variable{
- method->context,
- method->context.getClassType(method->containingClass),
- "this"
- },
- method{ method }
- {
- }
-
- llvm::Value* accept(ExpressionCodegenVisitor& visitor, llvm::IRBuilder<>& arg2);
- };
- struct qlow::sem::Statement : public SemanticObject, public Visitable<llvm::Value*, gen::FunctionGenerator, qlow::StatementVisitor>
- {
- inline Statement(Context& context) :
- SemanticObject{ context } {}
- virtual llvm::Value* accept(qlow::StatementVisitor&, gen::FunctionGenerator&) = 0;
- };
- struct qlow::sem::DoEndBlock : public Statement
- {
- LocalScope scope;
- OwningList<Statement> statements;
- inline DoEndBlock(LocalScope& parentScope) :
- Statement{ parentScope.getContext() },
- scope{ parentScope } {}
-
- virtual llvm::Value* accept(qlow::StatementVisitor&, gen::FunctionGenerator&) override;
- };
- struct qlow::sem::IfElseBlock : public Statement
- {
- std::unique_ptr<Expression> condition;
- std::unique_ptr<DoEndBlock> ifBlock;
- std::unique_ptr<DoEndBlock> elseBlock;
- inline IfElseBlock(std::unique_ptr<Expression> condition,
- std::unique_ptr<DoEndBlock> ifBlock,
- std::unique_ptr<DoEndBlock> elseBlock) :
- Statement{ ifBlock->context },
- condition{ std::move(condition) },
- ifBlock{ std::move(ifBlock) },
- elseBlock{ std::move(elseBlock) }
- {
- }
-
- virtual llvm::Value* accept(qlow::StatementVisitor&, gen::FunctionGenerator&) override;
- };
- struct qlow::sem::WhileBlock : public Statement
- {
- std::unique_ptr<Expression> condition;
- std::unique_ptr<DoEndBlock> body;
- inline WhileBlock(std::unique_ptr<Expression> condition,
- std::unique_ptr<DoEndBlock> body) :
- Statement{ body->context },
- condition{ std::move(condition) },
- body{ std::move(body) }
- {
- }
-
- virtual llvm::Value* accept(qlow::StatementVisitor&, gen::FunctionGenerator&) override;
- };
- struct qlow::sem::AssignmentStatement : public Statement
- {
- std::unique_ptr<Expression> target;
- std::unique_ptr<Expression> value;
- inline AssignmentStatement(Context& context) :
- Statement{ context } {}
- virtual std::string toString(void) const override;
- virtual llvm::Value* accept(qlow::StatementVisitor&, gen::FunctionGenerator&) override;
- };
- struct qlow::sem::ReturnStatement : public Statement
- {
- std::unique_ptr<Expression> value;
- inline ReturnStatement(Context& context) :
- Statement{ context } {}
- virtual std::string toString(void) const override;
- virtual llvm::Value* accept(qlow::StatementVisitor&, gen::FunctionGenerator&) override;
- };
- struct qlow::sem::Expression :
- public SemanticObject,
- public Visitable<llvm::Value*,
- llvm::IRBuilder<>,
- qlow::ExpressionCodegenVisitor>,
- public Visitable<llvm::Value*,
- qlow::gen::FunctionGenerator,
- qlow::LValueVisitor>
- {
- Type* type;
- CodePosition pos;
-
- inline Expression(Context& context, Type* type, const CodePosition& pos) :
- SemanticObject{ context },
- type{ type },
- pos{ pos }
- {
- }
-
- inline virtual bool isLValue(void) const { return false; }
-
- virtual llvm::Value* accept(ExpressionCodegenVisitor& visitor, llvm::IRBuilder<>& arg2) override = 0;
- virtual llvm::Value* accept(LValueVisitor& visitor, qlow::gen::FunctionGenerator&) override;
- };
- struct qlow::sem::Operation : public Expression
- {
- std::string opString;
-
- inline Operation(Context& context, Type* type, const CodePosition& pos) :
- Expression{ context, type, pos }
- {
- }
- };
- struct qlow::sem::LocalVariableExpression : public Expression
- {
- Variable* var;
-
- inline LocalVariableExpression(Variable* var, const CodePosition& pos) :
- Expression{ var->context, var->type, pos },
- var{ var }
- {
- }
-
- inline virtual bool isLValue(void) const override { return true; }
- virtual llvm::Value* accept(ExpressionCodegenVisitor& visitor, llvm::IRBuilder<>& arg2) override;
- virtual llvm::Value* accept(LValueVisitor& visitor, qlow::gen::FunctionGenerator&) override;
- virtual std::string toString(void) const override;
- };
- struct qlow::sem::AddressExpression : public Expression
- {
- std::unique_ptr<sem::Expression> target;
-
- inline AddressExpression(std::unique_ptr<sem::Expression> target) :
- Expression{ target->context, nullptr /*context.createPointerType(target->type)*/, CodePosition{} },
- target{ std::move(target) }
- {
- }
-
- virtual llvm::Value* accept(ExpressionCodegenVisitor& visitor, llvm::IRBuilder<>& arg2) override;
- };
- struct qlow::sem::ArrayAccessExpression : public Expression
- {
- std::unique_ptr<sem::Expression> array;
- std::unique_ptr<sem::Expression> index;
- inline ArrayAccessExpression(std::unique_ptr<sem::Expression> array,
- std::unique_ptr<sem::Expression> index,
- const CodePosition& pos) :
- Expression{ array->context, array->type->getArrayOf(), pos },
- array{ std::move(array) },
- index{ std::move(index) }
- {
- }
- virtual llvm::Value* accept(ExpressionCodegenVisitor& visitor, llvm::IRBuilder<>& arg2) override;
- virtual llvm::Value* accept(LValueVisitor& visitor, qlow::gen::FunctionGenerator&) override;
- virtual std::string toString(void) const override;
- };
- struct qlow::sem::BinaryOperation : public Operation
- {
- std::unique_ptr<Expression> left;
- std::unique_ptr<Expression> right;
- ast::BinaryOperation* astNode;
-
- /// method that is called to execute the operator
- sem::Method* operationMethod;
-
- inline BinaryOperation(Context& context,
- Type* type, ast::BinaryOperation* astNode) :
- Operation{ context, type , astNode->pos},
- astNode{ astNode }
- {
- }
-
- virtual llvm::Value* accept(ExpressionCodegenVisitor& visitor, llvm::IRBuilder<>& arg2) override;
-
- virtual std::string toString(void) const override;
- };
- struct qlow::sem::CastExpression : public Expression
- {
- std::unique_ptr<Expression> expression;
- Type* targetType;
-
- ast::CastExpression* astNode;
- bool isImplicit;
- bool isNativeCast;
-
- inline CastExpression(std::unique_ptr<Expression> expression,
- Type* type,
- ast::CastExpression* astNode,
- bool isNative,
- const CodePosition& pos) :
- Expression{ expression->context, type, pos },
- expression{ std::move(expression) },
- targetType{ type },
- astNode{ astNode },
- isImplicit{ astNode == nullptr },
- isNativeCast{ isNative }
- {
- }
-
- virtual llvm::Value* accept(ExpressionCodegenVisitor& visitor, llvm::IRBuilder<>& arg2) override;
-
- virtual std::string toString(void) const override;
- };
- struct qlow::sem::NewExpression : public Expression
- {
- inline NewExpression(Context& context, Type* type, const CodePosition& pos) :
- Expression{ context, type, pos }
- {
- }
-
- virtual llvm::Value* accept(ExpressionCodegenVisitor& visitor, llvm::IRBuilder<>& arg2) override;
- virtual std::string toString(void) const override;
- };
- struct qlow::sem::NewArrayExpression : public Expression
- {
- Type* elementType;
- std::unique_ptr<Expression> length;
-
- inline NewArrayExpression(Type* elementType, std::unique_ptr<Expression> length, const CodePosition& pos) :
- Expression{ length->context, length->context.getArrayType(elementType), pos },
- elementType{ elementType },
- length{ std::move(length) }
- {
- }
-
- virtual llvm::Value* accept(ExpressionCodegenVisitor& visitor, llvm::IRBuilder<>& arg2) override;
- virtual std::string toString(void) const override;
- };
- struct qlow::sem::UnaryOperation : public Operation
- {
- qlow::ast::UnaryOperation::Side side;
- std::unique_ptr<Expression> arg;
-
- inline UnaryOperation(Context& context, Type* type, const CodePosition& pos) :
- Operation{ context, type, pos }
- {
- }
-
- virtual llvm::Value* accept(ExpressionCodegenVisitor& visitor, llvm::IRBuilder<>& arg2) override;
- virtual std::string toString(void) const override;
- };
- struct qlow::sem::MethodCallExpression : public Expression
- {
- Method* callee;
- std::unique_ptr<Expression> target;
- OwningList<Expression> arguments;
-
- inline MethodCallExpression(std::unique_ptr<Expression> target,
- Method* callee, const CodePosition& pos) :
- Expression{ callee->context, callee->returnType, pos },
- callee{ callee },
- target{ std::move(target) }
- {
- }
-
- virtual llvm::Value* accept(ExpressionCodegenVisitor& visitor, llvm::IRBuilder<>& arg2) override;
-
- virtual std::string toString(void) const override;
- };
- struct qlow::sem::FieldAccessExpression : public Expression
- {
- sem::Field* accessed;
- std::unique_ptr<Expression> target;
- //OwningList<Expression> arguments;
-
- inline FieldAccessExpression(std::unique_ptr<Expression> target,
- Field* accessed, const CodePosition& pos) :
- Expression{ target->context, accessed->type, pos },
- accessed{ accessed },
- target{ std::move(target) }
- {
- }
-
- inline virtual bool isLValue(void) const override { return true; }
-
- virtual llvm::Value* accept(ExpressionCodegenVisitor& visitor, llvm::IRBuilder<>& arg2) override;
- virtual llvm::Value* accept(LValueVisitor& visitor, qlow::gen::FunctionGenerator&) override;
-
- virtual std::string toString(void) const override;
- };
- struct qlow::sem::IntConst : public Expression
- {
- unsigned long long value;
- inline IntConst(Context& context, unsigned long long value, const CodePosition& pos) :
- Expression{ context, context.getNativeType(NativeType::NType::INTEGER), pos },
- value{ value }
- {
- }
-
- virtual llvm::Value* accept(ExpressionCodegenVisitor& visitor, llvm::IRBuilder<>& arg2) override;
- virtual std::string toString(void) const override;
- };
- struct qlow::sem::FeatureCallStatement : public Statement
- {
- std::unique_ptr<MethodCallExpression> expr;
- inline FeatureCallStatement(std::unique_ptr<MethodCallExpression> expr) :
- Statement{ expr->context },
- expr{ std::move(expr) } {}
- virtual std::string toString(void) const override;
- virtual llvm::Value* accept(qlow::StatementVisitor&, gen::FunctionGenerator&) override;
- };
- #endif // QLOW_SEMANTIC_H
|