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

Commit

Permalink
implement eg
Browse files Browse the repository at this point in the history
  • Loading branch information
SaptakBhoumik committed Jan 25, 2022
1 parent e62b34e commit 379c10b
Show file tree
Hide file tree
Showing 12 changed files with 269 additions and 18 deletions.
36 changes: 34 additions & 2 deletions Peregrine/ast/ast.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -522,7 +522,7 @@ std::string BlockStatement::stringify() const {
std::string res = "";

for (auto& stmt : m_statements) {
res += stmt->stringify();
res += " "+stmt->stringify();
res += "\n";
}

Expand Down Expand Up @@ -1321,6 +1321,38 @@ std::string TernaryIf::stringify() const{
std::string res=m_if_value->stringify()+" if("+m_if_value->stringify()+") else "+m_else_value->stringify();
return res;
}

TryExcept::TryExcept(Token token,AstNodePtr body,std::vector<except_type> except_clauses,AstNodePtr else_body){
m_token=token;
m_body=body;
m_except_clauses=except_clauses;
m_else_body=else_body;
}
AstNodePtr TryExcept::body() const{return m_body;}
std::vector<except_type> TryExcept::except_clauses() const{return m_except_clauses;}
AstNodePtr TryExcept::else_body() const{return m_else_body;}
Token TryExcept::token() const{return m_token;}
AstKind TryExcept::type() const{return KAstTryExcept;}
std::string TryExcept::stringify() const{
std::string res="try:\n";
res+=m_body->stringify();
res+="\n";
for(size_t i=0;i<m_except_clauses.size();++i){
except_type x=m_except_clauses[i];
res+="except ";
for (size_t i=0;i<x.first.first.size();++i){
res+=x.first.first[i]->stringify();
if(i<x.first.first.size()-1){
res+=",";
}
}
res+=" as ";
res+=x.first.second->stringify();
res+=":\n";
res+=x.second->stringify();
res+="\n";
}
res+="except:\n"+m_else_body->stringify();
return res;
}

} // namespace ast
26 changes: 25 additions & 1 deletion Peregrine/ast/ast.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,8 @@ enum AstKind {
KAstCast,
KAstDefaultArg,
KAstExport,
KAstTernaryIf
KAstTernaryIf,
KAstTryExcept
};

class AstVisitor;
Expand Down Expand Up @@ -975,6 +976,29 @@ class TernaryIf : public AstNode {
void accept(AstVisitor& visitor) const;

};
//This is long 🤣🤣
typedef std::pair<std::pair<std::vector<AstNodePtr>,AstNodePtr>,AstNodePtr> except_type;
/*
except_type.first.first=the various exception types
except_type.first.second=exception as variable
except_type.second=except_type's body
*/
class TryExcept : public AstNode {
Token m_token;
AstNodePtr m_body;
std::vector<except_type> m_except_clauses;

AstNodePtr m_else_body;
public:
TryExcept(Token token,AstNodePtr body,std::vector<except_type> except_clauses,AstNodePtr else_body);
AstNodePtr body() const;
std::vector<except_type> except_clauses() const;
AstNodePtr else_body() const;//If none of the exeptions are thrown, this is executed
Token token() const;
AstKind type() const;
std::string stringify() const;
void accept(AstVisitor& visitor) const;
};
} // namespace ast

