|
|
|
@ -8,7 +8,6 @@
@@ -8,7 +8,6 @@
|
|
|
|
|
#include <iostream> |
|
|
|
|
#include <memory> |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Internal JS types: String, Number, Function, Array, Object
|
|
|
|
|
// blocks/scopes?
|
|
|
|
|
class js_internal_storage { |
|
|
|
@ -20,9 +19,12 @@ public:
@@ -20,9 +19,12 @@ public:
|
|
|
|
|
// toArray
|
|
|
|
|
// toObject
|
|
|
|
|
// toReference
|
|
|
|
|
// toForward
|
|
|
|
|
virtual ~js_internal_storage() = default; |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
// deprecated
|
|
|
|
|
/*
|
|
|
|
|
class js_scope { |
|
|
|
|
public: |
|
|
|
|
js_scope *parent; |
|
|
|
@ -38,8 +40,13 @@ public:
@@ -38,8 +40,13 @@ public:
|
|
|
|
|
// feel like we need an instruction pointer...
|
|
|
|
|
// esp. for loops
|
|
|
|
|
// but how we address tokens, by index?
|
|
|
|
|
// could just be strings tbh
|
|
|
|
|
//std::vector<std::string> forwardExpressions;
|
|
|
|
|
std::vector<std::string> forwardCalls; |
|
|
|
|
}; |
|
|
|
|
*/ |
|
|
|
|
|
|
|
|
|
// maybe singletons?
|
|
|
|
|
class js_bool : public js_internal_storage { |
|
|
|
|
public: |
|
|
|
|
bool value; |
|
|
|
@ -55,10 +62,9 @@ public:
@@ -55,10 +62,9 @@ public:
|
|
|
|
|
signed long value; |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
class js_function : public js_internal_storage { |
|
|
|
|
class js_object : public js_internal_storage { |
|
|
|
|
public: |
|
|
|
|
std::vector<std::string> tokens; |
|
|
|
|
js_scope scope; |
|
|
|
|
std::map<std::string, js_internal_storage *> value; |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
class js_array : public js_internal_storage { |
|
|
|
@ -66,49 +72,99 @@ public:
@@ -66,49 +72,99 @@ public:
|
|
|
|
|
std::vector<js_internal_storage> value; |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
class js_object : public js_internal_storage { |
|
|
|
|
// we probably should extend js_object
|
|
|
|
|
class js_function : public js_internal_storage { |
|
|
|
|
public: |
|
|
|
|
// I think 2nd needs to be a pointer...
|
|
|
|
|
std::map<std::string, js_internal_storage *> value; |
|
|
|
|
std::vector<std::string> tokens; |
|
|
|
|
std::vector<std::string> parameters; |
|
|
|
|
js_function *parentScope = nullptr; |
|
|
|
|
js_object locals; |
|
|
|
|
//js_scope scope;
|
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
class js_reference : public js_internal_storage { |
|
|
|
|
public: |
|
|
|
|
js_internal_storage *ptr; |
|
|
|
|
js_internal_storage *ptr; // to a function
|
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
class js_forward : public js_internal_storage { |
|
|
|
|
public: |
|
|
|
|
std::string expression; |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
bool doAssignment(js_scope &rootScope, std::string token); |
|
|
|
|
size_t parseFunctionBody(std::string source, size_t start); |
|
|
|
|
std::string typeOfStorage(js_internal_storage *storage); |
|
|
|
|
// should this be a member function?
|
|
|
|
|
js_internal_storage *jsLocateKey(const js_function *scope, const std::string key); |
|
|
|
|
|
|
|
|
|
// left side deference
|
|
|
|
|
js_internal_storage **getObjectKeyPointer(const std::string input, const js_function *scope); |
|
|
|
|
// right side deference
|
|
|
|
|
js_internal_storage *dereferenceObject(const std::string input, const js_function *scope); |
|
|
|
|
js_function *makeFunctionFromString(const std::string body, const std::string prototype, js_function *parent); |
|
|
|
|
// FIXME: should be a member function
|
|
|
|
|
void jsDisplayScope(const js_function *scope, size_t level); |
|
|
|
|
size_t findClosing(std::string token, size_t start, char open, char close); |
|
|
|
|
size_t locateFunctionNameEnd(std::string source, size_t start); |
|
|
|
|
size_t locateFunctionParamsEnd(std::string source, size_t start); |
|
|
|
|
|
|
|
|
|
// locate the end of single quoted expression
|
|
|
|
|
// start after ', return at '
|
|
|
|
|
size_t locateSingleQuoteEnd(const std::string source, const size_t start); |
|
|
|
|
|
|
|
|
|
// locate the end of double quoted expression
|
|
|
|
|
// start after ", return at "
|
|
|
|
|
size_t locateDoubleQuoteEnd(const std::string source, const size_t start); |
|
|
|
|
size_t locateRegexEnd(const std::string source, const size_t start); |
|
|
|
|
size_t getNextExpression(const std::string source, const size_t start); |
|
|
|
|
size_t parseFunctionBody(std::string source, size_t start); |
|
|
|
|
|
|
|
|
|
js_internal_storage *doFunctionCall(js_function *func, std::string params, js_function &scope); |
|
|
|
|
js_internal_storage *doExpression(js_function &rootScope, std::string token); |
|
|
|
|
bool doAssignment(js_function &rootScope, std::string token); |
|
|
|
|
|
|
|
|
|
void parseArray(js_function &rootScope, std::string token); |
|
|
|
|
js_internal_storage *parseExpression(js_function &rootScope, std::string token); |
|
|
|
|
void parseJSON(js_function &rootScope, std::string token); |
|
|
|
|
|
|
|
|
|
std::vector<std::string> jsGetTokens(const std::string &source, const size_t start); |
|
|
|
|
// belongs in js_function
|
|
|
|
|
js_internal_storage *jsParseTokens(const std::vector<std::string> &tokens, js_function *scope); |
|
|
|
|
|
|
|
|
|
class JavaScript { |
|
|
|
|
public: |
|
|
|
|
JavaScript() { |
|
|
|
|
this->setUpRoot(); |
|
|
|
|
} |
|
|
|
|
void setUpRoot() { |
|
|
|
|
// set up default window reference
|
|
|
|
|
js_reference *window = new js_reference; |
|
|
|
|
window->ptr = &rootScope; |
|
|
|
|
rootScope.locals.value["window"] = window; |
|
|
|
|
} |
|
|
|
|
void clear() { |
|
|
|
|
tokens.clear(); |
|
|
|
|
/*
|
|
|
|
|
rootScope.parent = nullptr; |
|
|
|
|
rootScope.children.clear(); |
|
|
|
|
rootScope.variables.clear(); |
|
|
|
|
*/ |
|
|
|
|
delete rootScope.locals.value["window"]; |
|
|
|
|
this->setUpRoot(); |
|
|
|
|
rootScope.locals.value.clear(); |
|
|
|
|
} |
|
|
|
|
// has to be called after the scopes are applied
|
|
|
|
|
// actually maybe not with the forward system and parse/exec split
|
|
|
|
|
void parse(const std::string); |
|
|
|
|
void append(const std::shared_ptr<JavaScript> &source); |
|
|
|
|
void applyScope(const std::shared_ptr<JavaScript> &source); |
|
|
|
|
void execute(); |
|
|
|
|
// each token is one statement
|
|
|
|
|
std::vector<std::string> tokens; |
|
|
|
|
// we're just settings the rootScope.variables
|
|
|
|
|
std::vector<std::string> definitions; // all var declarations and their expressions
|
|
|
|
|
std::vector<std::string> instructions; // then a list of all remaining expressions and function calls
|
|
|
|
|
js_scope rootScope; |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
js_internal_storage *parseExpression(js_scope &rootScope, std::string token); |
|
|
|
|
void parseArray(js_scope &rootScope, std::string token); |
|
|
|
|
void parseJSON(js_scope &rootScope, std::string token); |
|
|
|
|
|
|
|
|
|
// this is no members could all be static
|
|
|
|
|
class JSParser { |
|
|
|
|
public: |
|
|
|
|
//std::shared_ptr<JavaScript> parse(const std::string &javascript) const;
|
|
|
|
|
void parseTokens(const std::vector<std::string> &tokens, js_scope *scope) const; |
|
|
|
|
std::vector<std::string> getTokens(const std::string &source) const; |
|
|
|
|
std::shared_ptr<JavaScript> append(std::shared_ptr<JavaScript> &destination, const std::shared_ptr<JavaScript> &source) const; |
|
|
|
|
js_function rootScope; |
|
|
|
|
//js_scope rootScope;
|
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
#endif |
|
|
|
|