Skip to content

Commit 2dfd3df

Browse files
authored
Merge pull request #3 from sillydan1/feature/comparisons
Feature/comparisons
2 parents 6631ace + 85e34d2 commit 2dfd3df

File tree

6 files changed

+157
-13
lines changed

6 files changed

+157
-13
lines changed

CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
cmake_minimum_required(VERSION 3.0)
2-
project(expr VERSION 1.1.3)
2+
project(expr VERSION 1.2.0)
33
include(cmake/CPM.cmake)
44
configure_file(src/config.h.in config.h)
55
set(CMAKE_CXX_STANDARD 20)

include/operations/boolean.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,12 @@
44
symbol_value_t and_(const symbol_value_t& a, const symbol_value_t& b);
55
symbol_value_t or_(const symbol_value_t& a, const symbol_value_t& b);
66
symbol_value_t not_(const symbol_value_t& a);
7+
symbol_value_t gt_(const symbol_value_t& a, const symbol_value_t& b);
8+
symbol_value_t ge_(const symbol_value_t& a, const symbol_value_t& b);
9+
symbol_value_t ee_(const symbol_value_t& a, const symbol_value_t& b);
10+
symbol_value_t ne_(const symbol_value_t& a, const symbol_value_t& b);
11+
symbol_value_t le_(const symbol_value_t& a, const symbol_value_t& b);
12+
symbol_value_t lt_(const symbol_value_t& a, const symbol_value_t& b);
713
// TODO: These operators are ambiguous with symbol_value_t && std::false_type / std::true_type for some reason.
814
//symbol_value_t operator&&(const symbol_value_t& a, const symbol_value_t& b);
915
//symbol_value_t operator||(const symbol_value_t& a, const symbol_value_t& b);

src/operations/boolean.cpp

Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,48 @@ auto t_not(const T1&) {
2323
throw std::domain_error(ss.str());
2424
return nullptr; // Must return something
2525
}
26+
template<typename T1, typename T2>
27+
auto t_gt(const T1&, const T2&) {
28+
std::ostringstream ss{};
29+
ss << "Unable to compare (>) types " << typeid(T1).name() << " and " << typeid(T2).name();
30+
throw std::domain_error(ss.str());
31+
return nullptr; // Must return something
32+
}
33+
template<typename T1, typename T2>
34+
auto t_ge(const T1&, const T2&) {
35+
std::ostringstream ss{};
36+
ss << "Unable to compare (>=) types " << typeid(T1).name() << " and " << typeid(T2).name();
37+
throw std::domain_error(ss.str());
38+
return nullptr; // Must return something
39+
}
40+
template<typename T1, typename T2>
41+
auto t_ee(const T1&, const T2&) {
42+
std::ostringstream ss{};
43+
ss << "Unable to compare (==) types " << typeid(T1).name() << " and " << typeid(T2).name();
44+
throw std::domain_error(ss.str());
45+
return nullptr; // Must return something
46+
}
47+
template<typename T1, typename T2>
48+
auto t_ne(const T1&, const T2&) {
49+
std::ostringstream ss{};
50+
ss << "Unable to compare (!=) types " << typeid(T1).name() << " and " << typeid(T2).name();
51+
throw std::domain_error(ss.str());
52+
return nullptr; // Must return something
53+
}
54+
template<typename T1, typename T2>
55+
auto t_le(const T1&, const T2&) {
56+
std::ostringstream ss{};
57+
ss << "Unable to compare (<=) types " << typeid(T1).name() << " and " << typeid(T2).name();
58+
throw std::domain_error(ss.str());
59+
return nullptr; // Must return something
60+
}
61+
template<typename T1, typename T2>
62+
auto t_lt(const T1&, const T2&) {
63+
std::ostringstream ss{};
64+
ss << "Unable to compare (<) types " << typeid(T1).name() << " and " << typeid(T2).name();
65+
throw std::domain_error(ss.str());
66+
return nullptr; // Must return something
67+
}
2668

