Skip to content
This repository has been archived by the owner on Nov 24, 2024. It is now read-only.

Commit

Permalink
A lot codegen
Browse files Browse the repository at this point in the history
  • Loading branch information
SaptakBhoumik committed Nov 10, 2021
1 parent bf191bd commit 3b4255e
Show file tree
Hide file tree
Showing 9 changed files with 90 additions and 48 deletions.
4 changes: 1 addition & 3 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,18 +1,16 @@
test
Peregrine/test
**/pycatch
.vscode
/push.bat
/push.sh
.idea
**/output
**.out
**/temp.c
temp.cc
**.exe
*.so
*.o
temp
/Peregrine/peregrine
/objs
*.elf
doctest.h
49 changes: 37 additions & 12 deletions Peregrine/codegen/codegen.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,50 +14,75 @@ Codegen::Codegen(std::string output_filename) {

void Codegen::write(std::string_view code) { m_file << code; }

void Codegen::generate(AstNodePtr ast_node) {
std::string Codegen::generate(AstNodePtr ast_node) {
std::string res;
switch (ast_node->type()) {
case KAstProgram: {
auto node = std::dynamic_pointer_cast<Program>(ast_node);

for (auto& stmt : node->statements()) {
generate(stmt);
res+=generate(stmt)+";\n";
}

break;
}

case KAstInteger: {
auto node = std::dynamic_pointer_cast<IntegerLiteral>(ast_node);
write(node->value());
res+=node->value();
break;
}

case KAstDecimal: {
auto node = std::dynamic_pointer_cast<DecimalLiteral>(ast_node);
write(node->value());
res+=node->value();
break;
}

case KAstBool: {
auto node = std::dynamic_pointer_cast<BoolLiteral>(ast_node);
write((node->value() == "True") ? "true" : "false");
res+=((node->value() == "True") ? "true" : "false");
break;
}

case KAstBinaryOp: {
auto node = std::dynamic_pointer_cast<BinaryOperation>(ast_node);

generate(node->left());
write(node->op());
generate(node->right());

res+="("+generate(node->left())+node->op()+generate(node->right())+")";
break;
}
case KAstBlockStmt:{
auto node = std::dynamic_pointer_cast<BlockStatement>(ast_node);
auto body = node->statements();
for (auto& stmp : body){
res+=generate(stmp)+";\n";
}
break;
}
case KAstIfStmt:{
auto node = std::dynamic_pointer_cast<IfStatement>(ast_node);
res += "if("+generate(node->condition())+"){\n"+generate(node->if_body())+"}";
auto elif_node=node->elifs();
if (elif_node.size()!=0){
res+="\n";
for (auto& body: elif_node){//making sure that elif exists
res+="else if("+generate(body.first)+"){\n"+generate(body.second)+"}";
}
}
auto else_node=node->else_body();
if (else_node->type()==KAstBlockStmt){//making sure that else exists
res+="\nelse{\n"+generate(else_node)+"}";
}
break;
}
case KAstWhileStmt:{
auto node = std::dynamic_pointer_cast<WhileStatement>(ast_node);
res+="while("+generate(node->condition())+"){\n"+generate(node->body())+"}";
break;
}

default: {
std::cerr << fg(style("Error: invalid ast node passed to generate(). This should never happen.", bold), light_red) << "\n";
std::cerr << "This is most likely not an issue with the compiler itself. You can seek help at our discord server: https://discord.gg/CAMgzwDJDM" << "\n";
exit(1);
}
}
return res;
}
5 changes: 2 additions & 3 deletions Peregrine/codegen/codegen.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,11 @@
class Codegen {
std::ofstream m_file;

void write(std::string_view code);

public:
void write(std::string_view code);
Codegen(std::string output_filename);

void generate(AstNodePtr ast_node);
std::string generate(AstNodePtr ast_node);
};

#endif
9 changes: 7 additions & 2 deletions Peregrine/errors/errors.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,11 @@ void display(PEError e) {
std::cout << " |"
<< "\n";
}
std::cout << " ╰- " << fg(style("Hint: ", bold), cyan)
<< "Use peregrine --explain=" << e.ecode << "\n";
if (e.ecode==""){
std::cout << " ╰----------------------------------------- ";
}
else{
std::cout << " ╰- " << fg(style("Hint: ", bold), cyan)
<< "Use peregrine --explain=" << e.ecode << "\n";
}
}
44 changes: 30 additions & 14 deletions Peregrine/lexer/lexer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -246,7 +246,9 @@ LEXEME lexer(std::string src, std::string filename) {
// is that it will reduce the time it takes to run
while (current_index < src.size()) {
item = src.at(current_index);
if (item == "\n"||item == "\r\n"||item == "\r") {
if ((item == "\n"||item == "\r\n"||item == "\r")
&& next(current_index,src)!=""//dont want it to be the end of file
) {
last_line = current_index;
line++;
if (seperate_lines.size() > line - 1) {
Expand Down Expand Up @@ -296,7 +298,7 @@ LEXEME lexer(std::string src, std::string filename) {
previous_identation = 0;
}
}
} else if (item == "\n"||item == "\r\n"||item == "\r") {
} else if (item == "\n"||item == "\r\n"||item == "\r"){
is_tab = true;
curr_identation_level = 0;
}
Expand Down Expand Up @@ -928,13 +930,6 @@ LEXEME lexer(std::string src, std::string filename) {
token_type(keyword, next(current_index - 1, src)),
start_index, current_index, line));
}
curr_identation_level /= 4; // dividing by 4 to know the number of tabs
while (curr_identation_level != 0) {
token = token_init(statement, "", tk_dedent, current_index,
current_index, line);
tokens.emplace_back(token);
curr_identation_level--;
}
if (is_string == true || is_list_dictionary_cpp_string == true) {
std::string temp = "Expecting a "+string_starter;
display(PEError({.loc = Location({.line = line,
Expand All @@ -944,7 +939,7 @@ LEXEME lexer(std::string src, std::string filename) {
.msg = "Unexpected end of file",
.submsg = temp,
.ecode = "e1"}));
tokens.clear();
exit(1);
}
if (is_dictionary == true) {
std::string temp = "Expecting a }";
Expand All @@ -955,7 +950,7 @@ LEXEME lexer(std::string src, std::string filename) {
.msg = "Unexpected end of file",
.submsg = temp,
.ecode = "e1"}));
tokens.clear();
exit(1);
}
if (is_array == true) {
std::string temp = "Expecting a ]";
Expand All @@ -966,7 +961,7 @@ LEXEME lexer(std::string src, std::string filename) {
.msg = "Unexpected end of file",
.submsg = temp,
.ecode = "e1"}));
tokens.clear();
exit(1);
}
if (is_cpp == true) {
std::string temp = "Expecting a )";
Expand All @@ -977,7 +972,7 @@ LEXEME lexer(std::string src, std::string filename) {
.msg = "Unexpected end of file",
.submsg = temp,
.ecode = "e1"}));
tokens.clear();
exit(1);
}
else if (first_bracket_count!=0){
std::string temp = "Expecting a )";
Expand All @@ -988,9 +983,30 @@ LEXEME lexer(std::string src, std::string filename) {
.msg = "Unexpected end of file",
.submsg = temp,
.ecode = "e1"}));
tokens.clear();
exit(1);
}
if (tokens.size() > 0) {
uint64_t total_tab=0;
for (auto tok : tokens){
switch (tok.tk_type) {
case tk_ident:{
total_tab++;
break;
}
case tk_dedent:{
total_tab--;
break;
}
default:{
}
}
}
while (total_tab!=0){
token = token_init(statement, "", tk_dedent, current_index,
current_index, line);
tokens.push_back(token);
total_tab--;
}
tokens.push_back(
token_init("", "", tk_eof, current_index, current_index, line));
}
Expand Down
8 changes: 4 additions & 4 deletions Peregrine/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,9 @@ int main() {

std::cout << program->stringify() << "\n";

Codegen codegen("out.txt");

codegen.generate(program);

Codegen codegen("temp.cc");
auto res=codegen.generate(program);
std::cout<<res<<"\n";
codegen.write(res);
return 0;
}
1 change: 0 additions & 1 deletion Peregrine/parser/parser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,6 @@ AstNodePtr Parser::parse() {
statements.push_back(ParseStatement());
advance();
}

if (!m_errors.empty()) {
for (auto& err : m_errors) {
display(err);
Expand Down
18 changes: 9 additions & 9 deletions Peregrine/test.pe
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
if "test":
53 + 2
elif 54:
100
elif 123:
65
if True:
3 + 3
if True:
3 + 3
elif False:
8+8
else:
"nothing"

3 + 3
7
while True:
0
File renamed without changes.

0 comments on commit 3b4255e

Please sign in to comment.