summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNagi5Yeq <wu@x-nagi.com>2020-05-27 02:08:29 +0800
committerNagi5Yeq <wu@x-nagi.com>2020-05-27 02:08:29 +0800
commitba1e3fdd1eea618a38e56918912dc966d1e399a8 (patch)
tree0abf1bf045529cc20da9312cbabe32ded31a0103
parente83990754f49ec6eba7b9e1a5ff80a6add5de3a1 (diff)
fix array, string, and constant nodes
-rw-r--r--Lexer.hh47
-rw-r--r--Lexer.l16
-rw-r--r--Parser.y34
-rw-r--r--Type.cc4
-rw-r--r--node/DeclNode.cc4
-rw-r--r--node/FunctionNode.cc7
-rw-r--r--node/LiteralNode.cc10
-rw-r--r--node/LiteralNode.hh4
-rw-r--r--t/1.pas11
9 files changed, 54 insertions, 83 deletions
diff --git a/Lexer.hh b/Lexer.hh
index 86e8480..43400a8 100644
--- a/Lexer.hh
+++ b/Lexer.hh
@@ -51,53 +51,6 @@ char* GetUnescapedChar(char* s, char* end, char* out) {
return s + 2;
}
}
-
-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>(
- context,
- context->GetTypeManager()->GetBuiltinType(BuiltinType::BOOLEAN), b),
- loc);
-}
-
-Parser::symbol_type make_CHAR_LITERAL(char c, pcc::Context* context,
- const Parser::location_type& loc) {
- return Parser::make_CHAR_LITERAL(
- std::make_shared<CharLiteralNode>(
- context,
- context->GetTypeManager()->GetBuiltinType(BuiltinType::CHAR), c),
- loc);
-}
-
-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>(
- context,
- context->GetTypeManager()->GetBuiltinType(BuiltinType::INTEGER), v),
- loc);
-}
-
-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>(
- context,
- context->GetTypeManager()->GetBuiltinType(BuiltinType::REAL), v),
- loc);
-}
-
-Parser::symbol_type make_STRING_LITERAL(char* begin, char* end,
- pcc::Context* context,
- const Parser::location_type& loc) {
- return Parser::make_STRING_LITERAL(
- std::make_shared<StringLiteralNode>(
- context,
- context->GetTypeManager()->GetBuiltinType(BuiltinType::STRING),
- begin, end),
- loc);
-}
} // namespace Lexer
} // namespace pcc
diff --git a/Lexer.l b/Lexer.l
index 6d6204e..66a3e37 100644
--- a/Lexer.l
+++ b/Lexer.l
@@ -30,12 +30,12 @@ decimal ([1-9][0-9]*)|0
octal 0[0-7]*
hexadecimal 0[xX][0-9a-fA-F]
-integer [+-]?({decimal}|{octal}|{hexadecimal})
+integer {decimal}|{octal}|{hexadecimal}
real_exp [0-9]*(\.[0-9]*)?[eE]{decimal}
real_noexp [0-9]*\.[0-9]*
-real [+-]?({real_exp}|{real_noexp})
+real {real_exp}|{real_noexp}
trival_char [0-9a-zA-Z_{}[\]#()<>%:;.?*+\-/^&|~!=,\\" \t\n\v\f]
escaped_char \\[\'?\\abfnrtv]
@@ -106,17 +106,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, context, loc);}
-"false" {return pcc::Lexer::make_BOOLEAN_LITERAL(false, context, loc);}
+"true" {return Parser::make_BOOLEAN_LITERAL(true, loc);}
+"false" {return Parser::make_BOOLEAN_LITERAL(false, loc);}
{integer} {
int number = std::strtol(yytext, NULL, 0);
- return pcc::Lexer::make_INTEGER_LITERAL(number, context, loc);
+ return Parser::make_INTEGER_LITERAL(number, loc);
}
{real} {
float number = std::strtof(yytext, NULL);
- return pcc::Lexer::make_REAL_LITERAL(number, context, loc);
+ return Parser::make_REAL_LITERAL(number, loc);
}
{char} {
@@ -124,7 +124,7 @@ white [\t\f\r ]
s = yytext + 1;
end = s + yyleng - 2;
pcc::Lexer::GetUnescapedChar(s, end, &c);
- return pcc::Lexer::make_CHAR_LITERAL(c, context, loc);
+ return Parser::make_CHAR_LITERAL(c, loc);
}
{string} {
@@ -136,7 +136,7 @@ white [\t\f\r ]
p++;
}
*p++ = '\0';
- return pcc::Lexer::make_STRING_LITERAL(yytext + 1, p, context, loc);
+ return Parser::make_STRING_LITERAL(std::vector<char>(yytext + 1, p), loc);
}
{identifier} {
diff --git a/Parser.y b/Parser.y
index d989651..543e70b 100644
--- a/Parser.y
+++ b/Parser.y
@@ -20,7 +20,10 @@ namespace pcc{
%param {pcc::Context* ctx}
%code{
+#include <sstream>
+
#include "Driver.hh"
+#include "Log.hh"
#define YY_DECL \
pcc::Parser::symbol_type yylex(pcc::Driver& driver, pcc::Context* ctx)
@@ -36,8 +39,9 @@ YY_DECL;
%define parse.error verbose
%define parse.assert
+%token FILE_END 0;
%token COLON SEMICOLON COMMA DOT ASSIGN LBRACKET RBRACKET LPARENTHESIS RPARENTHESIS
-%token PROGRAM IDENTIFIER CONST VAR BEGINS ENDS FUNCTION FILE_END
+%token PROGRAM IDENTIFIER CONST VAR BEGINS ENDS FUNCTION
%token IF THEN ELSE WHILE DO
%token BOOLEAN CHAR INTEGER REAL STRING
%token ADD SUB MUL REAL_DIV DIV MOD LT LE GT GE EQ NE
@@ -50,11 +54,11 @@ YY_DECL;
%type <std::pair<std::list<std::string>, std::shared_ptr<pcc::Type>>> var_decl
%type <std::list<std::string>> vars
-%type <std::shared_ptr<pcc::BooleanLiteralNode>> BOOLEAN_LITERAL
-%type <std::shared_ptr<pcc::CharLiteralNode>> CHAR_LITERAL
-%type <std::shared_ptr<pcc::IntegerLiteralNode>> INTEGER_LITERAL
-%type <std::shared_ptr<pcc::RealLiteralNode>> REAL_LITERAL
-%type <std::shared_ptr<pcc::StringLiteralNode>> STRING_LITERAL
+%type <bool> BOOLEAN_LITERAL
+%type <char> CHAR_LITERAL
+%type <int> INTEGER_LITERAL
+%type <float> REAL_LITERAL
+%type <std::vector<char>> 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
@@ -237,8 +241,8 @@ l4_operator
lvalue
: IDENTIFIER {$$=std::make_shared<pcc::IdentifierNode>(ctx, $1);}
- | IDENTIFIER LBRACKET expression RBRACKET {$$=std::make_shared<pcc::BinaryExprNode>(ctx, pcc::BinaryOperator::ARRAY_ACCESS, std::make_shared<pcc::IdentifierNode>(ctx, $1), $3);}
- | IDENTIFIER DOT IDENTIFIER
+ | expression LBRACKET expression RBRACKET {$$=std::make_shared<pcc::BinaryExprNode>(ctx, pcc::BinaryOperator::ARRAY_ACCESS, $1, $3);}
+ | expression DOT IDENTIFIER
;
function_call
@@ -252,11 +256,11 @@ arguments
;
literal
- : BOOLEAN_LITERAL {$$=$1;}
- | CHAR_LITERAL {$$=$1;}
- | INTEGER_LITERAL {$$=$1;}
- | REAL_LITERAL {$$=$1;}
- | STRING_LITERAL {$$=$1;}
+ : BOOLEAN_LITERAL {$$=std::make_shared<pcc::BooleanLiteralNode>(ctx, ctx->GetTypeManager()->GetBuiltinType(BuiltinType::BOOLEAN), $1);}
+ | CHAR_LITERAL {$$=std::make_shared<pcc::CharLiteralNode>(ctx, ctx->GetTypeManager()->GetBuiltinType(BuiltinType::CHAR), $1);}
+ | INTEGER_LITERAL {$$=std::make_shared<pcc::IntegerLiteralNode>(ctx, ctx->GetTypeManager()->GetBuiltinType(BuiltinType::INTEGER), $1);}
+ | REAL_LITERAL {$$=std::make_shared<pcc::RealLiteralNode>(ctx, ctx->GetTypeManager()->GetBuiltinType(BuiltinType::REAL), $1);}
+ | STRING_LITERAL {$$=std::make_shared<pcc::StringLiteralNode>(ctx, ctx->GetTypeManager()->GetBuiltinType(BuiltinType::STRING), $1);}
;
%%
@@ -265,7 +269,9 @@ namespace pcc {
void Parser::error (const location_type& l, const std::string& m)
{
- std::cerr << l << ":" << m << '\n';
+ std::stringstream loc;
+ loc<<l;
+ Log(LogLevel::PCC_ERROR, "error on %s: %s", loc.str().c_str(), m.c_str());
}
}
diff --git a/Type.cc b/Type.cc
index 891168d..c01f71f 100644
--- a/Type.cc
+++ b/Type.cc
@@ -316,7 +316,7 @@ Value PointerType::CreateBinaryOperation(BinaryOperator op, Value v0, Value v1,
&PointerType::CreateGe, &PointerType::CreateEq,
&PointerType::CreateNe, &PointerType::NotAllowed,
&PointerType::NotAllowed, &PointerType::NotAllowed,
- &PointerType::NotAllowed};
+ &PointerType::CreateArrayAccess};
return (this->*operations[ToUnderlying(op)])(v0, v1, context);
}
@@ -329,7 +329,7 @@ Value PointerType::CreatePointerSub(Value v0, Value v1, Context* context) {
}
Value PointerType::CreateArrayAccess(Value v0, Value v1, Context* context) {
- return context->GetBuilder()->CreateInBoundsGEP(LLVMType_, v0, v1);
+ return context->GetBuilder()->CreateInBoundsGEP(v0, v1);
}
FunctionType::FunctionType(std::shared_ptr<Type> ReturnType,
diff --git a/node/DeclNode.cc b/node/DeclNode.cc
index 63dc848..0fc3b89 100644
--- a/node/DeclNode.cc
+++ b/node/DeclNode.cc
@@ -1,7 +1,7 @@
-#include "DeclNode.hh"
-
#include <llvm/IR/IRBuilder.h>
+#include "DeclNode.hh"
+
namespace pcc {
VarDeclNode::VarDeclNode(Context* context, VariableList* scope,
std::list<Declaration> decls)
diff --git a/node/FunctionNode.cc b/node/FunctionNode.cc
index e22c8b6..6352b5b 100644
--- a/node/FunctionNode.cc
+++ b/node/FunctionNode.cc
@@ -64,12 +64,15 @@ Value FunctionNode::CodeGen() {
// push the function scope variables
context_->PushScope(&locals_);
body_->CodeGen();
- builder->CreateRet(rv);
+ builder->CreateRet(builder->CreateLoad(type_->GetLLVMType(), rv));
context_->PopScope();
std::string msg;
llvm::raw_string_ostream MsgStream(msg);
llvm::verifyFunction(*function, &MsgStream);
- Log(LogLevel::PCC_INFO, "%s", msg.c_str());
+ MsgStream.flush();
+ if (!msg.empty()) {
+ Log(LogLevel::PCC_INFO, "%s", msg.c_str());
+ }
return nullptr;
}
diff --git a/node/LiteralNode.cc b/node/LiteralNode.cc
index 19a2419..c68a219 100644
--- a/node/LiteralNode.cc
+++ b/node/LiteralNode.cc
@@ -27,10 +27,10 @@ template <> Value RealLiteralNode::CodeGen() {
}
StringLiteralNode::StringLiteralNode(Context* context,
- std::shared_ptr<Type> type, char* begin,
- char* end)
+ std::shared_ptr<Type> type,
+ std::vector<char> value)
: ExprNode(context)
- , value_(begin, end) {
+ , value_(value) {
type_ = type;
}
@@ -41,8 +41,8 @@ Value StringLiteralNode::CodeGen() {
llvm::Constant* ConstantString =
llvm::ConstantDataArray::get(GlobalLLVMContext, value_);
llvm::Constant* GlobalString = new llvm::GlobalVariable(
- type_->GetLLVMType(), true, llvm::GlobalValue::PrivateLinkage,
- ConstantString);
+ *context_->GetModule(), ConstantString->getType(), true,
+ llvm::GlobalValue::PrivateLinkage, ConstantString);
Value ZeroIndex =
llvm::ConstantInt::get(pointer->GetIndexType()->GetLLVMType(), 0, true);
return builder->CreateInBoundsGEP(GlobalString, {ZeroIndex, ZeroIndex});
diff --git a/node/LiteralNode.hh b/node/LiteralNode.hh
index b7fcb38..ca12131 100644
--- a/node/LiteralNode.hh
+++ b/node/LiteralNode.hh
@@ -33,8 +33,8 @@ using RealLiteralNode = LiteralNode<float>;
class StringLiteralNode : public ExprNode {
public:
- StringLiteralNode(Context* context, std::shared_ptr<Type> type, char* begin,
- char* end);
+ StringLiteralNode(Context* context, std::shared_ptr<Type> type,
+ std::vector<char> value);
Value CodeGen() override;
private:
diff --git a/t/1.pas b/t/1.pas
index ece501e..0b2228f 100644
--- a/t/1.pas
+++ b/t/1.pas
@@ -1,9 +1,18 @@
program a;
function test(a:integer;b:char;c:real;):integer;
+var
+ d:integer;
+ e:char;
+ f:string;
begin
a:=1;
b:='a';
c:=3.5;
- test:=6;
+ a:=b*(c-b+6)--4;
+ d:=a*a-b-(5+c);
+ e:='\x03';
+ f:='a normal test \'\\\0\023';
+ f[4];
+ test:=e+d;
end;