#endif
2 changes: 1 addition & 1 deletion Peregrine/ast/visitor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,6 @@ void PointerTypeExpr::accept(AstVisitor& visitor) const { visitor.visit(*this);
void DefaultArg::accept(AstVisitor& visitor) const { visitor.visit(*this); }

void TernaryIf::accept(AstVisitor& visitor) const { visitor.visit(*this); }

void TryExcept::accept(AstVisitor& visitor) const { visitor.visit(*this); }

} // namespace ast
1 change: 1 addition & 0 deletions Peregrine/ast/visitor.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ class AstVisitor {
virtual bool visit(const PointerTypeExpr& node) { return false; };
virtual bool visit(const DefaultArg& node) { return false; };
virtual bool visit(const TernaryIf& node) { return false; };
virtual bool visit(const TryExcept& node) { return false; };
};

} // namespace ast
Expand Down
69 changes: 68 additions & 1 deletion Peregrine/codegen/cpp/codegen.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -707,7 +707,12 @@ bool Codegen::visit(const ast::InlineStatement& node){
}
bool Codegen::visit(const ast::RaiseStatement& node){
write("throw ");
node.value()->accept(*this);
if(node.value()->type()!=ast::KAstNoLiteral){
node.value()->accept(*this);
}
else{
write("0");
}
return true;
}
bool Codegen::visit(const ast::UnionLiteral& node){
Expand Down Expand Up @@ -865,4 +870,66 @@ bool Codegen::visit(const ast::TernaryIf& node){
node.else_value()->accept(*this);
return true;
}
bool Codegen::visit(const ast::TryExcept& node){
write("try{\n");
node.body()->accept(*this);
//TODO:This should be base exception
write("}\ncatch(error __PEREGRINE__exception){\n");
if(node.except_clauses().size()>0){
write("if (");
auto x=node.except_clauses()[0];
for (size_t i=0;i<x.first.first.size();++i){
write("__PEREGRINE__exception==");
x.first.first[i]->accept(*this);
if(i<x.first.first.size()-1){write("||");}
}
write("){\n");
if(x.first.second->type()!=ast::KAstNoLiteral){
write("auto ");
x.first.second->accept(*this);
write("=__PEREGRINE__exception;\n");
}
x.second->accept(*this);
write("}\n");
for(size_t i=1;i<node.except_clauses().size();++i){
write("else if (");
auto x=node.except_clauses()[i];
for (size_t i=0;i<x.first.first.size();++i){
write("__PEREGRINE__exception==");
x.first.first[i]->accept(*this);
if(i<x.first.first.size()-1){write("||");}
}
write("){\n");
if(x.first.second->type()!=ast::KAstNoLiteral){
write("auto ");
x.first.second->accept(*this);
write("=__PEREGRINE__exception;\n");
}
x.second->accept(*this);
write("}\n");
}
}
if(node.else_body()->type()!=ast::KAstNoLiteral){
if(node.except_clauses().size()>0){
write("else{");
node.else_body()->accept(*this);
write("}\n");
}
else{
node.else_body()->accept(*this);
}
}
else{
if(node.except_clauses().size()>0){
write("else{");
write("throw __PEREGRINE__exception;\n");
write("}\n");
}
else{
write("throw __PEREGRINE__exception;\n");
}
}
write("}");
return true;
}
} // namespace cpp
1 change: 1 addition & 0 deletions Peregrine/codegen/cpp/codegen.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,7 @@ class Codegen : public ast::AstVisitor {
bool visit(const ast::DefaultArg& node);
bool visit(const ast::ExportStatement& node);
bool visit(const ast::TernaryIf& node);
bool visit(const ast::TryExcept& node);
EnvPtr m_env;
};

