move template functions into cpp file

v1
Brett 2024-05-11 17:44:37 -04:00
parent fa5083b637
commit f228cfbbe3
4 changed files with 229 additions and 213 deletions

View File

@ -1,7 +1,7 @@
cmake_minimum_required(VERSION 3.20) cmake_minimum_required(VERSION 3.20)
include(cmake/color.cmake) include(cmake/color.cmake)
set(BLT_VERSION 0.17.4) set(BLT_VERSION 0.17.5)
set(BLT_TEST_VERSION 0.0.1) set(BLT_TEST_VERSION 0.0.1)
set(BLT_TARGET BLT) set(BLT_TARGET BLT)

View File

@ -321,223 +321,19 @@ namespace blt
} }
private: private:
estring statement() estring statement();
{
auto next = consumer.consume();
if (next.type == template_token_t::STRING || next.type == template_token_t::QUOTE)
{
consumer.back();
auto str = string();
return str;
} else if (next.type == template_token_t::FUNCTION)
{
return function();
} else if (next.type == template_token_t::IDENT && consumer.hasNext() && consumer.next().type == template_token_t::CURLY_OPEN)
{
consumer.advance();
auto stmt = statement();
// should never occur
if (consumer.hasNext() && consumer.next().type != template_token_t::CURLY_CLOSE)
return blt::unexpected(template_parser_failure_t::NO_MATCHING_CURLY);
consumer.advance();
return stmt;
} else if (next.type == template_token_t::IF)
{
return if_func();
}
return blt::unexpected(template_parser_failure_t::UNKNOWN_STATEMENT_ERROR);
}
estring function() estring function();
{
auto str = consumer.consume();
if (consumer.next().type == template_token_t::SEMI)
consumer.advance();
if (str.type != template_token_t::STRING)
return blt::unexpected(template_parser_failure_t::FUNCTION_EXPECTED_STRING);
if (str.token == "DISCARD")
return blt::unexpected(template_parser_failure_t::FUNCTION_DISCARD);
return blt::unexpected(template_parser_failure_t::FUNCTION_NOT_FOUND);
}
estring if_func() estring if_func();
{
// IF(
if (consumer.consume().type != template_token_t::PAR_OPEN)
return blt::unexpected(template_parser_failure_t::IF_EXPECTED_PAREN);
// (statement)
auto bool_eval = bool_statement();
if (!bool_eval)
return blt::unexpected(bool_eval.error());
if (consumer.consume().type != template_token_t::CURLY_OPEN)
return blt::unexpected(template_parser_failure_t::IF_EXPECTED_CURLY);
auto true_statement = statement();
if (consumer.consume().type != template_token_t::CURLY_CLOSE)
return blt::unexpected(template_parser_failure_t::IF_EXPECTED_CURLY);
estring false_statement = blt::unexpected(template_parser_failure_t::UNKNOWN_ERROR);
bool has_false = false;
if (consumer.next().type == template_token_t::ELSE)
{
consumer.advance();
if (consumer.consume().type != template_token_t::CURLY_OPEN)
return blt::unexpected(template_parser_failure_t::IF_EXPECTED_CURLY);
false_statement = statement();
if (consumer.consume().type != template_token_t::CURLY_CLOSE)
return blt::unexpected(template_parser_failure_t::IF_EXPECTED_CURLY);
has_false = true;
}
if (bool_eval.value())
return true_statement;
else
{
if (has_false)
return false_statement;
return "";
}
}
estring string() estring string();
{
auto next = consumer.consume();
if (next.type == template_token_t::STRING)
{
//
// return blt::unexpected(template_parser_failure_t::SUBSTITUTION_NOT_FOUND);
if (consumer.next().type == template_token_t::SEMI || consumer.next().type == template_token_t::ELSE ||
consumer.next().type == template_token_t::CURLY_CLOSE || consumer.next().type == template_token_t::PAR_CLOSE)
{
if (consumer.next().type == template_token_t::SEMI)
consumer.advance();
if (!engine.contains(next.token))
return "";
return engine.get(next.token);
}
if (consumer.next().type != template_token_t::ADD)
return blt::unexpected(template_parser_failure_t::STRING_EXPECTED_CONCAT);
consumer.advance();
auto str = string();
if (!str)
return str;
auto sub = engine.get(next.token);
if (!sub)
return sub;
return sub.value() + str.value();
} else
{
if (consumer.next().type == template_token_t::SEMI)
{
consumer.advance();
return std::string(next.token);
}
auto str = string();
if (str)
return std::string(next.token) + str.value();
else
return str;
}
}
ebool bool_statement() ebool bool_statement();
{
auto next = consumer.next();
if (next.type == template_token_t::PAR_OPEN)
{
consumer.advance();
auto b = bool_statement();
if (consumer.consume().type != template_token_t::PAR_CLOSE)
return blt::unexpected(template_parser_failure_t::BOOL_EXPECTED_PAREN);
consumer.advance();
return b;
}
return bool_expression();
}
ebool bool_value() ebool bool_value();
{
bool b1;
auto next = consumer.next();
bool invert = false;
// prefixes
if (next.type == template_token_t::NOT)
{
invert = true;
consumer.advance();
next = consumer.next();
}
if (next.type == template_token_t::PAR_OPEN)
{
auto b = bool_statement();
if (!b)
return b;
b1 = b.value();
} else
{
if (consumer.next().type == template_token_t::PAR_OPEN)
{
auto b = bool_statement();
if (!b)
return b;
b1 = b.value();
} else
{
auto b = statement();
if (!b)
return blt::unexpected(b.error());
b1 = !b.value().empty();
}
}
if (invert)
b1 = !b1;
return b1;
}
ebool bool_expression() ebool bool_expression();
{
// this whole thing is just bad. please redo. TODO
std::vector<int> values;
while (consumer.next().type != template_token_t::CURLY_OPEN)
{
auto next = consumer.next();
auto bv = bool_value();
if (!bv)
return bv;
values.push_back(bv.value());
if (values.size() == 2)
{
auto b1 = values[0];
auto b2 = values[1];
values.pop_back();
values.pop_back();
switch (next.type)
{
case template_token_t::AND:
values.push_back(b1 && b2);
break;
case template_token_t::OR:
values.push_back(b1 || b2);
break;
case template_token_t::XOR:
values.push_back(b1 ^ b2);
break;
default:
BLT_WARN("Unexpected token '%s'", std::string(next.token).c_str());
return blt::unexpected(template_parser_failure_t::BOOL_TYPE_NOT_FOUND);
}
}
next = consumer.next();
if (next.type == template_token_t::CURLY_OPEN)
break;
consumer.advance();
}
if (values.empty())
BLT_WARN("This is not possible!");
return values[0];
}
template_engine_t& engine; template_engine_t& engine;
template_token_consumer_t& consumer; template_token_consumer_t& consumer;

