diff options
| author | Nagi5Yeq <wu@x-nagi.com> | 2020-05-27 02:08:29 +0800 |
|---|---|---|
| committer | Nagi5Yeq <wu@x-nagi.com> | 2020-05-27 02:08:29 +0800 |
| commit | ba1e3fdd1eea618a38e56918912dc966d1e399a8 (patch) | |
| tree | 0abf1bf045529cc20da9312cbabe32ded31a0103 | |
| parent | e83990754f49ec6eba7b9e1a5ff80a6add5de3a1 (diff) | |
fix array, string, and constant nodes
| -rw-r--r-- | Lexer.hh | 47 | ||||
| -rw-r--r-- | Lexer.l | 16 | ||||
| -rw-r--r-- | Parser.y | 34 | ||||
| -rw-r--r-- | Type.cc | 4 | ||||
| -rw-r--r-- | node/DeclNode.cc | 4 | ||||
| -rw-r--r-- | node/FunctionNode.cc | 7 | ||||
| -rw-r--r-- | node/LiteralNode.cc | 10 | ||||
| -rw-r--r-- | node/LiteralNode.hh | 4 | ||||
| -rw-r--r-- | t/1.pas | 11 |
9 files changed, 54 insertions, 83 deletions
@@ -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 @@ -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} { @@ -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()); } } @@ -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: @@ -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; |
