Skip to content

Commit

Permalink
[PP] shift expression
Browse files Browse the repository at this point in the history
  • Loading branch information
LuisHsu committed Mar 19, 2024
1 parent 343a50d commit bb9443b
Show file tree
Hide file tree
Showing 2 changed files with 59 additions and 3 deletions.
19 changes: 18 additions & 1 deletion src/include/PreProcessor.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ struct PreProcessor {
Result unary();
Result multiplicative();
Result additive();
Result shift(); // TODO:
Result shift();
Result relational(); // TODO:
Result equality(); // TODO:
Result bitwise_AND(); // TODO:
Expand All @@ -92,13 +92,30 @@ struct PreProcessor {
Result logical_AND(); // TODO:
Result conditional(); // TODO:

template<typename T = void>
struct lshift {
template<typename U>
U operator()(U& lhs, U& rhs){
return lhs << rhs;
}
};
template<typename T = void>
struct rshift{
template<typename U>
U operator()(U& lhs, U& rhs){
return lhs >> rhs;
}
};

template<typename T>
static Result& cast_result(Result& res);

template<template<typename T> class Op, typename T = void>
static Result binary_op(Result&, Result&);
template<template<typename T> class Op, typename T = void>
requires std::is_same_v<Op<T>, std::modulus<T>>
|| std::is_same_v<Op<T>, lshift<T>>
|| std::is_same_v<Op<T>, rshift<T>>
static Result binary_op(Result&, Result&);

static void implicit_cast(Result&, Result&);
Expand Down
43 changes: 41 additions & 2 deletions src/lib/PreProcessor/Expression.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@

#include <cerrno>
#include <limits>
#include <climits>
#include <functional>
#include <Error.hpp>

Expand Down Expand Up @@ -48,7 +49,9 @@ void PreProcessor::Expression::implicit_cast(PreProcessor::Expression::Result& o
}

template<template<typename T> class Op, typename T>
requires std::is_same_v<Op<T>, std::modulus<T>>
requires std::is_same_v<Op<T>, std::modulus<T>>
|| std::is_same_v<Op<T>, PreProcessor::Expression::lshift<T>>
|| std::is_same_v<Op<T>, PreProcessor::Expression::rshift<T>>
PreProcessor::Expression::Result PreProcessor::Expression::binary_op(PreProcessor::Expression::Result& op1, PreProcessor::Expression::Result& op2){
return std::visit<Result>(overloaded {
[&](uintmax_t op1){
Expand Down Expand Up @@ -83,7 +86,7 @@ PreProcessor::Expression::Result PreProcessor::Expression::binary_op(PreProcesso
}

PreProcessor::Expression::Result PreProcessor::Expression::eval(){
return additive(); // TODO:
return shift(); // TODO:
}

PreProcessor::Expression::Result PreProcessor::Expression::primary(){
Expand Down Expand Up @@ -228,4 +231,40 @@ PreProcessor::Expression::Result PreProcessor::Expression::additive(){
}
}
return res;
}

PreProcessor::Expression::Result PreProcessor::Expression::shift(){
PreProcessor::Expression::Result res = additive();
Line::iterator head = skip_whitespace(cur, end);
cur = head;
if(cur != end && cur->hold<TokenType::Punctuator>()){
TokenType::Punctuator punct = cur->value();
if(punct.type == TokenType::Punctuator::Shift_L || punct.type == TokenType::Punctuator::Shift_R){
cur = std::next(cur);
PreProcessor::Expression::Result operand = shift();
if(std::holds_alternative<double>(res) || std::holds_alternative<double>(operand)){
throw Exception::Error(head->value().pos, "operands of shift expressions should be integral");
}
implicit_cast(res, operand);
if(std::holds_alternative<intmax_t>(operand) && (std::get<intmax_t>(operand) < 0)){
throw Exception::Error(head->value().pos, "right operands of shift expressions should be positive");
}
std::visit(overloaded {
[&](auto val){
if(val >= (sizeof(uintmax_t) * CHAR_BIT)){
throw Exception::Error(head->value().pos, "right operands of shift expressions too large");
}
}
}, operand);
if(punct.type == TokenType::Punctuator::Shift_L){
if(std::holds_alternative<intmax_t>(res) && (std::get<intmax_t>(res) < 0)){
throw Exception::Error(head->value().pos, "left operands of left shift should be positive");
}
return binary_op<lshift>(res, operand);
}else{
return binary_op<rshift>(res, operand);
}
}
}
return res;
}

0 comments on commit bb9443b

Please sign in to comment.