Переглянути джерело

scope refactor, forward type, prototypes, Javascript refactor

Odilitime 2 роки тому
1 змінених файлів з 80 додано та 24 видалено
  1. 80

+ 80
- 24
src/parsers/scripting/javascript/JSParser.h Переглянути файл

@@ -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:
// toArray
// toObject
// toReference
// toForward
virtual ~js_internal_storage() = default;

// deprecated
class js_scope {
js_scope *parent;
@@ -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 {
bool value;
@@ -55,10 +62,9 @@ public:
signed long value;

class js_function : public js_internal_storage {
class js_object : public js_internal_storage {
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:
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 {
// 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 {
js_internal_storage *ptr;
js_internal_storage *ptr; // to a function

class js_forward : public js_internal_storage {
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 {
JavaScript() {
void setUpRoot() {
// set up default window reference
js_reference *window = new js_reference;
window->ptr = &rootScope;
rootScope.locals.value["window"] = window;
void clear() {
rootScope.parent = nullptr;
delete rootScope.locals.value["window"];
// 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 {
//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;