@ -1 +1 @@
Subproject commit 7ef2e733416953b222851f9a360d7fc72d068ee5 Subproject commit 10368163ab1f4367d2f0685b5928b1c973ebd1ec

View File

@ -244,4 +244,224 @@ namespace blt
return return_str; return return_str;
} }
template_parser_t::ebool template_parser_t::bool_expression()
{
// this whole thing is just bad. please redo. TODO
std::vector<int> values;
while (consumer.next().type != template_token_t::CURLY_OPEN)
{
auto next = consumer.next();
auto bv = bool_value();
if (!bv)
return bv;
values.push_back(bv.value());
if (values.size() == 2)
{
auto b1 = values[0];
auto b2 = values[1];
values.pop_back();
values.pop_back();
switch (next.type)
{
case template_token_t::AND:
values.push_back(b1 && b2);
break;
case template_token_t::OR:
values.push_back(b1 || b2);
break;
case template_token_t::XOR:
values.push_back(b1 ^ b2);
break;
default:
BLT_WARN("Unexpected token '%s'", std::string(next.token).c_str());
return blt::unexpected(template_parser_failure_t::BOOL_TYPE_NOT_FOUND);
}
}
next = consumer.next();
if (next.type == template_token_t::CURLY_OPEN)
break;
consumer.advance();
}
if (values.empty())
BLT_WARN("This is not possible!");
return values[0];
}
template_parser_t::ebool template_parser_t::bool_value()
{
bool b1;
auto next = consumer.next();
bool invert = false;
// prefixes
if (next.type == template_token_t::NOT)
{
invert = true;
consumer.advance();
next = consumer.next();
}
if (next.type == template_token_t::PAR_OPEN)
{
auto b = bool_statement();
if (!b)
return b;
b1 = b.value();
} else
{
if (consumer.next().type == template_token_t::PAR_OPEN)
{
auto b = bool_statement();
if (!b)
return b;
b1 = b.value();
} else
{
auto b = statement();
if (!b)
return blt::unexpected(b.error());
b1 = !b.value().empty();
}
}
if (invert)
b1 = !b1;
return b1;
}
template_parser_t::ebool template_parser_t::bool_statement()
{
auto next = consumer.next();
if (next.type == template_token_t::PAR_OPEN)
{
consumer.advance();
auto b = bool_statement();
if (consumer.consume().type != template_token_t::PAR_CLOSE)
return blt::unexpected(template_parser_failure_t::BOOL_EXPECTED_PAREN);
consumer.advance();
return b;
}
return bool_expression();
}
template_parser_t::estring template_parser_t::string()
{
auto next = consumer.consume();
if (next.type == template_token_t::STRING)
{
//
// return blt::unexpected(template_parser_failure_t::SUBSTITUTION_NOT_FOUND);
if (consumer.next().type == template_token_t::SEMI || consumer.next().type == template_token_t::ELSE ||
consumer.next().type == template_token_t::CURLY_CLOSE || consumer.next().type == template_token_t::PAR_CLOSE)
{
if (consumer.next().type == template_token_t::SEMI)
consumer.advance();
if (!engine.contains(next.token))
return "";
return engine.get(next.token);
}
if (consumer.next().type != template_token_t::ADD)
return blt::unexpected(template_parser_failure_t::STRING_EXPECTED_CONCAT);
consumer.advance();
auto str = string();
if (!str)
return str;
auto sub = engine.get(next.token);
if (!sub)
return sub;
return sub.value() + str.value();
} else
{
if (consumer.next().type == template_token_t::SEMI)
{
consumer.advance();
return std::string(next.token);
}
auto str = string();
if (str)
return std::string(next.token) + str.value();
else
return str;
}
}
template_parser_t::estring template_parser_t::if_func()
{
// IF(
if (consumer.consume().type != template_token_t::PAR_OPEN)
return blt::unexpected(template_parser_failure_t::IF_EXPECTED_PAREN);
// (statement)
auto bool_eval = bool_statement();
if (!bool_eval)
return blt::unexpected(bool_eval.error());
if (consumer.consume().type != template_token_t::CURLY_OPEN)
return blt::unexpected(template_parser_failure_t::IF_EXPECTED_CURLY);
auto true_statement = statement();
if (consumer.consume().type != template_token_t::CURLY_CLOSE)
return blt::unexpected(template_parser_failure_t::IF_EXPECTED_CURLY);
estring false_statement = blt::unexpected(template_parser_failure_t::UNKNOWN_ERROR);
bool has_false = false;
if (consumer.next().type == template_token_t::ELSE)
{
consumer.advance();
if (consumer.consume().type != template_token_t::CURLY_OPEN)
return blt::unexpected(template_parser_failure_t::IF_EXPECTED_CURLY);
false_statement = statement();
if (consumer.consume().type != template_token_t::CURLY_CLOSE)
return blt::unexpected(template_parser_failure_t::IF_EXPECTED_CURLY);
has_false = true;
}
if (bool_eval.value())
return true_statement;
else
{
if (has_false)
return false_statement;
return "";
}
}
template_parser_t::estring template_parser_t::function()
{
auto str = consumer.consume();
if (consumer.next().type == template_token_t::SEMI)
consumer.advance();
if (str.type != template_token_t::STRING)
return blt::unexpected(template_parser_failure_t::FUNCTION_EXPECTED_STRING);
if (str.token == "DISCARD")
return blt::unexpected(template_parser_failure_t::FUNCTION_DISCARD);
return blt::unexpected(template_parser_failure_t::FUNCTION_NOT_FOUND);
}
template_parser_t::estring template_parser_t::statement()
{
auto next = consumer.consume();
if (next.type == template_token_t::STRING || next.type == template_token_t::QUOTE)
{
consumer.back();
auto str = string();
return str;
} else if (next.type == template_token_t::FUNCTION)
{
return function();
} else if (next.type == template_token_t::IDENT && consumer.hasNext() && consumer.next().type == template_token_t::CURLY_OPEN)
{
consumer.advance();
auto stmt = statement();
// should never occur
if (consumer.hasNext() && consumer.next().type != template_token_t::CURLY_CLOSE)
return blt::unexpected(template_parser_failure_t::NO_MATCHING_CURLY);
consumer.advance();
return stmt;
} else if (next.type == template_token_t::IF)
{
return if_func();
}
return blt::unexpected(template_parser_failure_t::UNKNOWN_STATEMENT_ERROR);
}
} }