Skip to content

Commit

Permalink
Merge pull request #3 from sillydan1/feature/comparisons
Browse files Browse the repository at this point in the history
Feature/comparisons
  • Loading branch information
sillydan1 authored Mar 20, 2022
2 parents 6631ace + 85e34d2 commit 2dfd3df
Show file tree
Hide file tree
Showing 6 changed files with 157 additions and 13 deletions.
2 changes: 1 addition & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
cmake_minimum_required(VERSION 3.0)
project(expr VERSION 1.1.3)
project(expr VERSION 1.2.0)
include(cmake/CPM.cmake)
configure_file(src/config.h.in config.h)
set(CMAKE_CXX_STANDARD 20)
Expand Down
6 changes: 6 additions & 0 deletions include/operations/boolean.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,12 @@
symbol_value_t and_(const symbol_value_t& a, const symbol_value_t& b);
symbol_value_t or_(const symbol_value_t& a, const symbol_value_t& b);
symbol_value_t not_(const symbol_value_t& a);
symbol_value_t gt_(const symbol_value_t& a, const symbol_value_t& b);
symbol_value_t ge_(const symbol_value_t& a, const symbol_value_t& b);
symbol_value_t ee_(const symbol_value_t& a, const symbol_value_t& b);
symbol_value_t ne_(const symbol_value_t& a, const symbol_value_t& b);
symbol_value_t le_(const symbol_value_t& a, const symbol_value_t& b);
symbol_value_t lt_(const symbol_value_t& a, const symbol_value_t& b);
// TODO: These operators are ambiguous with symbol_value_t && std::false_type / std::true_type for some reason.
//symbol_value_t operator&&(const symbol_value_t& a, const symbol_value_t& b);
//symbol_value_t operator||(const symbol_value_t& a, const symbol_value_t& b);
Expand Down
106 changes: 106 additions & 0 deletions src/operations/boolean.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,48 @@ auto t_not(const T1&) {
throw std::domain_error(ss.str());
return nullptr; // Must return something
}
template<typename T1, typename T2>
auto t_gt(const T1&, const T2&) {
std::ostringstream ss{};
ss << "Unable to compare (>) types " << typeid(T1).name() << " and " << typeid(T2).name();
throw std::domain_error(ss.str());
return nullptr; // Must return something
}
template<typename T1, typename T2>
auto t_ge(const T1&, const T2&) {
std::ostringstream ss{};
ss << "Unable to compare (>=) types " << typeid(T1).name() << " and " << typeid(T2).name();
throw std::domain_error(ss.str());
return nullptr; // Must return something
}
template<typename T1, typename T2>
auto t_ee(const T1&, const T2&) {
std::ostringstream ss{};
ss << "Unable to compare (==) types " << typeid(T1).name() << " and " << typeid(T2).name();
throw std::domain_error(ss.str());
return nullptr; // Must return something
}
template<typename T1, typename T2>
auto t_ne(const T1&, const T2&) {
std::ostringstream ss{};
ss << "Unable to compare (!=) types " << typeid(T1).name() << " and " << typeid(T2).name();
throw std::domain_error(ss.str());
return nullptr; // Must return something
}
template<typename T1, typename T2>
auto t_le(const T1&, const T2&) {
std::ostringstream ss{};
ss << "Unable to compare (<=) types " << typeid(T1).name() << " and " << typeid(T2).name();
throw std::domain_error(ss.str());
return nullptr; // Must return something
}
template<typename T1, typename T2>
auto t_lt(const T1&, const T2&) {
std::ostringstream ss{};
ss << "Unable to compare (<) types " << typeid(T1).name() << " and " << typeid(T2).name();
throw std::domain_error(ss.str());
return nullptr; // Must return something
}

