diff options
| -rw-r--r-- | Driver.cc | 9 | ||||
| -rw-r--r-- | Driver.hh | 6 | ||||
| -rw-r--r-- | Parser.y | 44 | ||||
| -rw-r--r-- | Type.cc | 7 | ||||
| -rw-r--r-- | TypeManager.cc | 6 | ||||
| -rw-r--r-- | main.cc | 8 | ||||
| -rw-r--r-- | node/BaseNode.cc | 19 | ||||
| -rw-r--r-- | node/BaseNode.hh | 15 | ||||
| -rw-r--r-- | node/ExprNode.cc | 1 | ||||
| -rw-r--r-- | node/FunctionNode.cc | 10 | ||||
| -rw-r--r-- | t/1.pas | 18 |
11 files changed, 99 insertions, 44 deletions
@@ -7,13 +7,18 @@ Driver::Driver(const char* name) Driver::~Driver() {} -void Driver::Parse(std::string& filename) { +std::shared_ptr<ProgramNode> Driver::Parse(std::string& filename) { location_.initialize(&filename); if (StartLexer(filename) != 0) { - return; + return nullptr; } Parser parser(*this, &context_); parser.parse(); StopLexer(); + return root_; } + +void Driver::SetRoot(std::shared_ptr<ProgramNode> root) { root_ = root; } + +Context* Driver::GetContext() { return &context_; } } // namespace pcc @@ -3,6 +3,7 @@ #include <cstdio> +#include "BaseNode.hh" #include "Context.hh" #include "Location.hh" @@ -13,11 +14,14 @@ class Driver { ~Driver(); int StartLexer(std::string& filename); void StopLexer(); - void Parse(std::string& filename); + std::shared_ptr<ProgramNode> Parse(std::string& filename); + void SetRoot(std::shared_ptr<ProgramNode> root); + Context* GetContext(); Location location_; private: Context context_; + std::shared_ptr<ProgramNode> root_; }; } // namespace pcc @@ -20,6 +20,8 @@ namespace pcc{ %param {pcc::Context* ctx} %code{ +#include "Driver.hh" + #define YY_DECL \ pcc::Parser::symbol_type yylex(pcc::Driver& driver, pcc::Context* ctx) @@ -42,7 +44,7 @@ YY_DECL; %token AND NOT OR XOR %token INTEGER_LITERAL REAL_LITERAL STRING_LITERAL BOOLEAN_LITERAL CHAR_LITERAL -%type <std::string> IDENTIFIER +%type <std::string> IDENTIFIER program_header %type <std::shared_ptr<pcc::Type>> type %type <std::list<Declaration>> var_decls %type <std::pair<std::list<std::string>, std::shared_ptr<pcc::Type>>> var_decl @@ -54,13 +56,16 @@ YY_DECL; %type <std::shared_ptr<pcc::RealLiteralNode>> REAL_LITERAL %type <std::shared_ptr<pcc::StringLiteralNode>> STRING_LITERAL %type <std::shared_ptr<pcc::ExprNode>> literal lvalue +%type <std::list<std::shared_ptr<pcc::ExprNode>>> arguments +%type <std::shared_ptr<pcc::FunctionCallNode>> function_call %type <std::shared_ptr<pcc::ExprNode>> expression l1_expression l2_expression l3_expression %type <pcc::BinaryOperator> l1_operator l2_operator l3_operator %type <pcc::UnaryOperator> l4_operator +%type <std::list<std::shared_ptr<pcc::FunctionNode>>> functions %type <std::shared_ptr<pcc::FunctionNode>> function -%type <std::list<std::shared_ptr<pcc::BaseNode>>> local_decls -%type <std::shared_ptr<pcc::BaseNode>> local_decl +%type <std::list<std::shared_ptr<pcc::BaseNode>>> local_decls global_decls +%type <std::shared_ptr<pcc::BaseNode>> local_decl global_decl %type <std::shared_ptr<pcc::StatementListNode>> statements statement_block %type <std::shared_ptr<pcc::BaseNode>> statement open_statement closed_statement normal_statement @@ -72,36 +77,36 @@ YY_DECL; /* ==================[global part]================== */ program - : program_header global_decls functions + : program_header global_decls functions FILE_END {driver.SetRoot(std::make_shared<pcc::ProgramNode>(ctx, $1, $2, $3));} ; program_header - : PROGRAM IDENTIFIER SEMICOLON + : PROGRAM IDENTIFIER SEMICOLON {$$=$2;} ; global_decls - : global_decls global_decl SEMICOLON - | + : global_decls global_decl {$$=$1; $$.push_back($2);} + | {$$=std::list<std::shared_ptr<pcc::BaseNode>>();} ; global_decl - : VAR var_decls + : VAR var_decls {$$=std::make_shared<pcc::VarDeclNode>(ctx, nullptr, $2);} ; functions - : functions function SEMICOLON - | + : functions function SEMICOLON {$$=$1; $$.push_back($2);} + | {$$=std::list<std::shared_ptr<pcc::FunctionNode>>();} ; /* ==================[var part]================== */ var_decls - : var_decls SEMICOLON var_decl {$$=$1; auto NewChilds=std::get<0>($3); for(auto& name: NewChilds){$$.push_back({name, std::get<1>($3)});}} - | var_decl {auto NewChilds=std::get<0>($1); for(auto& name: NewChilds){$$.push_back({name, std::get<1>($1)});}} + : var_decls var_decl {$$=$1; auto NewChilds=std::get<0>($2); for(auto& name: NewChilds){$$.push_back({name, std::get<1>($2)});}} + | var_decl {auto NewChilds=std::get<0>($1); for(auto& name: NewChilds){$$.push_back({name, std::get<1>($1)});}} ; var_decl - : vars COLON type {$$={$1,$3};} + : vars COLON type SEMICOLON {$$={$1,$3};} ; vars @@ -126,7 +131,7 @@ function local_decls : local_decls local_decl {$$=$1; $$.push_back($2);} - | + | {$$=std::list<std::shared_ptr<pcc::BaseNode>>();} ; local_decl @@ -195,7 +200,7 @@ l2_expression l3_expression : lvalue {$$=std::make_shared<pcc::L2RCastingNode>(ctx, $1);} - | function_call + | function_call {$$=$1;} | literal {$$=$1;} | LPARENTHESIS expression RPARENTHESIS {$$=$2;} | l4_operator l3_expression {$$=std::make_shared<pcc::UnaryExprNode>(ctx,$1,$2);} @@ -237,17 +242,18 @@ lvalue ; function_call - : IDENTIFIER LPARENTHESIS arguments RPARENTHESIS - | IDENTIFIER LPARENTHESIS RPARENTHESIS + : IDENTIFIER LPARENTHESIS arguments RPARENTHESIS {$$=std::make_shared<pcc::FunctionCallNode>(ctx, $1, $3);} + | IDENTIFIER LPARENTHESIS RPARENTHESIS {$$=std::make_shared<pcc::FunctionCallNode>(ctx, $1, std::list<std::shared_ptr<pcc::ExprNode>>());} ; arguments - : arguments COMMA expression - | expression + : arguments COMMA expression {$$=$1; $$.push_back($3);} + | expression {$$.push_back($1);} ; literal : BOOLEAN_LITERAL {$$=$1;} + | CHAR_LITERAL {$$=$1;} | INTEGER_LITERAL {$$=$1;} | REAL_LITERAL {$$=$1;} | STRING_LITERAL {$$=$1;} @@ -339,10 +339,9 @@ FunctionType::FunctionType(std::shared_ptr<Type> ReturnType, , ReturnType_(ReturnType) , ArgTypes_(ArgTypes) { std::vector<llvm::Type*> params(ArgTypes_.size()); - std::transform(ArgTypes_.cbegin(), ArgTypes_.cend(), params.begin(), - [](const Declaration& decl) { - return std::get<1>(decl)->GetLLVMType(); - }); + std::transform( + ArgTypes_.cbegin(), ArgTypes_.cend(), params.begin(), + [](std::shared_ptr<Type> decl) { return decl->GetLLVMType(); }); LLVMType_ = llvm::FunctionType::get(ReturnType_->GetLLVMType(), params, false); } diff --git a/TypeManager.cc b/TypeManager.cc index 7481032..c721df8 100644 --- a/TypeManager.cc +++ b/TypeManager.cc @@ -190,8 +190,10 @@ std::shared_ptr<FunctionType> TypeManager::CreateFunctionType( name.append((*ArgIt)->GetCommonName()); } } - types_.push_back(std::make_shared<FunctionType>( - ReturnType, ArgTypes, ReturnType->GetCommonName() + name + ")")); + std::shared_ptr<FunctionType> NewType = std::make_shared<FunctionType>( + ReturnType, ArgTypes, ReturnType->GetCommonName() + name + ")"); + types_.push_back(NewType); + return NewType; } } // namespace pcc @@ -6,6 +6,8 @@ #include <unistd.h> #endif +#include <llvm/Support/raw_ostream.h> + #include "Driver.hh" #include "Log.hh" #include "Version.hh" @@ -34,7 +36,11 @@ int main(int argc, char* argv[]) { for (int i = optind; i < argc; i++) { pcc::Driver driver(argv[i]); std::string filename(argv[i]); - driver.Parse(filename); + std::shared_ptr<pcc::ProgramNode> root = driver.Parse(filename); + if (root != nullptr) { + root->CodeGen(); + } + driver.GetContext()->GetModule()->print(llvm::errs(), nullptr); } return 0; diff --git a/node/BaseNode.cc b/node/BaseNode.cc index 8fe2c5d..4b1166b 100644 --- a/node/BaseNode.cc +++ b/node/BaseNode.cc @@ -3,4 +3,23 @@ namespace pcc { BaseNode::BaseNode(Context* context) : context_(context) {} + +ProgramNode::ProgramNode( + Context* context, const std::string& name, + std::list<std::shared_ptr<BaseNode>> GlobalDeclarations, + std::list<std::shared_ptr<FunctionNode>> functions) + : BaseNode(context) + , name_(name) + , GlobalDeclarations_(GlobalDeclarations) + , functions_(functions) {} + +Value ProgramNode::CodeGen() { + for (auto decl : GlobalDeclarations_) { + decl->CodeGen(); + } + for (auto function : functions_) { + function->CodeGen(); + } + return nullptr; +} } // namespace pcc diff --git a/node/BaseNode.hh b/node/BaseNode.hh index 16ee82d..71b0925 100644 --- a/node/BaseNode.hh +++ b/node/BaseNode.hh @@ -25,6 +25,21 @@ template <typename T, class Base = BaseNode> class ListNode : public Base { private: std::list<T> childs_; }; + +class FunctionNode; + +class ProgramNode : public BaseNode { + public: + ProgramNode(Context* context, const std::string& name, + std::list<std::shared_ptr<BaseNode>> GlobalDeclarations, + std::list<std::shared_ptr<FunctionNode>> functions); + virtual Value CodeGen() override; + + protected: + std::string name_; + std::list<std::shared_ptr<BaseNode>> GlobalDeclarations_; + std::list<std::shared_ptr<FunctionNode>> functions_; +}; } // namespace pcc #endif diff --git a/node/ExprNode.cc b/node/ExprNode.cc index e7ef2aa..6127f6f 100644 --- a/node/ExprNode.cc +++ b/node/ExprNode.cc @@ -51,6 +51,7 @@ Value UnaryExprNode::CodeGen() { if (result == nullptr) { Log(LogLevel::PCC_ERROR, "failed to generate a unary operation"); } + type_ = value_->GetType(); return result; } diff --git a/node/FunctionNode.cc b/node/FunctionNode.cc index dfb7eff..e22c8b6 100644 --- a/node/FunctionNode.cc +++ b/node/FunctionNode.cc @@ -2,9 +2,11 @@ #include <vector> #include <llvm/IR/IRBuilder.h> +#include <llvm/IR/Verifier.h> #include "DeclNode.hh" #include "FunctionNode.hh" +#include "Log.hh" namespace pcc { FunctionNode::FunctionNode( @@ -34,7 +36,7 @@ Value FunctionNode::CodeGen() { std::vector<std::shared_ptr<Type>> params(arguments_.size()); std::transform(arguments_.cbegin(), arguments_.cend(), params.begin(), [](const Declaration& decl) { return std::get<1>(decl); }); - std::shared_ptr<Type> type = + std::shared_ptr<FunctionType> type = context_->GetTypeManager()->CreateFunctionType(type_, params); context_->AddFunctionType(name_, type); llvm::FunctionType* LLVMType = @@ -46,7 +48,7 @@ Value FunctionNode::CodeGen() { llvm::BasicBlock::Create(GlobalLLVMContext, name_, function); builder->SetInsertPoint(block); // alloc arguments - llvm::Function::arg_iterator ArgIt; + llvm::Function::arg_iterator ArgIt = function->arg_begin(); for (auto& arg : arguments_) { Value ArgValue = builder->CreateAlloca(std::get<1>(arg)->GetLLVMType()); builder->CreateStore(ArgIt++, ArgValue); @@ -64,6 +66,10 @@ Value FunctionNode::CodeGen() { body_->CodeGen(); builder->CreateRet(rv); context_->PopScope(); + std::string msg; + llvm::raw_string_ostream MsgStream(msg); + llvm::verifyFunction(*function, &MsgStream); + Log(LogLevel::PCC_INFO, "%s", msg.c_str()); return nullptr; } @@ -1,17 +1,9 @@ program a; -VAR - f : integer; - g : real; - h : boolean; - j : integer; -function test(a:integer;b:string):char; -var s1:real; +function test(a:integer;b:char;c:real;):integer; begin - f:=b; - g:=c; - if g<=c then - h:=ture - else - h:=false; + a:=1; + b:='a'; + c:=3.5; + test:=6; end; |
