summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Driver.cc9
-rw-r--r--Driver.hh6
-rw-r--r--Parser.y44
-rw-r--r--Type.cc7
-rw-r--r--TypeManager.cc6
-rw-r--r--main.cc8
-rw-r--r--node/BaseNode.cc19
-rw-r--r--node/BaseNode.hh15
-rw-r--r--node/ExprNode.cc1
-rw-r--r--node/FunctionNode.cc10
-rw-r--r--t/1.pas18
11 files changed, 99 insertions, 44 deletions
diff --git a/Driver.cc b/Driver.cc
index 6d557db..a3db940 100644
--- a/Driver.cc
+++ b/Driver.cc
@@ -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
diff --git a/Driver.hh b/Driver.hh
index d3e773d..2fdc86d 100644
--- a/Driver.hh
+++ b/Driver.hh
@@ -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
diff --git a/Parser.y b/Parser.y
index 74827ba..d989651 100644
--- a/Parser.y
+++ b/Parser.y
@@ -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;}
diff --git a/Type.cc b/Type.cc
index a661fde..891168d 100644
--- a/Type.cc
+++ b/Type.cc
@@ -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
diff --git a/main.cc b/main.cc
index e538e45..0db215b 100644
--- a/main.cc
+++ b/main.cc
@@ -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;
}
diff --git a/t/1.pas b/t/1.pas
index 0275bbf..ece501e 100644
--- a/t/1.pas
+++ b/t/1.pas
@@ -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;