Skip to content

Commit

Permalink
Started work to support a unified ordering interface for symbols
Browse files Browse the repository at this point in the history
  • Loading branch information
KaruroChori committed Jan 17, 2025
1 parent 92dac36 commit 8ace8e8
Show file tree
Hide file tree
Showing 8 changed files with 69 additions and 42 deletions.
3 changes: 1 addition & 2 deletions docs/syntax.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,7 @@ title: Full Syntax reference
---

> [!WARNING]
> This documentation reflects the expected functionality for v0.5.0.
> Some features are still missing, progress is tracked in the repository and on the todo file in root.
> While all core features have been implemented, documentation efforts are still ongoing.
`vs.templ` uses special elements and attributes to define which actions the preprocessor should perform.
These XML entities are scoped under the namespace `s` by default, but the user can set up a custom one as well.
Expand Down
8 changes: 4 additions & 4 deletions include/stack-lang.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -52,12 +52,12 @@ struct repl{
size_t operands;
};

std::stack<concrete_symbol> stack;
std::stack<symbol> stack;

const preprocessor& ctx;

struct command_t{
error_t (*fn)(std::stack<concrete_symbol>& stack, size_t N);
error_t (*fn)(std::stack<symbol>& stack, size_t N);
int min_arity = 1;
int max_arity = min_arity;
int default_arity = min_arity;
Expand All @@ -69,8 +69,8 @@ struct repl{

repl(const preprocessor& _ctx);

std::optional<concrete_symbol> eval(const char* expr) noexcept;
bool push_operand(const concrete_symbol& ref)noexcept;
std::optional<symbol> eval(const char* expr) noexcept;
bool push_operand(const symbol& ref)noexcept;
};

}
Expand Down
7 changes: 2 additions & 5 deletions include/symbols.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,10 @@
namespace vs{
namespace templ{

//Symbol which can be saved in the table. Now they are the same as concrete_symbol
//Symbol which can be saved in the table. Now they are the same as symbol
typedef std::variant<int,const pugi::xml_node, const pugi::xml_attribute, std::string, float> symbol;

//Extended symbol which is the result of computations. ~~String is introduced as they cannot be set as values for symbols, but they can be computed.~~
typedef std::variant<int,const pugi::xml_node, const pugi::xml_attribute, std::string, float> concrete_symbol;

std::optional<std::string> to_string(const concrete_symbol& val);
std::optional<std::string> to_string(const symbol& val);

//Utility class to implement a list of symbols. Use for `for` like structures in pattern matching.
struct symbol_map{
Expand Down
27 changes: 26 additions & 1 deletion include/vs-templ.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,7 @@ struct preprocessor{

private:
struct order_method_t{
//TODO: legacy to be removed
enum values{
UNKNOWN = 0,
ASC,
Expand All @@ -134,6 +135,21 @@ struct preprocessor{
USE_DOT_EVAL = 16 //For strings, split evaluation based on their dot groups. Valid for all methods.
};

enum class method_t{
DEFAULT,ASC,DESC,RANDOM
}method;

enum class type_t{
DEFAULT,
STRING,NATURAL_STRING,LEXI_STRING,
INTEGER,
FLOAT
}type;

struct modifiers_t{
bool dot : 1; //It has effect only on strings
}modifiers;

static values from_string(std::string_view str);
};

Expand Down Expand Up @@ -193,8 +209,17 @@ struct preprocessor{

}strings;

enum class compare_result{
NOT_COMPARABLE = -2,
LESS = -1,
EQUAL = 0,
BIGGER = 1,
};

static compare_result compare_symbols(const symbol& a, const symbol& b, order_method_t method);

//Transforming a string into a parsed symbol, setting an optional base root or leaving it to a default evaluation.
std::optional<concrete_symbol> resolve_expr(const std::string_view& str, const pugi::xml_node* base=nullptr) const;
std::optional<symbol> resolve_expr(const std::string_view& str, const pugi::xml_node* base=nullptr) const;

std::vector<pugi::xml_attribute> prepare_props_data(const pugi::xml_node& base, int limit, int offset, const char *filter, order_method_t::values criterion);

Expand Down
14 changes: 7 additions & 7 deletions schemas/vm.gperf
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ struct command_entry_t{
};

%{
auto op_if = +[](std::stack<concrete_symbol>& stack, size_t N){
auto op_if = +[](std::stack<symbol>& stack, size_t N){
auto condition = stack.top();
stack.pop();
auto if_true = stack.top();
Expand All @@ -24,10 +24,10 @@ auto op_if = +[](std::stack<concrete_symbol>& stack, size_t N){
%}

%%
"nop", {+[](std::stack<concrete_symbol>& stack, size_t N){return error_t::OK;}, 0}
"(", {+[](std::stack<concrete_symbol>& stack, size_t N){return error_t::OK;}, 0}
")", {+[](std::stack<concrete_symbol>& stack, size_t N){return error_t::OK;}, 0}
"rem", {+[](std::stack<concrete_symbol>& stack, size_t N){for(int i=0;i<N;i++){stack.pop();}return repl::error_t::OK;}, 1, MAX_ARITY}
"nop", {+[](std::stack<symbol>& stack, size_t N){return error_t::OK;}, 0}
"(", {+[](std::stack<symbol>& stack, size_t N){return error_t::OK;}, 0}
")", {+[](std::stack<symbol>& stack, size_t N){return error_t::OK;}, 0}
"rem", {+[](std::stack<symbol>& stack, size_t N){for(int i=0;i<N;i++){stack.pop();}return repl::error_t::OK;}, 1, MAX_ARITY}
"cat", VS_OPERATOR_N_HELPER(+=,std::string)
"add", VS_OPERATOR_N_MATH_HELPER(+=)
"+", VS_OPERATOR_N_MATH_HELPER(+=)
Expand All @@ -47,7 +47,7 @@ auto op_if = +[](std::stack<concrete_symbol>& stack, size_t N){
"!", VS_OPERATOR_1_HELPER(~,int)
"count.1", VS_OPERATOR_1_HELPER(__builtin_popcount,int)
"count.0", VS_OPERATOR_1_HELPER(sizeof(int)*8-__builtin_popcount,int)
"true", {+[](std::stack<concrete_symbol>& stack, size_t N){stack.push(true);return error_t::OK;}, 0}
"false", {+[](std::stack<concrete_symbol>& stack, size_t N){stack.push(false);return error_t::OK;}, 0}
"true", {+[](std::stack<symbol>& stack, size_t N){stack.push(true);return error_t::OK;}, 0}
"false", {+[](std::stack<symbol>& stack, size_t N){stack.push(false);return error_t::OK;}, 0}
"?", {op_if, 3, 3}
%%
42 changes: 21 additions & 21 deletions src/stack-lang.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
#include "stack-lang.hpp"

#define VS_OPERATOR_N_MATH_HELPER(OPERATOR) \
{ +[](std::stack<concrete_symbol>& stack, size_t N){\
{ +[](std::stack<symbol>& stack, size_t N){\
enum {NONE, INT, FLOAT} type = NONE;\
int ret_i = 0;\
float ret_f = 0.0;\
Expand All @@ -39,7 +39,7 @@
}, 2, MAX_ARITY}

#define VS_OPERATOR_1_MATH_HELPER(OPERATOR) \
{ +[](std::stack<concrete_symbol>& stack, size_t N){\
{ +[](std::stack<symbol>& stack, size_t N){\
enum {NONE, INT, FLOAT} type;\
int ret_i;\
float ret_f;\
Expand All @@ -62,7 +62,7 @@
}, 1}

#define VS_OPERATOR_CMP_HELPER(OPERATOR) \
{ +[](std::stack<concrete_symbol>& stack, size_t N){\
{ +[](std::stack<symbol>& stack, size_t N){\
auto a = std::move(stack.top());\
stack.pop();\
if(std::holds_alternative<int>(a)){\
Expand All @@ -86,7 +86,7 @@
}, 2}

#define VS_OPERATOR_N_HELPER(OPERATOR, TYPE) \
{ +[](std::stack<concrete_symbol>& stack, size_t N){\
{ +[](std::stack<symbol>& stack, size_t N){\
TYPE ret = TYPE ();\
for(size_t i = 0;i<N;i++){\
auto tmp = std::move(stack.top());\
Expand All @@ -100,7 +100,7 @@
}, 2, MAX_ARITY}

#define VS_OPERATOR_1_HELPER(OPERATOR, TYPE) \
{ +[](std::stack<concrete_symbol>& stack, size_t N){\
{ +[](std::stack<symbol>& stack, size_t N){\
TYPE ret;\
auto tmp = std::move(stack.top());\
stack.pop();\
Expand All @@ -115,24 +115,24 @@ namespace vs{
namespace templ{


bool repl::push_operand(const concrete_symbol& ref)noexcept{
bool repl::push_operand(const symbol& ref)noexcept{
stack.push(ref);
//TODO: for now the assumption is no memory failure
return true;
}

std::optional<concrete_symbol> repl::eval(const char* expr) noexcept{
std::optional<symbol> repl::eval(const char* expr) noexcept{
static const size_t MAX_ARITY = 100;
static frozen::unordered_map<frozen::string, command_t, 38> commands = {
{"nop", {+[](std::stack<concrete_symbol>& stack, size_t N){return error_t::OK;}, 0}},
{"(", {+[](std::stack<concrete_symbol>& stack, size_t N){return error_t::OK;}, 0}},
{")", {+[](std::stack<concrete_symbol>& stack, size_t N){return error_t::OK;}, 0}},
{"nop", {+[](std::stack<symbol>& stack, size_t N){return error_t::OK;}, 0}},
{"(", {+[](std::stack<symbol>& stack, size_t N){return error_t::OK;}, 0}},
{")", {+[](std::stack<symbol>& stack, size_t N){return error_t::OK;}, 0}},

{"rem", {+[](std::stack<concrete_symbol>& stack, size_t N){for(size_t i=0;i<N;i++){stack.pop();}return repl::error_t::OK;}, 1, MAX_ARITY}},
{"dup", {+[](std::stack<concrete_symbol>& stack, size_t N){stack.push(stack.top());return repl::error_t::OK;}, 1}},
{"rem", {+[](std::stack<symbol>& stack, size_t N){for(size_t i=0;i<N;i++){stack.pop();}return repl::error_t::OK;}, 1, MAX_ARITY}},
{"dup", {+[](std::stack<symbol>& stack, size_t N){stack.push(stack.top());return repl::error_t::OK;}, 1}},

{"cat", VS_OPERATOR_N_HELPER(+=,std::string)},
{"join", {+[](std::stack<concrete_symbol>& stack, size_t N){
{"join", {+[](std::stack<symbol>& stack, size_t N){
std::string ret;
std::string sep;
{
Expand Down Expand Up @@ -195,7 +195,7 @@ std::optional<concrete_symbol> repl::eval(const char* expr) noexcept{
//{"lsh", VS_OPERATOR_N_HELPER(<<=,int)},
//{"rsh", VS_OPERATOR_N_HELPER(>>=,int)},

{"as.int", {+[](std::stack<concrete_symbol>& stack, size_t N){
{"as.int", {+[](std::stack<symbol>& stack, size_t N){
auto t=std::move(stack.top());
stack.pop();
if(std::holds_alternative<int>(t))stack.push(std::get<int>(t));
Expand All @@ -204,7 +204,7 @@ std::optional<concrete_symbol> repl::eval(const char* expr) noexcept{
else return error_t::WRONG_TYPE;
return error_t::OK;
}, 1}},
{"as.float", {+[](std::stack<concrete_symbol>& stack, size_t N){
{"as.float", {+[](std::stack<symbol>& stack, size_t N){
auto t=std::move(stack.top());
stack.pop();
if(std::holds_alternative<int>(t))stack.push((float)std::get<int>(t));
Expand All @@ -213,7 +213,7 @@ std::optional<concrete_symbol> repl::eval(const char* expr) noexcept{
else return error_t::WRONG_TYPE;
return error_t::OK;
}, 1}},
{"as.str", {+[](std::stack<concrete_symbol>& stack, size_t N){
{"as.str", {+[](std::stack<symbol>& stack, size_t N){
auto t=std::move(stack.top());
stack.pop();
if(std::holds_alternative<int>(t))stack.push(std::to_string(std::get<int>(t)));
Expand All @@ -225,11 +225,11 @@ std::optional<concrete_symbol> repl::eval(const char* expr) noexcept{


///Constants
{"APOS", {+[](std::stack<concrete_symbol>& stack, size_t N){stack.push("`");return error_t::OK;}, 0}},
{"PIPE", {+[](std::stack<concrete_symbol>& stack, size_t N){stack.push("|");return error_t::OK;}, 0}},
{"true", {+[](std::stack<concrete_symbol>& stack, size_t N){stack.push(true);return error_t::OK;}, 0}},
{"false", {+[](std::stack<concrete_symbol>& stack, size_t N){stack.push(false);return error_t::OK;}, 0}},
{"?", {+[](std::stack<concrete_symbol>& stack, size_t N){
{"APOS", {+[](std::stack<symbol>& stack, size_t N){stack.push("`");return error_t::OK;}, 0}},
{"PIPE", {+[](std::stack<symbol>& stack, size_t N){stack.push("|");return error_t::OK;}, 0}},
{"true", {+[](std::stack<symbol>& stack, size_t N){stack.push(true);return error_t::OK;}, 0}},
{"false", {+[](std::stack<symbol>& stack, size_t N){stack.push(false);return error_t::OK;}, 0}},
{"?", {+[](std::stack<symbol>& stack, size_t N){
auto condition = stack.top();
stack.pop();
auto if_true = stack.top();
Expand Down
2 changes: 1 addition & 1 deletion src/symbols.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
namespace vs{
namespace templ{

std::optional<std::string> to_string(const concrete_symbol& val){
std::optional<std::string> to_string(const symbol& val){
if(std::holds_alternative<int>(val))return std::to_string(std::get<int>(val));
else if(std::holds_alternative<float>(val))return std::to_string(std::get<float>(val));
else if(std::holds_alternative<std::string>(val))return std::get<std::string>(val);
Expand Down
8 changes: 7 additions & 1 deletion src/vs-templ.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -38,10 +38,16 @@ void preprocessor::log(log_t::values type, const std::string& str) const{
logfn(type,str.data(),ctx);
}

preprocessor::compare_result preprocessor::compare_symbols(const symbol& a, const symbol& b, order_method_t method){
//TODO: Implement
return compare_result::NOT_COMPARABLE;
}


//TODO: The next release of pugixml will have support for string_views directly.
// As such, the double buffer to add \0 around will no longer be needed.
// Once that is done, please revise this function to make it much faster.
std::optional<concrete_symbol> preprocessor::resolve_expr(const std::string_view& _str, const pugi::xml_node* base) const{
std::optional<symbol> preprocessor::resolve_expr(const std::string_view& _str, const pugi::xml_node* base) const{
int str_len = _str.size();
char str[str_len+1];
memcpy(str,_str.data(),str_len+1);
Expand Down

0 comments on commit 8ace8e8

Please sign in to comment.