Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.

JSParser.h 5.8KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187
  1. #ifndef JSPARSER_H
  2. #define JSPARSER_H
  3. #include <string>
  4. #include <vector>
  5. #include <map>
  6. // for gcc & shared_ptr
  7. #include <iostream>
  8. #include <memory>
  9. // Internal JS types: String, Number, Function, Array, Object
  10. // blocks/scopes?
  11. class js_internal_storage {
  12. public:
  13. // toBool
  14. // toString
  15. // toNumber
  16. // toFunction
  17. // toArray
  18. // toElement
  19. // toObject
  20. // toReference
  21. // toForward
  22. virtual ~js_internal_storage() = default;
  23. };
  24. // deprecated
  25. /*
  26. class js_scope {
  27. public:
  28. js_scope *parent;
  29. // what do we need children for?
  30. // a callstack only includes it's parents (in JS?)
  31. std::vector<js_scope> children;
  32. js_scope() {
  33. parent = nullptr;
  34. }
  35. std::map<std::string, std::string> variables;
  36. std::map<std::string, js_internal_storage *> data;
  37. // maybe a vector of resolve on execution assignments...
  38. // feel like we need an instruction pointer...
  39. // esp. for loops
  40. // but how we address tokens, by index?
  41. // could just be strings tbh
  42. //std::vector<std::string> forwardExpressions;
  43. std::vector<std::string> forwardCalls;
  44. };
  45. */
  46. // maybe singletons?
  47. class js_bool : public js_internal_storage {
  48. public:
  49. bool value;
  50. };
  51. class js_string : public js_internal_storage {
  52. public:
  53. std::string value;
  54. };
  55. class js_number : public js_internal_storage {
  56. public:
  57. double value;
  58. };
  59. class js_object : public js_internal_storage {
  60. public:
  61. std::map<std::string, js_internal_storage *> value;
  62. };
  63. class js_array : public js_internal_storage {
  64. public:
  65. std::vector<js_internal_storage *> value;
  66. };
  67. class Node; // fwd declr
  68. class js_element : public js_internal_storage {
  69. public:
  70. Node *value; // shared_ptr ?
  71. };
  72. class JavaScript; // fwd declr
  73. // we probably should extend js_object
  74. class js_function : public js_internal_storage {
  75. public:
  76. std::vector<std::string> tokens;
  77. std::vector<std::string> parameters; // incoming call or defined vars?
  78. js_function *parentScope = nullptr;
  79. js_object locals;
  80. JavaScript *script = nullptr; // can store any type of JavaScript
  81. //js_scope scope;
  82. };
  83. class js_reference : public js_internal_storage {
  84. public:
  85. js_internal_storage *ptr; // to a function
  86. };
  87. class js_forward : public js_internal_storage {
  88. public:
  89. std::string expression;
  90. };
  91. std::string typeOfStorage(js_internal_storage *storage);
  92. // should this be a member function?
  93. js_internal_storage *jsLocateKey(const js_function *scope, const std::string key);
  94. // left side deference
  95. js_internal_storage **getObjectKeyPointer(const std::string input, const js_function *scope);
  96. // right side deference
  97. js_internal_storage *dereferenceObject(const std::string input, const js_function *scope);
  98. bool dereferenceHasBase(const std::string input, const js_function *scope);
  99. js_function *makeFunctionFromString(const std::string body, const std::string prototype, js_function *parent);
  100. // FIXME: should be a member function
  101. void jsDisplayScope(const js_function *scope, size_t level);
  102. size_t findClosing(std::string token, size_t start, char open, char close);
  103. size_t locateFunctionNameEnd(std::string source, size_t start);
  104. size_t locateFunctionParamsEnd(std::string source, size_t start);
  105. // locate the end of single quoted expression
  106. // start after ', return at '
  107. size_t locateSingleQuoteEnd(const std::string source, const size_t start);
  108. // locate the end of double quoted expression
  109. // start after ", return at "
  110. size_t locateDoubleQuoteEnd(const std::string source, const size_t start);
  111. size_t locateRegexEnd(const std::string source, const size_t start);
  112. size_t getNextExpression(const std::string source, const size_t start);
  113. size_t parseFunctionBody(std::string source, size_t start);
  114. //js_internal_storage *doFunctionCall(js_function *func, std::string params, js_function &scope);
  115. js_internal_storage *jsFunctionCall(std::string funcName, js_function *func, std::string params, js_function &scope);
  116. js_internal_storage *doExpression(js_function &rootScope, std::string token);
  117. bool doAssignment(js_function &rootScope, std::string token);
  118. void parseArray(js_function &rootScope, std::string token);
  119. js_array *jsGetArray(js_function &rootScope, std::string token);
  120. //js_internal_storage *parseExpression(js_function &rootScope, std::string token);
  121. void parseJSON(js_function &rootScope, std::string token);
  122. js_object *jsGetObject(js_function &rootScope, std::string token);
  123. std::vector<std::string> jsGetTokens(const std::string &source, const size_t start);
  124. // belongs in js_function
  125. js_internal_storage *jsParseTokens(const std::vector<std::string> &tokens, js_function *scope);
  126. class JavaScript {
  127. public:
  128. JavaScript() {
  129. this->setUpRoot();
  130. }
  131. virtual ~JavaScript() = default;
  132. void setUpRoot() {
  133. // set up default window reference
  134. js_reference *window = new js_reference;
  135. window->ptr = &rootScope;
  136. this->rootScope.locals.value["window"] = window;
  137. this->rootScope.script = this;
  138. }
  139. void clear() {
  140. tokens.clear();
  141. /*
  142. rootScope.parent = nullptr;
  143. rootScope.children.clear();
  144. rootScope.variables.clear();
  145. */
  146. delete rootScope.locals.value["window"];
  147. this->setUpRoot();
  148. rootScope.locals.value.clear();
  149. }
  150. // has to be called after the scopes are applied
  151. // actually maybe not with the forward system and parse/exec split
  152. void parse(const std::string);
  153. void append(const std::shared_ptr<JavaScript> &source);
  154. void applyScope(const std::shared_ptr<JavaScript> &source);
  155. void execute(); // probably not needed
  156. // each token is one statement
  157. std::vector<std::string> tokens;
  158. // we're just settings the rootScope.variables
  159. std::vector<std::string> definitions; // all var declarations and their expressions
  160. std::vector<std::string> instructions; // then a list of all remaining expressions and function calls
  161. js_function rootScope;
  162. //js_scope rootScope;
  163. };
  164. #endif