summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNagi5Yeq <wu@x-nagi.com>2020-05-15 21:16:26 +0800
committerNagi5Yeq <wu@x-nagi.com>2020-05-15 21:16:26 +0800
commit41f6e75e3f26bdcccfcb3910f202452e14653826 (patch)
tree0076a928d4ac9737f8b83b7b6b0c055e5ff4f46a
parentd80958f987790f533f5048c2e0e8a1cd5fd9f5a1 (diff)
basic support of types
-rw-r--r--CMakeLists.txt36
-rw-r--r--Context.cc4
-rw-r--r--Context.hh5
-rw-r--r--Driver.cc10
-rw-r--r--Driver.hh7
-rw-r--r--Lexer.hh19
-rw-r--r--Lexer.l11
-rw-r--r--Parser.y22
-rw-r--r--Type.cc212
-rw-r--r--Type.hh108
-rw-r--r--TypeManager.cc0
-rw-r--r--TypeManager.hh16
-rw-r--r--main.cc5
-rw-r--r--node/BaseNode.cc4
-rw-r--r--node/BaseNode.hh9
-rw-r--r--node/ExpressionNode.hh8
-rw-r--r--node/LiteralNode.cc8
-rw-r--r--node/LiteralNode.hh7
-rw-r--r--win32/getopt.c (renamed from getopt.c)0
-rw-r--r--win32/getopt.h (renamed from getopt.h)0
20 files changed, 418 insertions, 73 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 388e050..cf4517f 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -5,36 +5,46 @@ find_package(LLVM REQUIRED CONFIG)
include_directories(${LLVM_INCLUDE_DIRS})
add_definitions(${LLVM_DEFINITIONS})
-find_package(BISON REQUIRED)
-find_package(FLEX REQUIRED)
-
set(PCC_SOURCE
Context.cc
Driver.cc
Log.cc
main.cc
+ Type.cc
Version.cc)
-bison_target(pcc_parser Parser.y ${CMAKE_CURRENT_BINARY_DIR}/Parser.cc)
-flex_target(pcc_lexer Lexer.l ${CMAKE_CURRENT_BINARY_DIR}/Lexer.cc)
-add_flex_bison_dependency(pcc_lexer pcc_parser)
-
-add_definitions(-DPCC_OSNAME="${CMAKE_SYSTEM}")
-
list(APPEND PCC_SOURCE
node/BaseNode.cc
node/LiteralNode.cc)
+set(PCC_INCLUDE
+ ${CMAKE_SOURCE_DIR}
+ ${CMAKE_SOURCE_DIR}/node
+ ${CMAKE_CURRENT_BINARY_DIR})
+
+if(WIN32)
+ add_compile_options(/Zc:__cplusplus)
+ list(APPEND PCC_SOURCE
+ win32/getopt.c)
+ list(APPEND PCC_INCLUDE
+ ${CMAKE_SOURCE_DIR}/win32)
+endif()
+
+find_package(BISON REQUIRED)
+find_package(FLEX REQUIRED)
+
+bison_target(pcc_parser Parser.y ${CMAKE_CURRENT_BINARY_DIR}/Parser.cc)
+flex_target(pcc_lexer Lexer.l ${CMAKE_CURRENT_BINARY_DIR}/Lexer.cc)
+add_flex_bison_dependency(pcc_lexer pcc_parser)
list(APPEND PCC_SOURCE
${BISON_pcc_parser_OUTPUTS}
${FLEX_pcc_lexer_OUTPUTS})
+add_definitions(-DPCC_OSNAME="${CMAKE_SYSTEM}")
+
add_executable(pcc ${PCC_SOURCE})
-target_include_directories(pcc PRIVATE
- ${CMAKE_SOURCE_DIR}
- ${CMAKE_SOURCE_DIR}/node
- ${CMAKE_CURRENT_BINARY_DIR})
+target_include_directories(pcc PRIVATE ${PCC_INCLUDE})
llvm_map_components_to_libnames(llvm_libs support core)
target_link_libraries(pcc ${llvm_libs})
diff --git a/Context.cc b/Context.cc
index ee88544..fd4a7a5 100644
--- a/Context.cc
+++ b/Context.cc
@@ -8,4 +8,8 @@ llvm::LLVMContext GlobalContext;
Context::Context(const char* name)
: builder_(GlobalContext)
, module_(name, GlobalContext) {}
+
+llvm::Module* Context::GetModule() { return &module_; }
+
+llvm::IRBuilder<>* Context::GetBuilder() { return &builder_; }
} // namespace pcc
diff --git a/Context.hh b/Context.hh
index bc66632..e300a19 100644
--- a/Context.hh
+++ b/Context.hh
@@ -5,15 +5,16 @@
#include <llvm/IR/Module.h>
namespace pcc {
-class Driver;
+using Value = llvm::Value*;
class Context {
public:
Context(const char* name);
+ llvm::Module* GetModule();
+ llvm::IRBuilder<>* GetBuilder();
private:
llvm::IRBuilder<> builder_;
llvm::Module module_;
- friend class Driver;
};
extern llvm::LLVMContext GlobalContext;
diff --git a/Driver.cc b/Driver.cc
index 6c3509d..6d557db 100644
--- a/Driver.cc
+++ b/Driver.cc
@@ -2,8 +2,8 @@
#include "Parser.hh"
namespace pcc {
-Driver::Driver(Context* context)
- : context_(context) {}
+Driver::Driver(const char* name)
+ : context_(name) {}
Driver::~Driver() {}
@@ -12,12 +12,8 @@ void Driver::Parse(std::string& filename) {
if (StartLexer(filename) != 0) {
return;
}
- Parser parser(*this);
+ Parser parser(*this, &context_);
parser.parse();
StopLexer();
}
-
-llvm::Module* Driver::GetModule() { return &context_->module_; }
-
-llvm::IRBuilder<>* Driver::GetBuilder() { return &context_->builder_; }
} // namespace pcc
diff --git a/Driver.hh b/Driver.hh
index 5f0d18d..d3e773d 100644
--- a/Driver.hh
+++ b/Driver.hh
@@ -9,16 +9,15 @@
namespace pcc {
class Driver {
public:
- Driver(Context* context);
+ Driver(const char* name);
~Driver();
int StartLexer(std::string& filename);
void StopLexer();
void Parse(std::string& filename);
- llvm::Module* GetModule();
- llvm::IRBuilder<>* GetBuilder();
Location location_;
- Context* context_;
+ private:
+ Context context_;
};
} // namespace pcc
diff --git a/Lexer.hh b/Lexer.hh
index 35b27cc..c6103eb 100644
--- a/Lexer.hh
+++ b/Lexer.hh
@@ -6,7 +6,8 @@
#include "Node.hh"
#include "Parser.hh"
-#define YY_DECL pcc::Parser::symbol_type yylex(pcc::Driver& driver)
+#define YY_DECL \
+ pcc::Parser::symbol_type yylex(pcc::Driver& driver, pcc::Context* context)
YY_DECL;
@@ -51,28 +52,28 @@ char* GetUnescapedChar(char* s, char* end, char* out) {
}
}
-Parser::symbol_type make_BOOLEAN_LITERAL(bool b, pcc::Driver& driver,
+Parser::symbol_type make_BOOLEAN_LITERAL(bool b, pcc::Context* context,
const Parser::location_type& loc) {
return Parser::make_BOOLEAN_LITERAL(
- std::make_shared<BooleanLiteralNode>(&driver, b), loc);
+ std::make_shared<BooleanLiteralNode>(context, b), loc);
}
-Parser::symbol_type make_INTEGER_LITERAL(int v, pcc::Driver& driver,
+Parser::symbol_type make_INTEGER_LITERAL(int v, pcc::Context* context,
const Parser::location_type& loc) {
return Parser::make_INTEGER_LITERAL(
- std::make_shared<IntegerLiteralNode>(&driver, v), loc);
+ std::make_shared<IntegerLiteralNode>(context, v), loc);
}
-Parser::symbol_type make_REAL_LITERAL(float v, pcc::Driver& driver,
+Parser::symbol_type make_REAL_LITERAL(float v, pcc::Context* context,
const Parser::location_type& loc) {
return Parser::make_REAL_LITERAL(
- std::make_shared<RealLiteralNode>(&driver, v), loc);
+ std::make_shared<RealLiteralNode>(context, v), loc);
}
-Parser::symbol_type make_STRING_LITERAL(char* s, pcc::Driver& driver,
+Parser::symbol_type make_STRING_LITERAL(char* s, pcc::Context* context,
const Parser::location_type& loc) {
return Parser::make_STRING_LITERAL(
- std::make_shared<StringLiteralNode>(&driver, s), loc);
+ std::make_shared<StringLiteralNode>(context, s), loc);
}
} // namespace Lexer
} // namespace pcc
diff --git a/Lexer.l b/Lexer.l
index 6f43790..b55cb80 100644
--- a/Lexer.l
+++ b/Lexer.l
@@ -74,7 +74,6 @@ white [\t\f\r ]
"/" {return Parser::make_REAL_DIV(loc);}
"div" {return Parser::make_DIV(loc);}
"mod" {return Parser::make_MOD(loc);}
-"**" {return Parser::make_EXP(loc);}
"and" {return Parser::make_AND(loc);}
"not" {return Parser::make_NOT(loc);}
@@ -105,17 +104,17 @@ white [\t\f\r ]
"real" {return Parser::make_REAL(loc);}
"string" {return Parser::make_STRING(loc);}
-"true" {return pcc::Lexer::make_BOOLEAN_LITERAL(true, driver, loc);}
-"false" {return pcc::Lexer::make_BOOLEAN_LITERAL(false, driver, loc);}
+"true" {return pcc::Lexer::make_BOOLEAN_LITERAL(true, context, loc);}
+"false" {return pcc::Lexer::make_BOOLEAN_LITERAL(false, context, loc);}
{integer} {
int number = std::strtol(yytext, NULL, 0);
- return pcc::Lexer::make_INTEGER_LITERAL(number, driver, loc);
+ return pcc::Lexer::make_INTEGER_LITERAL(number, context, loc);
}
{real} {
float number = std::strtof(yytext, NULL);
- return pcc::Lexer::make_REAL_LITERAL(number, driver, loc);
+ return pcc::Lexer::make_REAL_LITERAL(number, context, loc);
}
{string} {
@@ -127,7 +126,7 @@ white [\t\f\r ]
p++;
}
*p = '\0';
- return pcc::Lexer::make_STRING_LITERAL(yytext + 1, driver, loc);
+ return pcc::Lexer::make_STRING_LITERAL(yytext + 1, context, loc);
}
{identifier} {
diff --git a/Parser.y b/Parser.y
index 993867f..bcde931 100644
--- a/Parser.y
+++ b/Parser.y
@@ -7,8 +7,9 @@
#include "Location.hh"
#include "Node.hh"
+#include "Context.hh"
-namespace pcc {
+namespace pcc{
class Driver;
}
}
@@ -16,11 +17,12 @@ namespace pcc {
%locations
%param {pcc::Driver& driver}
+%param {pcc::Context* context}
-%code {
-#include "Driver.hh"
+%code{
+#define YY_DECL \
+ pcc::Parser::symbol_type yylex(pcc::Driver& driver, pcc::Context* context)
-#define YY_DECL pcc::Parser::symbol_type yylex(pcc::Driver& driver)
YY_DECL;
}
@@ -36,7 +38,7 @@ YY_DECL;
%token PROGRAM IDENTIFIER CONST VAR BEGINS ENDS FUNCTION FILE_END
%token IF THEN ELSE WHILE DO
%token BOOLEAN CHAR INTEGER REAL STRING
-%token ADD SUB MUL REAL_DIV DIV MOD EXP LT LE GT GE EQ NE
+%token ADD SUB MUL REAL_DIV DIV MOD LT LE GT GE EQ NE
%token AND NOT OR XOR
%token INTEGER_LITERAL REAL_LITERAL STRING_LITERAL BOOLEAN_LITERAL CHAR_LITERAL
@@ -166,15 +168,11 @@ l2_expression
;
l3_expression
- : l3_expression l4_operator l4_expression
- | l4_expression
-
-l4_expression
: lvalue
| function_call
| literal
| LPARENTHESIS expression RPARENTHESIS
- | l5_operator l4_expression
+ | l4_operator l3_expression
;
l1_operator
@@ -202,10 +200,6 @@ l3_operator
;
l4_operator
- : EXP
- ;
-
-l5_operator
: NOT
| ADD
| SUB
diff --git a/Type.cc b/Type.cc
new file mode 100644
index 0000000..4e3dd86
--- /dev/null
+++ b/Type.cc
@@ -0,0 +1,212 @@
+#include <llvm/IR/InstrTypes.h>
+
+#include "Type.hh"
+
+namespace pcc {
+Type::Type(const char* name, bool IsBasicType, int width)
+ : name_(name)
+ , IsBasicType_(IsBasicType)
+ , width_(width) {}
+
+const char* Type::GetCommonName() { return name_; }
+
+int Type::CreateBinaryOperation(BinaryOperator op, Value v0, Value v1,
+ Context* context) {
+ return NotAllowed(v0, v1, context);
+}
+
+int Type::NotAllowed(Value v0, Value v1, Context* context) { return -1; }
+
+int Type::CreateAdd(Value v0, Value v1, Context* context) {
+ context->GetBuilder()->CreateBinOp(llvm::Instruction::Add, v0, v1);
+ return 0;
+}
+
+int Type::CreateSub(Value v0, Value v1, Context* context) {
+ context->GetBuilder()->CreateBinOp(llvm::Instruction::Sub, v0, v1);
+ return 0;
+}
+
+int Type::CreateMul(Value v0, Value v1, Context* context) {
+ context->GetBuilder()->CreateBinOp(llvm::Instruction::Mul, v0, v1);
+ return 0;
+}
+
+int Type::CreateDiv(Value v0, Value v1, Context* context) {
+ context->GetBuilder()->CreateBinOp(llvm::Instruction::SDiv, v0, v1);
+ return 0;
+}
+
+int Type::CreateMod(Value v0, Value v1, Context* context) {
+ context->GetBuilder()->CreateBinOp(llvm::Instruction::SRem, v0, v1);
+ return 0;
+}
+
+int Type::CreateLt(Value v0, Value v1, Context* context) {
+ context->GetBuilder()->CreateICmp(llvm::CmpInst::ICMP_SLT, v0, v1);
+ return 0;
+}
+
+int Type::CreateLe(Value v0, Value v1, Context* context) {
+ context->GetBuilder()->CreateICmp(llvm::CmpInst::ICMP_SLE, v0, v1);
+ return 0;
+}
+
+int Type::CreateGt(Value v0, Value v1, Context* context) {
+ context->GetBuilder()->CreateICmp(llvm::CmpInst::ICMP_SGT, v0, v1);
+ return 0;
+}
+
+int Type::CreateGe(Value v0, Value v1, Context* context) {
+ context->GetBuilder()->CreateICmp(llvm::CmpInst::ICMP_SGE, v0, v1);
+ return 0;
+}
+
+int Type::CreateEq(Value v0, Value v1, Context* context) {
+ context->GetBuilder()->CreateICmp(llvm::CmpInst::ICMP_EQ, v0, v1);
+ return 0;
+}
+
+int Type::CreateNe(Value v0, Value v1, Context* context) {
+ context->GetBuilder()->CreateICmp(llvm::CmpInst::ICMP_NE, v0, v1);
+ return 0;
+}
+
+int Type::CreateAnd(Value v0, Value v1, Context* context) {
+ context->GetBuilder()->CreateBinOp(llvm::Instruction::And, v0, v1);
+ return 0;
+}
+
+int Type::CreateOr(Value v0, Value v1, Context* context) {
+ context->GetBuilder()->CreateBinOp(llvm::Instruction::Or, v0, v1);
+ return 0;
+}
+
+int Type::CreateXor(Value v0, Value v1, Context* context) {
+ context->GetBuilder()->CreateBinOp(llvm::Instruction::Xor, v0, v1);
+ return 0;
+}
+
+int Type::CreateFAdd(Value v0, Value v1, Context* context) {
+ context->GetBuilder()->CreateBinOp(llvm::Instruction::FAdd, v0, v1);
+ return 0;
+}
+
+int Type::CreateFSub(Value v0, Value v1, Context* context) {
+ context->GetBuilder()->CreateBinOp(llvm::Instruction::FSub, v0, v1);
+ return 0;
+}
+
+int Type::CreateFMul(Value v0, Value v1, Context* context) {
+ context->GetBuilder()->CreateBinOp(llvm::Instruction::FMul, v0, v1);
+ return 0;
+}
+
+int Type::CreateFDiv(Value v0, Value v1, Context* context) {
+ context->GetBuilder()->CreateBinOp(llvm::Instruction::FDiv, v0, v1);
+ return 0;
+}
+
+int Type::CreateFMod(Value v0, Value v1, Context* context) {
+ context->GetBuilder()->CreateBinOp(llvm::Instruction::FRem, v0, v1);
+ return 0;
+}
+
+int Type::CreateFLt(Value v0, Value v1, Context* context) {
+ context->GetBuilder()->CreateFCmp(llvm::CmpInst::FCMP_OLT, v0, v1);
+ return 0;
+}
+
+int Type::CreateFLe(Value v0, Value v1, Context* context) {
+ context->GetBuilder()->CreateFCmp(llvm::CmpInst::FCMP_OLE, v0, v1);
+ return 0;
+}
+
+int Type::CreateFGt(Value v0, Value v1, Context* context) {
+ context->GetBuilder()->CreateFCmp(llvm::CmpInst::FCMP_OGT, v0, v1);
+ return 0;
+}
+
+int Type::CreateFGe(Value v0, Value v1, Context* context) {
+ context->GetBuilder()->CreateFCmp(llvm::CmpInst::FCMP_OGE, v0, v1);
+ return 0;
+}
+
+int Type::CreateFEq(Value v0, Value v1, Context* context) {
+ context->GetBuilder()->CreateFCmp(llvm::CmpInst::FCMP_OEQ, v0, v1);
+ return 0;
+}
+
+int Type::CreateFNe(Value v0, Value v1, Context* context) {
+ context->GetBuilder()->CreateFCmp(llvm::CmpInst::FCMP_ONE, v0, v1);
+ return 0;
+}
+
+BooleanType::BooleanType()
+ : Type("boolean", true, 1) {}
+
+int BooleanType::CreateBinaryOperation(BinaryOperator op, Value v0, Value v1,
+ Context* context) {
+ static int (pcc::BooleanType::*operations[ToUnderlying(
+ BinaryOperator::OPERATOR_NUMBER)])(Value, Value, Context*) = {
+ &BooleanType::NotAllowed, &BooleanType::NotAllowed,
+ &BooleanType::NotAllowed, &BooleanType::NotAllowed,
+ &BooleanType::NotAllowed, &BooleanType::NotAllowed,
+ &BooleanType::NotAllowed, &BooleanType::NotAllowed,
+ &BooleanType::NotAllowed, &BooleanType::CreateEq,
+ &BooleanType::CreateNe, &BooleanType::CreateAnd,
+ &BooleanType::CreateOr, &BooleanType::CreateXor,
+ &BooleanType::NotAllowed,
+ };
+ return (this->*operations[ToUnderlying(op)])(v0, v1, context);
+}
+
+CharType::CharType()
+ : Type("char", true, 8) {}
+
+int CharType::CreateBinaryOperation(BinaryOperator op, Value v0, Value v1,
+ Context* context) {
+ static int (pcc::CharType::*operations[ToUnderlying(
+ BinaryOperator::OPERATOR_NUMBER)])(Value, Value, Context*) = {
+ &CharType::CreateAdd, &CharType::CreateSub, &CharType::CreateMul,
+ &CharType::CreateDiv, &CharType::CreateMod, &CharType::CreateLt,
+ &CharType::CreateLe, &CharType::CreateGt, &CharType::CreateGe,
+ &CharType::CreateEq, &CharType::CreateNe, &CharType::CreateAnd,
+ &CharType::CreateOr, &CharType::CreateXor, &CharType::NotAllowed};
+ return (this->*operations[ToUnderlying(op)])(v0, v1, context);
+}
+
+IntegerType::IntegerType()
+ : Type("integer", true, 32) {}
+
+int IntegerType::CreateBinaryOperation(BinaryOperator op, Value v0, Value v1,
+ Context* context) {
+ static int (pcc::IntegerType::*operations[ToUnderlying(
+ BinaryOperator::OPERATOR_NUMBER)])(Value, Value, Context*) = {
+ &IntegerType::CreateAdd, &IntegerType::CreateSub,
+ &IntegerType::CreateMul, &IntegerType::CreateDiv,
+ &IntegerType::CreateMod, &IntegerType::CreateLt,
+ &IntegerType::CreateLe, &IntegerType::CreateGt,
+ &IntegerType::CreateGe, &IntegerType::CreateEq,
+ &IntegerType::CreateNe, &IntegerType::CreateAnd,
+ &IntegerType::CreateOr, &IntegerType::CreateXor,
+ &IntegerType::NotAllowed};
+ return (this->*operations[ToUnderlying(op)])(v0, v1, context);
+}
+
+RealType::RealType()
+ : Type("real", true, 32) {}
+
+int RealType::CreateBinaryOperation(BinaryOperator op, Value v0, Value v1,
+ Context* context) {
+ static int (pcc::RealType::*operations[ToUnderlying(
+ BinaryOperator::OPERATOR_NUMBER)])(Value, Value, Context*) = {
+ &RealType::CreateFAdd, &RealType::CreateFSub, &RealType::CreateFMul,
+ &RealType::CreateFDiv, &RealType::CreateFMod, &RealType::CreateFLt,
+ &RealType::CreateFLe, &RealType::CreateFGt, &RealType::CreateFGe,
+ &RealType::CreateFEq, &RealType::CreateFNe, &RealType::NotAllowed,
+ &RealType::NotAllowed, &RealType::NotAllowed, &RealType::NotAllowed};
+ return (this->*operations[ToUnderlying(op)])(v0, v1, context);
+}
+
+} // namespace pcc \ No newline at end of file
diff --git a/Type.hh b/Type.hh
new file mode 100644
index 0000000..0bc889d
--- /dev/null
+++ b/Type.hh
@@ -0,0 +1,108 @@
+#ifndef PCC_TYPE_H
+#define PCC_TYPE_H
+
+#include <memory>
+#include <string>
+#include <vector>
+
+#include "Context.hh"
+
+namespace pcc {
+enum class BinaryOperator {
+ ADD,
+ SUB,
+ MUL,
+ DIV,
+ MOD,
+ LT,
+ LE,
+ GT,
+ GE,
+ EQ,
+ NE,
+ AND,
+ OR,
+ XOR,
+ ARRAY_ACCESS,
+ OPERATOR_NUMBER
+};
+
+template <typename T>
+constexpr std::underlying_type_t<T> ToUnderlying(T value) {
+ return static_cast<std::underlying_type_t<T>>(value);
+}
+
+class Type {
+ public:
+ Type(const char* name, bool IsBasicType, int width);
+ virtual const char* GetCommonName();
+
+ // return -1 if the operation is not supported
+ virtual int CreateBinaryOperation(BinaryOperator op, Value v0, Value v1,
+ Context* context);
+
+ protected:
+ int NotAllowed(Value v0, Value v1, Context* context);
+
+ int CreateAdd(Value v0, Value v1, Context* context);
+ int CreateSub(Value v0, Value v1, Context* context);
+ int CreateMul(Value v0, Value v1, Context* context);
+ int CreateDiv(Value v0, Value v1, Context* context);
+ int CreateMod(Value v0, Value v1, Context* context);
+ int CreateLt(Value v0, Value v1, Context* context);
+ int CreateLe(Value v0, Value v1, Context* context);
+ int CreateGt(Value v0, Value v1, Context* context);
+ int CreateGe(Value v0, Value v1, Context* context);
+ int CreateEq(Value v0, Value v1, Context* context);
+ int CreateNe(Value v0, Value v1, Context* context);
+ int CreateAnd(Value v0, Value v1, Context* context);
+ int CreateOr(Value v0, Value v1, Context* context);
+ int CreateXor(Value v0, Value v1, Context* context);
+ int CreateFAdd(Value v0, Value v1, Context* context);
+ int CreateFSub(Value v0, Value v1, Context* context);
+ int CreateFMul(Value v0, Value v1, Context* context);
+ int CreateFDiv(Value v0, Value v1, Context* context);
+ int CreateFMod(Value v0, Value v1, Context* context);
+ int CreateFLt(Value v0, Value v1, Context* context);
+ int CreateFLe(Value v0, Value v1, Context* context);
+ int CreateFGt(Value v0, Value v1, Context* context);
+ int CreateFGe(Value v0, Value v1, Context* context);
+ int CreateFEq(Value v0, Value v1, Context* context);
+ int CreateFNe(Value v0, Value v1, Context* context);
+ int CreateArrayAccess(Value v0, Value v1, Context* context);
+ const char* name_;
+ bool IsBasicType_;
+ int width_;
+};
+
+class BooleanType : public Type {
+ public:
+ BooleanType();
+ virtual int CreateBinaryOperation(BinaryOperator op, Value v0, Value v1,
+ Context* context) override;
+};
+
+class CharType : public Type {
+ public:
+ CharType();
+ virtual int CreateBinaryOperation(BinaryOperator op, Value v0, Value v1,
+ Context* context) override;
+};
+
+class IntegerType : public Type {
+ public:
+ IntegerType();
+ virtual int CreateBinaryOperation(BinaryOperator op, Value v0, Value v1,
+ Context* context) override;
+};
+
+class RealType : public Type {
+ public:
+ RealType();
+ virtual int CreateBinaryOperation(BinaryOperator op, Value v0, Value v1,
+ Context* context) override;
+};
+
+} // namespace pcc
+
+#endif // PCC_TYPE_H
diff --git a/TypeManager.cc b/TypeManager.cc
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/TypeManager.cc
diff --git a/TypeManager.hh b/TypeManager.hh
new file mode 100644
index 0000000..248a53a
--- /dev/null
+++ b/TypeManager.hh
@@ -0,0 +1,16 @@
+#ifndef PCC_TYPEMANAGER_H
+#define PCC_TYPEMANAGER_H
+
+#include "Type.hh"
+
+namespace pcc {
+class TypeManager {
+ public:
+ TypeManager();
+
+ private:
+ std::vector<std::shared_ptr<Type>> types_;
+};
+} // namespace pcc
+
+#endif // !PCC_TYPEMANAGER_H
diff --git a/main.cc b/main.cc
index 25a1b65..e538e45 100644
--- a/main.cc
+++ b/main.cc
@@ -32,11 +32,10 @@ int main(int argc, char* argv[]) {
return 0;
}
for (int i = optind; i < argc; i++) {
- pcc::Context context(argv[i]);
- pcc::Driver driver(&context);
+ pcc::Driver driver(argv[i]);
std::string filename(argv[i]);
driver.Parse(filename);
}
-
+
return 0;
}
diff --git a/node/BaseNode.cc b/node/BaseNode.cc
index de38f55..8fe2c5d 100644
--- a/node/BaseNode.cc
+++ b/node/BaseNode.cc
@@ -1,6 +1,6 @@
#include "Node.hh"
namespace pcc {
-BaseNode::BaseNode(Driver* driver)
- : driver_(driver) {}
+BaseNode::BaseNode(Context* context)
+ : context_(context) {}
} // namespace pcc
diff --git a/node/BaseNode.hh b/node/BaseNode.hh
index 60e25bd..4a3746c 100644
--- a/node/BaseNode.hh
+++ b/node/BaseNode.hh
@@ -3,17 +3,16 @@
#include <llvm/IR/Value.h>
-namespace pcc {
-using Value = llvm::Value*;
-class Driver;
+#include "Context.hh"
+namespace pcc {
class BaseNode {
public:
virtual Value CodeGen() = 0;
- BaseNode(Driver* driver);
+ BaseNode(Context* context);
protected:
- Driver* driver_;
+ Context* context_;
};
} // namespace pcc
diff --git a/node/ExpressionNode.hh b/node/ExpressionNode.hh
new file mode 100644
index 0000000..ad31835
--- /dev/null
+++ b/node/ExpressionNode.hh
@@ -0,0 +1,8 @@
+#ifndef PCC_EXPRESSIONNODE_H
+#define PCC_EXPRESSIONNODE_H
+
+#include "BaseNode.hh"
+
+
+
+#endif
diff --git a/node/LiteralNode.cc b/node/LiteralNode.cc
index 1e9c4b7..fedeb36 100644
--- a/node/LiteralNode.cc
+++ b/node/LiteralNode.cc
@@ -6,7 +6,7 @@
namespace pcc {
template <> Value BooleanLiteralNode::CodeGen() {
- llvm::LLVMContext& context = driver_->GetModule()->getContext();
+ llvm::LLVMContext& context = context_->GetModule()->getContext();
if (value_ == true) {
return llvm::ConstantInt::getTrue(context);
} else {
@@ -15,19 +15,19 @@ template <> Value BooleanLiteralNode::CodeGen() {
}
template <> Value IntegerLiteralNode::CodeGen() {
- llvm::LLVMContext& context = driver_->GetModule()->getContext();
+ llvm::LLVMContext& context = context_->GetModule()->getContext();
llvm::APInt value(32, (uint64_t) value_, true);
return llvm::ConstantInt::get(context, value);
}
template <> Value RealLiteralNode::CodeGen() {
- llvm::LLVMContext& context = driver_->GetModule()->getContext();
+ llvm::LLVMContext& context = context_->GetModule()->getContext();
llvm::APFloat value(value_);
return llvm::ConstantFP::get(context, value);
}
template <> Value StringLiteralNode::CodeGen() {
- llvm::Module* module = driver_->GetModule();
+ llvm::Module* module = context_->GetModule();
llvm::LLVMContext& context = module->getContext();
llvm::Constant* str = llvm::ConstantDataArray::getString(context, value_);
llvm::Type* type = str->getType();
diff --git a/node/LiteralNode.hh b/node/LiteralNode.hh
index 1d5c1b8..7c74f27 100644
--- a/node/LiteralNode.hh
+++ b/node/LiteralNode.hh
@@ -9,7 +9,7 @@ namespace pcc {
template <typename Type, typename Construct = Type>
class LiteralNode : public BaseNode {
public:
- LiteralNode(Driver* driver, Construct value);
+ LiteralNode(Context* context, Construct value);
Value CodeGen() override; // type-specific CodeGen() is in the .cc file.
private:
@@ -17,9 +17,8 @@ class LiteralNode : public BaseNode {
};
template <typename Type, typename Construct>
-LiteralNode<Type, Construct>::LiteralNode(Driver* driver,
- Construct value)
- : BaseNode(driver)
+LiteralNode<Type, Construct>::LiteralNode(Context* context, Construct value)
+ : BaseNode(context)
, value_(value) {}
using BooleanLiteralNode = LiteralNode<bool>;
diff --git a/getopt.c b/win32/getopt.c
index b5eebdf..b5eebdf 100644
--- a/getopt.c
+++ b/win32/getopt.c
diff --git a/getopt.h b/win32/getopt.h
index 03f769f..03f769f 100644
--- a/getopt.h
+++ b/win32/getopt.h