Skip to content

Commit

Permalink
added boolean expressions
Browse files Browse the repository at this point in the history
  • Loading branch information
t-weber committed Jun 6, 2020
1 parent 7c492b0 commit ad7a8e8
Show file tree
Hide file tree
Showing 5 changed files with 87 additions and 3 deletions.
34 changes: 34 additions & 0 deletions src/ast.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ class ASTAssign;
class ASTArrayAssign;
class ASTArrayAccess;
class ASTComp;
class ASTBool;
class ASTCond;
class ASTLoop;
class ASTExprList;
Expand Down Expand Up @@ -68,6 +69,7 @@ enum class ASTType
ArrayAssign,
ArrayAccess,
Comp,
Bool,
Cond,
Loop,
ExprList,
Expand Down Expand Up @@ -105,6 +107,7 @@ class ASTVisitor
virtual t_astret visit(const ASTArrayAssign* ast) = 0;
virtual t_astret visit(const ASTArrayAccess* ast) = 0;
virtual t_astret visit(const ASTComp* ast) = 0;
virtual t_astret visit(const ASTBool* ast) = 0;
virtual t_astret visit(const ASTCond* ast) = 0;
virtual t_astret visit(const ASTLoop* ast) = 0;
virtual t_astret visit(const ASTStrConst* ast) = 0;
Expand Down Expand Up @@ -537,6 +540,37 @@ class ASTComp : public AST
};


class ASTBool : public AST
{
public:
enum BoolOp
{
NOT,
AND, OR, XOR
};

public:
ASTBool(std::shared_ptr<AST> term1, std::shared_ptr<AST> term2, BoolOp op)
: term1{term1}, term2{term2}, op{op}
{}

ASTBool(std::shared_ptr<AST> term1, BoolOp op)
: term1{term1}, term2{nullptr}, op{op}
{}

const std::shared_ptr<AST> GetTerm1() const { return term1; }
const std::shared_ptr<AST> GetTerm2() const { return term2; }
BoolOp GetOp() const { return op; }

virtual ASTType type() override { return ASTType::Bool; }
ASTVISITOR_ACCEPT

private:
std::shared_ptr<AST> term1, term2;
BoolOp op;
};


class ASTCond : public AST
{
public:
Expand Down
1 change: 1 addition & 0 deletions src/lexer.l
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ ident [A-Za-z_]+[A-Za-z0-9_]*
">" { return yy::Parser::make_GT(); }
"<" { return yy::Parser::make_LT(); }
"and" { return yy::Parser::make_AND(); }
"xor" { return yy::Parser::make_XOR(); }
"or" { return yy::Parser::make_OR(); }
"not" { return yy::Parser::make_NOT(); }

Expand Down
43 changes: 41 additions & 2 deletions src/llasm.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1956,12 +1956,51 @@ t_astret LLAsm::visit(const ASTComp* ast)
}
}

throw std::runtime_error("ASTComp: Invalid comparison of \""
+ term1->name + "\" and \"" + term2->name + "\".");
throw std::runtime_error("ASTComp: Invalid comparison of \"" + term1->name + "\" and \"" + term2->name + "\".");
return nullptr;
}


t_astret LLAsm::visit(const ASTBool* ast)
{
t_astret term1 = ast->GetTerm1()->accept(this);
t_astret term2 = nullptr;
if(ast->GetTerm2())
term2 = ast->GetTerm2()->accept(this);

t_astret ret = get_tmp_var(SymbolType::INT);
switch(ast->GetOp())
{
case ASTBool::XOR:
{
(*m_ostr) << "%" << ret->name << " = xor i1 %" << term1->name << ", %" << term2->name << "\n";
break;
}
case ASTBool::OR:
{
(*m_ostr) << "%" << ret->name << " = or i1 %" << term1->name << ", %" << term2->name << "\n";
break;
}
case ASTBool::AND:
{
(*m_ostr) << "%" << ret->name << " = and i1 %" << term1->name << ", %" << term2->name << "\n";
break;
}
case ASTBool::NOT:
{
(*m_ostr) << "%" << ret->name << " = xor i1 1, %" << term1->name << "\n";
break;
}
default:
{
throw std::runtime_error("ASTBool: Invalid operation.");
return nullptr;
}
}

return ret;
}


t_astret LLAsm::visit(const ASTCond* ast)
{
Expand Down
1 change: 1 addition & 0 deletions src/llasm.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ class LLAsm : public ASTVisitor
virtual t_astret visit(const ASTArrayAssign* ast) override;
virtual t_astret visit(const ASTComp* ast) override;
virtual t_astret visit(const ASTCond* ast) override;
virtual t_astret visit(const ASTBool* ast) override;
virtual t_astret visit(const ASTLoop* ast) override;
virtual t_astret visit(const ASTStrConst* ast) override;
virtual t_astret visit(const ASTExprList* ast) override;
Expand Down
11 changes: 10 additions & 1 deletion src/parser.y
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@
%token IF THEN ELSE
%token LOOP DO
%token EQU NEQ GT LT GEQ LEQ
%token AND OR NOT
%token AND XOR OR NOT


// nonterminals
Expand All @@ -91,12 +91,14 @@
%nonassoc RET
%left ','
%right '='
%left XOR
%left OR
%left AND
%left GT LT GEQ LEQ
%left EQU NEQ
%left '+' '-'
%left '*' '/' '%'
%right NOT
%right UNARY_OP
%right '^' '\''
%left '(' '[' '{' '|'
Expand Down Expand Up @@ -289,6 +291,8 @@ expr[res]
| '|' expr[term] '|' { $res = std::make_shared<ASTNorm>($term); }
| expr[term] '\'' { $res = std::make_shared<ASTTransp>($term); }

// unary boolean expression
| NOT expr[term] { $res = std::make_shared<ASTBool>($term, ASTBool::NOT); }

// binary expressions
| expr[term1] '+' expr[term2] { $res = std::make_shared<ASTPlus>($term1, $term2, 0); }
Expand All @@ -298,6 +302,11 @@ expr[res]
| expr[term1] '%' expr[term2] { $res = std::make_shared<ASTMod>($term1, $term2); }
| expr[term1] '^' expr[term2] { $res = std::make_shared<ASTPow>($term1, $term2); }

// binary boolean expressions
| expr[term1] AND expr[term2] { $res = std::make_shared<ASTBool>($term1, $term2, ASTBool::AND); }
| expr[term1] OR expr[term2] { $res = std::make_shared<ASTBool>($term1, $term2, ASTBool::OR); }
| expr[term1] XOR expr[term2] { $res = std::make_shared<ASTBool>($term1, $term2, ASTBool::XOR); }

// comparison expressions
| expr[term1] EQU expr[term2] { $res = std::make_shared<ASTComp>($term1, $term2, ASTComp::EQU); }
| expr[term1] NEQ expr[term2] { $res = std::make_shared<ASTComp>($term1, $term2, ASTComp::NEQ); }
Expand Down

0 comments on commit ad7a8e8

Please sign in to comment.