diff --git a/src/parsers/scripting/javascript/JSParser.cpp b/src/parsers/scripting/javascript/JSParser.cpp new file mode 100644 index 0000000..51e7cf8 --- /dev/null +++ b/src/parsers/scripting/javascript/JSParser.cpp @@ -0,0 +1,142 @@ +#include "JSParser.h" +#include +#include +#include + +class js_scope { +public: + js_scope *parent; + js_scope() { + parent = nullptr; + } + std::map variables; +}; + +std::shared_ptr JSParser::parse(const std::string &source) const { + std::shared_ptr ret = std::make_shared(); + std::shared_ptr global = std::make_shared(); + std::cout << "source: " << source << "\n" << std::endl; + // tokenize it + unsigned int cursor; + int state = 0; + int last = 0; + int quoteStart = 0; + int scopeLevel = 0; + int jsonStart = 0; + int jsonLevel = 0; + int functionStart = 0; + // each token is one statement + std::vector tokens; + for (cursor = 0; cursor < source.length(); cursor++) { + if (state == 0) { + if (source[cursor] == '{') { + state = 1; // JSON + jsonStart = cursor; + jsonLevel++; + //std::cout << "Entering JSON: " << cursor << std::endl; + } else if (source[cursor] == '\'') { // quotes just for allowing [;{}\n] in quotes + quoteStart = cursor; + state = 4; + } else if (source[cursor] == '"') { + quoteStart = cursor; + state = 5; + } else if (source[cursor] == '/' && source.length() > cursor + 1 && source[cursor + 1] == '/') { + // single line comment + state = 2; + } else if (source[cursor] == '/' && source.length() > cursor + 1 && source[cursor + 1] == '*') { + // Multiline comment + state = 3; + } else if (source[cursor] == 'v' && source.length() > cursor + 3 && source[cursor + 1] == 'a' + && source[cursor + 2] == 'r' && source[cursor + 3] == ' ') { + // var + state = 7; + } else if (source[cursor] == 'f' && source.length() > cursor + 8 && source[cursor + 1] == 'u' + && source[cursor + 2] == 'n' && source[cursor + 3] == 'c' && source[cursor + 4] == 't' + && source[cursor + 5] == 'i' && source[cursor + 6] == 'o' && source[cursor + 7] == 'n') { + //std::cout << "Entering function: " << cursor << std::endl; + state = 6; + functionStart = cursor; + } + } else if (state == 1) { + // inside a scope (JSON) + if (source[cursor] == '{') { + jsonLevel++; + } else + if (source[cursor] == '}') { + jsonLevel--; + if (!jsonLevel) { + std::cout << "Exiting JSON: " << source.substr(jsonStart, cursor - jsonStart) << std::endl; + state = 0; // exit JSON + } + } + } else if (state == 2) { + // inside a single line comment + if (source[cursor] == '\n') { + state = 0; + } + } else if (state == 3) { + // inside a multiline comment + if (source[cursor] == '*' && source.length() > cursor + 1 && source[cursor + 1] == '/') { + // end multiline comment + state = 0; + } + } else if (state == 4) { + // inside single quote + if (source[cursor] == '\'') { + if (source[cursor - 1] != '\\') { + //std::string quote = source.substr(quoteStart + 1, cursor - quoteStart - 1); + //std::cout << "single quote: " << quote << std::endl; + state = 0; + } + } + } else if (state == 5) { + // inside double quote + if (source[cursor] == '"') { + if (source[cursor - 1] != '\\') { + //std::string quote = source.substr(quoteStart + 1, cursor - quoteStart - 1); + //std::cout << "double quote: " << quote << std::endl; + state = 0; + } + } + } else if (state == 7) { + } + + // + if (source[cursor] == '{') { + scopeLevel++; + } + bool endIt = false; + if (source[cursor] == '}') { + scopeLevel--; + if (state == 6 && !scopeLevel) { + std::cout << "Exiting function: " << source.substr(functionStart, cursor - functionStart) << std::endl; + state = 0; + endIt = true; + } + } + + // state 0 or 7, ignore states 1-6 + if ((state == 0 || state == 7) && !scopeLevel) { + if (source[cursor] == '\n' || source[cursor] == ';' || endIt) { + // FIXME: ; in for loops + std::string token = source.substr(last ? last + 1 : last, last ? (cursor - last - 1) : cursor ); + if (source[cursor] == '}') { + token += '}'; + } + // scopeLevel[" << scopeLevel << "]" + std::cout << "got token [" << token << "] ending[" << source[cursor] << "] endIt[" << endIt << "]" << std::endl; + tokens.push_back(token); + last = cursor; + + if (state == 7) { // allow var constructs to end normally and take us out of var construct + state = 0; // reset state + } + } + } + } + std::cout << "out of characters in state " << state << std::endl; + std::string token = source.substr(last ? last + 1 : last, last ? (cursor - last - 1) : cursor ); + tokens.push_back(token); + std::cout << "got token [" << token << "] ending[" << source[cursor] << "]" << std::endl; + return ret; +} diff --git a/src/parsers/scripting/javascript/JSParser.h b/src/parsers/scripting/javascript/JSParser.h new file mode 100644 index 0000000..c2c01b8 --- /dev/null +++ b/src/parsers/scripting/javascript/JSParser.h @@ -0,0 +1,15 @@ +#ifndef JSPARSER_H +#define JSPARSER_H + +#include + +class JavaScript { + +}; + +class JSParser { +public: + std::shared_ptr parse(const std::string &javascript) const; +}; + +#endif