template<>
auto t_and(const bool& a, const bool& b) {
Expand All @@ -37,6 +79,40 @@ auto t_not(const bool& a) {
return !a;
}

auto t_gt(const int& a, const int& b) {return a > b;}
auto t_gt(const int& a, const float& b) {return a > b;}
auto t_gt(const float& a, const int& b) {return a > b;}
auto t_gt(const float& a, const float& b) {return a > b;}

auto t_ge(const int& a, const int& b) {return a >= b;}
auto t_ge(const int& a, const float& b) {return a >= b;}
auto t_ge(const float& a, const int& b) {return a >= b;}
auto t_ge(const float& a, const float& b) {return a >= b;}

auto t_ee(const bool& a, const bool& b) {return a == b;}
auto t_ee(const int& a, const int& b) {return a == b;}
auto t_ee(const int& a, const float& b) {return a == b;}
auto t_ee(const float& a, const int& b) {return a == b;}
auto t_ee(const float& a, const float& b) {return a == b;}
auto t_ee(const std::string& a, const std::string& b) {return a == b;}

auto t_ne(const bool& a, const bool& b) {return a != b;}
auto t_ne(const int& a, const int& b) {return a != b;}
auto t_ne(const int& a, const float& b) {return a != b;}
auto t_ne(const float& a, const int& b) {return a != b;}
auto t_ne(const float& a, const float& b) {return a != b;}
auto t_ne(const std::string& a, const std::string& b) {return a != b;}

auto t_lt(const int& a, const int& b) {return a < b;}
auto t_lt(const int& a, const float& b) {return a < b;}
auto t_lt(const float& a, const int& b) {return a < b;}
auto t_lt(const float& a, const float& b) {return a < b;}

auto t_le(const int& a, const int& b) {return a <= b;}
auto t_le(const int& a, const float& b) {return a <= b;}
auto t_le(const float& a, const int& b) {return a <= b;}
auto t_le(const float& a, const float& b) {return a <= b;}

symbol_value_t and_(const symbol_value_t& a, const symbol_value_t& b) {
symbol_value_t res{};
FUNC_IMPL(a, t_and, b, res);
Expand All @@ -61,3 +137,33 @@ symbol_value_t not_(const symbol_value_t& a) {
symbol_value_t operator!(const symbol_value_t& a) {
return not_(a);
}
symbol_value_t gt_(const symbol_value_t& a, const symbol_value_t& b) {
symbol_value_t res{};
FUNC_IMPL(a, t_gt, b, res);
return res;
}
symbol_value_t ge_(const symbol_value_t& a, const symbol_value_t& b) {
symbol_value_t res{};
FUNC_IMPL(a, t_ge, b, res);
return res;
}
symbol_value_t ee_(const symbol_value_t& a, const symbol_value_t& b) {
symbol_value_t res{};
FUNC_IMPL(a, t_ee, b, res);
return res;
}
symbol_value_t ne_(const symbol_value_t& a, const symbol_value_t& b) {
symbol_value_t res{};
FUNC_IMPL(a, t_ne, b, res);
return res;
}
symbol_value_t le_(const symbol_value_t& a, const symbol_value_t& b) {
symbol_value_t res{};
FUNC_IMPL(a, t_le, b, res);
return res;
}
symbol_value_t lt_(const symbol_value_t& a, const symbol_value_t& b) {
symbol_value_t res{};
FUNC_IMPL(a, t_lt, b, res);
return res;
}
2 changes: 2 additions & 0 deletions src/parser/driver.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ driver::driver(const symbol_table_t& map) : trace_parsing (false), trace_scannin
}

int driver::parse(const std::string &f) {
if(f.empty())
return 0;
file = f;
location.initialize (&file);
scan_begin();
Expand Down
48 changes: 36 additions & 12 deletions src/parser/parser.y
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,12 @@
SLASH "/"
AND "&&"
OR "||"
GT ">"
GE ">="
EE "=="
NE "!="
LE "<="
LT "<"
NOT "!"
LPAREN "("
RPAREN ")"
Expand All @@ -54,14 +60,14 @@
%token <float> FLOAT "float"
%token <bool> BOOL "bool"
%token <std::string> STRING "string"
%nterm <symbol_value_t> exp
%nterm <symbol_value_t> exp cmp op
%printer { yyo << $$; } <*>;

%%
%start unit;
unit:
assignments { }
| exp { drv.result["expression_result"] = $1; }
| cmp { drv.result["expression_result"] = $1; }
;

assignments:
Expand All @@ -71,24 +77,42 @@ assignments:
;

assignment:
"identifier" ":=" exp { drv.result[$1] = $3; };
"identifier" ":=" cmp { drv.result[$1] = $3; };

%left "+" "-";
%left "*" "/";
%precedence "||" "&&";

cmp:
op "||" op { $$ = or_($1,$3); }
| op "&&" op { $$ = and_($1,$3); }
| "!" op { $$ = not_($2); }
| op { $$ = $1; }
| "(" op ")" { $$ = $2; }
;

op:
exp "+" exp { $$ = $1 + $3; }
| exp "-" exp { $$ = $1 - $3; }
| exp "*" exp { $$ = $1 * $3; }
| exp "/" exp { $$ = $1 / $3; }
| exp ">" exp { $$ = gt_($1,$3); }
| exp ">=" exp { $$ = ge_($1,$3); }
| exp "==" exp { $$ = ee_($1,$3); }
| exp "!=" exp { $$ = ne_($1,$3); }
| exp "<=" exp { $$ = le_($1,$3); }
| exp "<" exp { $$ = lt_($1,$3); }
| exp { $$ = $1; }
;

exp:
"number" { $$ = $1; }
cmp { $$ = $1; }
| "number" { $$ = $1; }
| "float" { $$ = $1; }
| "string" { $$ = $1; }
| "bool" { $$ = $1; }
| "identifier" { $$ = drv.environment.at($1); }
| exp "+" exp { $$ = $1 + $3; }
| exp "-" exp { $$ = $1 - $3; }
| exp "*" exp { $$ = $1 * $3; }
| exp "/" exp { $$ = $1 / $3; }
| exp "||" exp { $$ = or_($1,$3); }
| exp "&&" exp { $$ = and_($1,$3); }
| "!" exp { $$ = not_($2); }
| "(" exp ")" { $$ = $2; }
;
%%

void yy::parser::error (const location_type& l, const std::string& m) {
Expand Down
6 changes: 6 additions & 0 deletions src/parser/scanner.l
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,12 @@ blank [ \t\r]
"/" return yy::parser::make_SLASH (loc);
"&&" return yy::parser::make_AND (loc);
"||" return yy::parser::make_OR (loc);
">" return yy::parser::make_GT (loc);
">=" return yy::parser::make_GE (loc);
"==" return yy::parser::make_EE (loc);
"!=" return yy::parser::make_NE (loc);
"<=" return yy::parser::make_LE (loc);
"<" return yy::parser::make_LT (loc);
"!" return yy::parser::make_NOT (loc);
"(" return yy::parser::make_LPAREN (loc);
")" return yy::parser::make_RPAREN (loc);
Expand Down

0 comments on commit 2dfd3df

Please sign in to comment.