fork download
  1. #include <iostream>
  2. #include <functional>
  3. #include <vector>
  4. #include <string>
  5. #include <sstream>
  6. #include <algorithm>
  7. #include <unordered_map>
  8. #include <iterator>
  9. #include <cassert>
  10. using namespace std;
  11.  
  12. //boring helper functions
  13. inline std::string trim(const std::string &s) {
  14. auto wsfront=std::find_if_not(s.begin(),s.end(),[](int c){return std::isspace(c);});
  15. return std::string(wsfront,std::find_if_not(s.rbegin(),std::string::const_reverse_iterator(wsfront),[](int c){return std::isspace(c);}).base());
  16. }
  17.  
  18. vector<string> str_to_tokens(string const &src) {
  19. istringstream stream(src);
  20. return {
  21. istream_iterator<string>{stream},
  22. istream_iterator<string>{}
  23. };
  24. }
  25.  
  26. string join(vector<string> const &vec, string const &delim) {
  27. stringstream res;
  28. copy(vec.begin(), vec.end(), ostream_iterator<string>(res, delim.c_str()));
  29. return res.str();
  30. }
  31.  
  32. //scaffolding
  33. using arguments = vector<string>;
  34. using command = function<void(arguments const &)>;
  35. using commands = unordered_map<string, command>;
  36. using middleware = function<void(arguments &)>;
  37. using middlewares = vector<middleware>;
  38.  
  39. //bullshit that matters
  40. void print(arguments const &args) {
  41. for(auto &&arg: args) {
  42. cout << arg << " ";
  43. }
  44. cout << endl;
  45. }
  46.  
  47. struct data_store {
  48. using vname = string;
  49. using vval = string;
  50. unordered_map<vname, vval> vars;
  51.  
  52. void store(vname const &name, vval const &val) {
  53. vars[name] = val;
  54. }
  55.  
  56. void store_cmd(arguments const &args) {
  57. enum { VNAME, VEQSIGN, VVAL_BEG };
  58. assert(args[VEQSIGN] == "=");
  59. auto val = join({begin(args)+VVAL_BEG, end(args)}, " ");
  60. store(args[VNAME], trim(val));
  61. }
  62.  
  63. vval get(vname const &name) const {
  64. return vars.at(name);
  65. }
  66. };
  67.  
  68. void replace_vars_with_values(data_store const &store, string const &var_prefix, arguments &args) {
  69. for(auto &arg: args) {
  70. if(arg.rfind(var_prefix, 0) == 0) {
  71. arg = store.get(string{begin(arg)+var_prefix.size(), end(arg)});
  72. }
  73. }
  74. }
  75.  
  76. void apply_middlewares(middlewares const &mdws, arguments &args) {
  77. for(auto &&mdw: mdws) {
  78. mdw(args);
  79. }
  80. }
  81.  
  82. int main() {
  83. string var_prefix = "$";
  84. data_store dstore;
  85.  
  86. middlewares mdws = {
  87. [&](arguments &args) { return replace_vars_with_values(dstore, var_prefix, args); }
  88. };
  89.  
  90. commands cmds = {
  91. {"print", print},
  92. {"var", [&dstore](arguments const &args) { dstore.store_cmd(args); }}
  93. };
  94.  
  95. string input;
  96. while(getline(cin, input)) {
  97. if(input.empty()) {
  98. continue;
  99. }
  100. auto tokens = str_to_tokens(input);
  101. apply_middlewares(mdws, tokens);
  102.  
  103. enum { FUNC_POS, ARGS_START };
  104.  
  105. cmds.at(tokens[FUNC_POS])(arguments{begin(tokens)+ARGS_START, end(tokens)});
  106. }
  107. return 0;
  108. }
Success #stdin #stdout 0s 16072KB
stdin
var person = Ala
var state = ma dziwnego kota.
var f = print

$f $person $state
stdout
Ala ma dziwnego kota.