Expand Down
6 changes: 3 additions & 3 deletions Peregrine/codegen/cpp/utils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -168,8 +168,8 @@ void Codegen::write_name(std::shared_ptr<ast::FunctionDefinition> node,std::stri
{"__lshift__","<<"},
{"__and__"," and"},
{"__or__"," or"},
{"__bit_and__","&"},
{"__bit_or__","|"},
{"__rand__","&"},
{"__ror__","|"},
{"__xor__","^"},
{"__lt__","<"},
{"__gt__",">"},
Expand All @@ -190,7 +190,7 @@ void Codegen::write_name(std::shared_ptr<ast::FunctionDefinition> node,std::stri
};
std::map<std::string,std::string> overloaded_unary_op={
{"__neg__","-"},
{"__invert__","+"},
{"__invert__","~"},
{"__not__"," not"},
{"__increment__","++"},
{"__decrement__","--"}
Expand Down
4 changes: 3 additions & 1 deletion Peregrine/codegen/js/codegen.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -519,7 +519,9 @@ bool Codegen::visit(const ast::AssertStatement& node){
}
bool Codegen::visit(const ast::RaiseStatement& node){
write("throw ");
node.value()->accept(*this);
if(node.value()->type()!=ast::KAstNoLiteral){
node.value()->accept(*this);
}
return true;
}
bool Codegen::visit(const ast::EnumLiteral& node){
Expand Down
111 changes: 107 additions & 4 deletions Peregrine/parser/parser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -174,8 +174,30 @@ AstNodePtr Parser::parseStatement() {
error(m_currentToken, "Virtual function should be inside class only","","","e4");
break;
}
// TODO: variables currently do not work with all the types, we need to
// fix this
case tk_try:{
stmt = parseTryExcept();
break;
}
case tk_else:{
error(m_currentToken, "else statement without a previous if","","","e4");
break;
}
case tk_elif:{
error(m_currentToken, "elif statement without a previous if","","","e4");
break;
}
case tk_except:{
error(m_currentToken, "except statement without a previous try","","","");
break;
}
case tk_case:{
error(m_currentToken, "case statement without a previous match","","","");
break;
}
case tk_default:{
error(m_currentToken, "default statement without a previous match","","","");
break;
}
case tk_identifier: {
if ((next().tkType == tk_colon || next().tkType == tk_assign)) {
// variable
Expand Down Expand Up @@ -386,7 +408,6 @@ AstNodePtr Parser::parseImport() {
return std::make_shared<ImportStatement>(tok, moduleName, importedSymbols);
}

// TODO: make this invalid: int = 43
AstNodePtr Parser::parseVariableStatement() {
Token tok = m_currentToken;
AstNodePtr varType = std::make_shared<NoLiteral>();
Expand Down Expand Up @@ -1208,7 +1229,10 @@ AstNodePtr Parser::parseAssert() {
AstNodePtr Parser::parseRaise() {
auto tok = m_currentToken;
advance();
AstNodePtr value = parseExpression();
AstNodePtr value = std::make_shared<NoLiteral>();
if(m_currentToken.tkType!=tk_new_line){
value = parseExpression();
}
return std::make_shared<RaiseStatement>(tok, value);
}

Expand Down Expand Up @@ -1446,3 +1470,82 @@ AstNodePtr Parser::parseTernaryIf(AstNodePtr left){
AstNodePtr else_value=parseExpression(pr_conditional);
return std::make_shared<TernaryIf>(tok,left,if_condition,else_value);
}
AstNodePtr Parser::parseTryExcept(){
auto tok=m_currentToken;
expect(tk_colon,"Expected : but got "+next().keyword+" instead","Add a : here","","");
auto line=m_currentToken.line;
AstNodePtr try_body;
if(next().tkType!=tk_ident && next().line==line){
advance();
std::vector<AstNodePtr> x;
x.push_back(parseStatement());
try_body = std::make_shared<BlockStatement>(x);
}
else{
expect(tk_ident,"Expected identation but got "+next().keyword+" instead","","","");
try_body = parseBlockStatement();
}
expect(tk_except,"Expected except but got "+next().keyword+" instead","Atleast one except is necessary","","");
AstNodePtr else_body=std::make_shared<NoLiteral>();
std::vector<except_type> m_except_clauses;
while(m_currentToken.tkType==tk_except){
if(next().tkType==tk_colon){
advance();
auto line=m_currentToken.line;
if(next().tkType!=tk_ident && next().line==line){
advance();
std::vector<AstNodePtr> x;
x.push_back(parseStatement());
else_body = std::make_shared<BlockStatement>(x);
}
else{
expect(tk_ident,"Expected identation but got "+next().keyword+" instead","","","");
else_body = parseBlockStatement();
}
break;
}
else{

AstNodePtr name=std::make_shared<NoLiteral>();
AstNodePtr except_body=std::make_shared<NoLiteral>();
std::vector<AstNodePtr> exceptions;
advance();
while(m_currentToken.tkType!=tk_colon && m_currentToken.tkType!=tk_as){
exceptions.push_back(parseExpression());
if(next().tkType==tk_comma){
advance();
advance();
}
else if(next().tkType==tk_as||next().tkType==tk_colon){
advance();
}
else{
error(next(),"Expected ',' or 'as' or ':' but got "+
next().keyword+
" instead","","","");
}
}
if(m_currentToken.tkType==tk_as){
advance();
name=parseName();
expect(tk_colon,"Expected : but got "+next().keyword+" instead","Add a : here","","");
}
auto line=m_currentToken.line;
if(next().tkType!=tk_ident && next().line==line){
advance();
std::vector<AstNodePtr> x;
x.push_back(parseStatement());
except_body = std::make_shared<BlockStatement>(x);
}
else{
expect(tk_ident,"Expected identation but got "+next().keyword+" instead","","","");
except_body = parseBlockStatement();
}
if (next().tkType==tk_except){
advance();
}
m_except_clauses.push_back(std::make_pair(std::make_pair(exceptions,name),except_body));
}
}
return std::make_shared<TryExcept>(tok,try_body,m_except_clauses,else_body);
}
1 change: 1 addition & 0 deletions Peregrine/parser/parser.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,7 @@ class Parser {
AstNodePtr parseExport();
AstNodePtr parseTypeDef();
AstNodePtr parseDefaultArg();
AstNodePtr parseTryExcept();

public:
Parser(const std::vector<Token>& tokens,std::string filename);
Expand Down
14 changes: 12 additions & 2 deletions Peregrine/test.pe
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
while True:#Infinite loop lol
pass
def test(a,b):
pass
raise
for x in y:
for i , j in x:
pass
Expand Down Expand Up @@ -80,4 +80,14 @@ match x:
i++
i--
def v():
return 1,2
return 1,2
try:
pass
except a:
pass
except a as b:
pass
except a,c as b:
pass
except:
pass
Loading

0 comments on commit 379c10b

Please sign in to comment.