2769
template<>
2870
auto t_and(const bool& a, const bool& b) {
@@ -37,6 +79,40 @@ auto t_not(const bool& a) {
3779
return !a;
3880
}
3981

82+
auto t_gt(const int& a, const int& b) {return a > b;}
83+
auto t_gt(const int& a, const float& b) {return a > b;}
84+
auto t_gt(const float& a, const int& b) {return a > b;}
85+
auto t_gt(const float& a, const float& b) {return a > b;}
86+
87+
auto t_ge(const int& a, const int& b) {return a >= b;}
88+
auto t_ge(const int& a, const float& b) {return a >= b;}
89+
auto t_ge(const float& a, const int& b) {return a >= b;}
90+
auto t_ge(const float& a, const float& b) {return a >= b;}
91+
92+
auto t_ee(const bool& a, const bool& b) {return a == b;}
93+
auto t_ee(const int& a, const int& b) {return a == b;}
94+
auto t_ee(const int& a, const float& b) {return a == b;}
95+
auto t_ee(const float& a, const int& b) {return a == b;}
96+
auto t_ee(const float& a, const float& b) {return a == b;}
97+
auto t_ee(const std::string& a, const std::string& b) {return a == b;}
98+
99+
auto t_ne(const bool& a, const bool& b) {return a != b;}
100+
auto t_ne(const int& a, const int& b) {return a != b;}
101+
auto t_ne(const int& a, const float& b) {return a != b;}
102+
auto t_ne(const float& a, const int& b) {return a != b;}
103+
auto t_ne(const float& a, const float& b) {return a != b;}
104+
auto t_ne(const std::string& a, const std::string& b) {return a != b;}
105+
106+
auto t_lt(const int& a, const int& b) {return a < b;}
107+
auto t_lt(const int& a, const float& b) {return a < b;}
108+
auto t_lt(const float& a, const int& b) {return a < b;}
109+
auto t_lt(const float& a, const float& b) {return a < b;}
110+
111+
auto t_le(const int& a, const int& b) {return a <= b;}
112+
auto t_le(const int& a, const float& b) {return a <= b;}
113+
auto t_le(const float& a, const int& b) {return a <= b;}
114+
auto t_le(const float& a, const float& b) {return a <= b;}
115+
40116
symbol_value_t and_(const symbol_value_t& a, const symbol_value_t& b) {
41117
symbol_value_t res{};
42118
FUNC_IMPL(a, t_and, b, res);
@@ -61,3 +137,33 @@ symbol_value_t not_(const symbol_value_t& a) {
61137
symbol_value_t operator!(const symbol_value_t& a) {
62138
return not_(a);
63139
}
140+
symbol_value_t gt_(const symbol_value_t& a, const symbol_value_t& b) {
141+
symbol_value_t res{};
142+
FUNC_IMPL(a, t_gt, b, res);
143+
return res;
144+
}
145+
symbol_value_t ge_(const symbol_value_t& a, const symbol_value_t& b) {
146+
symbol_value_t res{};
147+
FUNC_IMPL(a, t_ge, b, res);
148+
return res;
149+
}
150+
symbol_value_t ee_(const symbol_value_t& a, const symbol_value_t& b) {
151+
symbol_value_t res{};
152+
FUNC_IMPL(a, t_ee, b, res);
153+
return res;
154+
}
155+
symbol_value_t ne_(const symbol_value_t& a, const symbol_value_t& b) {
156+
symbol_value_t res{};
157+
FUNC_IMPL(a, t_ne, b, res);
158+
return res;
159+
}
160+
symbol_value_t le_(const symbol_value_t& a, const symbol_value_t& b) {
161+
symbol_value_t res{};
162+
FUNC_IMPL(a, t_le, b, res);
163+
return res;
164+
}
165+
symbol_value_t lt_(const symbol_value_t& a, const symbol_value_t& b) {
166+
symbol_value_t res{};
167+
FUNC_IMPL(a, t_lt, b, res);
168+
return res;
169+
}

src/parser/driver.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ driver::driver(const symbol_table_t& map) : trace_parsing (false), trace_scannin
66
}
77

88
int driver::parse(const std::string &f) {
9+
if(f.empty())
10+
return 0;
911
file = f;
1012
location.initialize (&file);
1113
scan_begin();

src/parser/parser.y

Lines changed: 36 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,12 @@
4242
SLASH "/"
4343
AND "&&"
4444
OR "||"
45+
GT ">"
46+
GE ">="
47+
EE "=="
48+
NE "!="
49+
LE "<="
50+
LT "<"
4551
NOT "!"
4652
LPAREN "("
4753
RPAREN ")"
@@ -54,14 +60,14 @@
5460
%token <float> FLOAT "float"
5561
%token <bool> BOOL "bool"
5662
%token <std::string> STRING "string"
57-
%nterm <symbol_value_t> exp
63+
%nterm <symbol_value_t> exp cmp op
5864
%printer { yyo << $$; } <*>;
5965

6066
%%
6167
%start unit;
6268
unit:
6369
assignments { }
64-
| exp { drv.result["expression_result"] = $1; }
70+
| cmp { drv.result["expression_result"] = $1; }
6571
;
6672

6773
assignments:
@@ -71,24 +77,42 @@ assignments:
7177
;
7278

7379
assignment:
74-
"identifier" ":=" exp { drv.result[$1] = $3; };
80+
"identifier" ":=" cmp { drv.result[$1] = $3; };
7581

7682
%left "+" "-";
7783
%left "*" "/";
84+
%precedence "||" "&&";
85+
86+
cmp:
87+
op "||" op { $$ = or_($1,$3); }
88+
| op "&&" op { $$ = and_($1,$3); }
89+
| "!" op { $$ = not_($2); }
90+
| op { $$ = $1; }
91+
| "(" op ")" { $$ = $2; }
92+
;
93+
94+
op:
95+
exp "+" exp { $$ = $1 + $3; }
96+
| exp "-" exp { $$ = $1 - $3; }
97+
| exp "*" exp { $$ = $1 * $3; }
98+
| exp "/" exp { $$ = $1 / $3; }
99+
| exp ">" exp { $$ = gt_($1,$3); }
100+
| exp ">=" exp { $$ = ge_($1,$3); }
101+
| exp "==" exp { $$ = ee_($1,$3); }
102+
| exp "!=" exp { $$ = ne_($1,$3); }
103+
| exp "<=" exp { $$ = le_($1,$3); }
104+
| exp "<" exp { $$ = lt_($1,$3); }
105+
| exp { $$ = $1; }
106+
;
107+
78108
exp:
79-
"number" { $$ = $1; }
109+
cmp { $$ = $1; }
110+
| "number" { $$ = $1; }
80111
| "float" { $$ = $1; }
81112
| "string" { $$ = $1; }
82113
| "bool" { $$ = $1; }
83114
| "identifier" { $$ = drv.environment.at($1); }
84-
| exp "+" exp { $$ = $1 + $3; }
85-
| exp "-" exp { $$ = $1 - $3; }
86-
| exp "*" exp { $$ = $1 * $3; }
87-
| exp "/" exp { $$ = $1 / $3; }
88-
| exp "||" exp { $$ = or_($1,$3); }
89-
| exp "&&" exp { $$ = and_($1,$3); }
90-
| "!" exp { $$ = not_($2); }
91-
| "(" exp ")" { $$ = $2; }
115+
;
92116
%%
93117

94118
void yy::parser::error (const location_type& l, const std::string& m) {

src/parser/scanner.l

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,12 @@ blank [ \t\r]
117117
"/" return yy::parser::make_SLASH (loc);
118118
"&&" return yy::parser::make_AND (loc);
119119
"||" return yy::parser::make_OR (loc);
120+
">" return yy::parser::make_GT (loc);
121+
">=" return yy::parser::make_GE (loc);
122+
"==" return yy::parser::make_EE (loc);
123+
"!=" return yy::parser::make_NE (loc);
124+
"<=" return yy::parser::make_LE (loc);
125+
"<" return yy::parser::make_LT (loc);
120126
"!" return yy::parser::make_NOT (loc);
121127
"(" return yy::parser::make_LPAREN (loc);
122128
")" return yy::parser::make_RPAREN (loc);

0 commit comments

Comments
 (0)