Browse Source

doFunctionCall() actually return return value, doExpression() handle ) only once / if func value hang around to see if it's called first before changing stack, parseJSON wait for , before reseting keyState, doAssignment() check to see if func is called before setting stack, JavaScript::parse() disable debug

master
Odilitime 2 years ago
parent
commit
79bd205eb7
1 changed files with 147 additions and 23 deletions
  1. 147
    23
      src/parsers/scripting/javascript/JSParser.cpp

+ 147
- 23
src/parsers/scripting/javascript/JSParser.cpp View File

@@ -285,8 +285,7 @@ js_internal_storage *doFunctionCall(js_function *func, std::string params, js_fu
std::cout << "passed null into doFunctionCall\n";
return nullptr;
}
jsParseTokens(func->tokens, &scope);
return nullptr;
return jsParseTokens(func->tokens, &scope);
}

// this should evaluate an expression and return it's return value
@@ -303,6 +302,7 @@ js_internal_storage *doExpression(js_function &rootScope, std::string token) {
std::cout << "doExpression start[" << token << "]\n";
// parse expression
for (cursor = 0; cursor < token.length(); cursor++) {
std::cout << "doExpression parse phase state[" << std::to_string(state) << "] char[" << token[cursor] << "]\n";
if (state == 0) {
// ||
// &&
@@ -497,7 +497,7 @@ js_internal_storage *doExpression(js_function &rootScope, std::string token) {
if (token[cursor] == ')') {
parenLevel--;
if (!parenLevel) {
expression_parts.push_back(token.substr(last, cursor - last)); last = cursor;
expression_parts.push_back(token.substr(last, cursor - last)); last = cursor + 1;
expression_parts.push_back(")");
state = 0;
}
@@ -526,13 +526,16 @@ js_internal_storage *doExpression(js_function &rootScope, std::string token) {
std::cout << "doExpression has [" << expression_parts.size() << "]parts\n";
js_internal_storage *stack = nullptr;
state = 0;
std::string callFunc = "";
std::string callFuncName = "";
js_function *callFunc = nullptr;
std::string params = "";
//js_function *func = nullptr;
size_t i = 0;
for(auto it : expression_parts) {
std::string trimmedToken = trim(it);
i++;
if (trimmedToken == "") continue;
std::cout << "doExpression part[" << it << "] state[" << std::to_string(state) << "]\n";
std::cout << "doExpression part[" << (i - 1) << "][" << it << "] state[" << std::to_string(state) << "]\n";
if (state == 0) {
// &&
if (trimmedToken == "&&") {
@@ -594,6 +597,7 @@ js_internal_storage *doExpression(js_function &rootScope, std::string token) {
if (trimmedToken == "(") {
// function call
std::cout << "func call param start\n";
state = 2;
continue;
}
@@ -620,11 +624,16 @@ js_internal_storage *doExpression(js_function &rootScope, std::string token) {
// object.property
js_internal_storage *dereferenceTest = dereferenceObject(trimmedToken, &rootScope);
if (dereferenceTest) {
stack = dereferenceTest;
if (typeOfStorage(stack)=="func") {
if (typeOfStorage(dereferenceTest)=="func") {
// it could be a call...
callFunc = it;
callFuncName = it;
callFunc = dynamic_cast<js_function *>(dereferenceTest);
if (!callFunc) {
std::cout << "Couldnt cast deference to func\n";
}
state = 1;
} else {
stack = dereferenceTest;
}
continue;
}
@@ -677,14 +686,16 @@ js_internal_storage *doExpression(js_function &rootScope, std::string token) {
js_internal_storage **isVar = getObjectKeyPointer(it, &rootScope);
if (isVar != nullptr) {
std::cout << "isVar [" << isVar << "]\n";
stack = *isVar; // set stack to point to this variable
std::cout << "stack is [" << stack << "] type[" << typeOfStorage(stack) << "]\n";
std::cout << "stack could be [" << *isVar << "] type[" << typeOfStorage(stack) << "]\n";
if (typeOfStorage(stack)=="func") {
callFunc = it;
callFuncName = it;
callFunc = dynamic_cast<js_function *>(dereferenceTest);
state = 1;
// (
// 1
// )
} else {
stack = *isVar; // set stack to point to this variable
}
/*
if (typeOfStorage(stack)=="string") {
@@ -706,7 +717,9 @@ js_internal_storage *doExpression(js_function &rootScope, std::string token) {
if (it == "(") {
state = 2;
} else {
std::cout << "func call did not have (\n";
std::cout << "doExpression1 - func call did not have (\n";
std::cout << "doExpression1 - stack is [" << stack << "] will now have to set it to [" << callFunc << "]\n";
stack = callFunc;
state = 0;
}
} else if (state == 2) {
@@ -715,16 +728,24 @@ js_internal_storage *doExpression(js_function &rootScope, std::string token) {
} else if (state == 3) {
// in func call, double check the )
if (it == ")") {
/*
js_function *jfunc = dynamic_cast<js_function*>(stack);
if (!jfunc) {
std::cout << "Could cast [" << stack << "] to func\n";
continue;
}
std::cout << "calling [" << callFunc << "](" << params << ") at [" << jfunc << "] with [" << jfunc->tokens.size() << "]tokens\n";
stack = doFunctionCall(jfunc, params, rootScope);
*/
if (!callFunc) {
std::cout << "HALT callFunc is null!\n";
continue;
}
std::cout << "doExpression3 - calling [" << callFuncName << "](" << params << ") at [" << callFunc << "] with [" << callFunc->tokens.size() << "]tokens\n";
stack = doFunctionCall(callFunc, params, rootScope);
state = 0;
} else {
std::cout << "func call did not have (\n";
std::cout << "doExpression3 - func call did not have (\n";
std::cout << "doExpression3 - stack is [" << stack << "] will now have to set it to [" << callFunc << "]\n";
stack = callFunc;
state = 0;
}
} else if (state == 4) {
@@ -754,6 +775,16 @@ js_internal_storage *doExpression(js_function &rootScope, std::string token) {
}
}
// FIXME: any remainder?
if (state == 1) {
// x = func ref that's never called
std::cout << "doExpressionEND1 - func call did not have (\n";
std::cout << "doExpressionEND1 - stack is [" << stack << "] will now have to set it to [" << callFunc << "]\n";
stack = callFunc;
state = 0;
}
if (state != 0) {
std::cout << "doExpression final state[" << std::to_string(state) << "]\n";
}
return stack;
}

@@ -1552,6 +1583,7 @@ void parseJSON(js_function &rootScope, std::string token) {
}
}
last = cursor + 1;
std::cout << "remainder last now points to[" << token[last] << "] should not be comma\n";
keyState = 0;
valueState = 0;
quoteStart = 0;
@@ -1577,7 +1609,7 @@ void parseJSON(js_function &rootScope, std::string token) {
rootScope.locals.value[json_keys.back()] = newObject;
last = cursor + 1;
valueState = 0;
keyState = 0;
// let keyState 2 finish it out
}
break;
}
@@ -2028,10 +2060,12 @@ bool doAssignment(js_function &rootScope, std::string token) {
}
bool negate = false;
js_function *func = nullptr;
js_function *callFunc = nullptr;
std::string prototype = "";
std::string params = "";
for(auto it : expression_parts) {
// probably should trim these
std::cout << std::string(doAssignmentLevel * 2, ' ') << "expression(" << doAssignmentLevel << ") token[" << it << "]" << std::to_string(state) << std::endl;
std::cout << std::string(doAssignmentLevel * 2, ' ') << "doAssignment expression(" << doAssignmentLevel << ") token[" << it << "]" << std::to_string(state) << std::endl;
// default: put token in left, get op (usually =) and then get right side
if (state==0) {
negate = false;
@@ -2067,16 +2101,32 @@ bool doAssignment(js_function &rootScope, std::string token) {
}
} else if (state == 1) {
if (it == "") continue; // skip empties, don't fire the assignment too early
if (it == " ") continue; // skip empties, don't fire the assignment too early
if (it == "!") continue; // valid expression
if (it == "}") continue; // valid part of an expression (why are we getting this, should have a starting { and be in state 2)
// so these next 2 execute a function that's on the stack
// state 0: elem =
// state 1: funcName,(,proto,),;
if (it == "(") continue; // valid part of an expression
if (it == ")") continue; // valid part of an expression
if (it == "&&") continue; // valid part of an expression
if (it == "{") {
state = 2;
} else {
std::string tLeft = trim(left);
if (tLeft[0]=='"' && tLeft[tLeft.length() - 1]=='"') {
//std::cout << "dequoting[" << tLeft << "]" << std::endl;
tLeft=tLeft.substr(1, tLeft.length() - 2);
}
js_internal_storage *storage = doExpression(rootScope, it);
if (storage) {
js_function *funcTest = dynamic_cast<js_function*>(storage);
if (funcTest) {
callFunc = funcTest;
state = 9;
continue;
}
std::string tLeft = trim(left);
if (tLeft[0]=='"' && tLeft[tLeft.length() - 1]=='"') {
//std::cout << "dequoting[" << tLeft << "]" << std::endl;
tLeft=tLeft.substr(1, tLeft.length() - 2);
}
bool alreadySet = false;
size_t dotPos = tLeft.find('.');
@@ -2212,6 +2262,79 @@ bool doAssignment(js_function &rootScope, std::string token) {
// call params
std::cout << std::string(doAssignmentLevel * 2, ' ') << "HALT need to parse these params[" << it << "]\n";
}
} else if (state == 9) { // are we a function call with return value, or assigning a function reference
js_internal_storage *storage = nullptr;
// we'll need a way to get tLeft back to set it
if (it == "(") {
// it's a function call
// set state = 10 until we get all prototype
state = 10;
//storage = jsParseTokens(callFunc->tokens, callFunc);
} else {
// it's a function reference
storage = callFunc;
state = 0; // assuming end of this expression
}
if (storage) {
std::string tLeft = trim(left);
if (tLeft[0]=='"' && tLeft[tLeft.length() - 1]=='"') {
//std::cout << "dequoting[" << tLeft << "]" << std::endl;
tLeft=tLeft.substr(1, tLeft.length() - 2);
}
bool alreadySet = false;
size_t dotPos = tLeft.find('.');
if (dotPos != std::string::npos) {
js_internal_storage **key = getObjectKeyPointer(tLeft, &rootScope);
if (key != nullptr) {
alreadySet = true;
*key = storage;
}
}
if (!alreadySet) {
std::cout << "doAssignment final assign[" << tLeft << "] of type[" << typeOfStorage(storage) << "] scope[" << &rootScope << "]\n";
rootScope.locals.value[tLeft] = storage;
jsDisplayScope(&rootScope, 0);
left = ""; // reset left
assignfile << tLeft << "=" << it << "\n";
}
}
} else if (state == 10) { // in function call params
if (it == ")") {
// use doFunctionCall
js_internal_storage *storage = nullptr;
std::cout << "calling function [" << callFunc << "](" << params << ")\n";
storage = doFunctionCall(callFunc, params, rootScope);
std::cout << "function retval[" << storage << "] type[" << typeOfStorage(storage) << "]\n";
if (storage) {
std::string tLeft = trim(left);
if (tLeft[0]=='"' && tLeft[tLeft.length() - 1]=='"') {
//std::cout << "dequoting[" << tLeft << "]" << std::endl;
tLeft=tLeft.substr(1, tLeft.length() - 2);
}
bool alreadySet = false;
size_t dotPos = tLeft.find('.');
if (dotPos != std::string::npos) {
js_internal_storage **key = getObjectKeyPointer(tLeft, &rootScope);
if (key != nullptr) {
alreadySet = true;
*key = storage;
}
}
if (!alreadySet) {
std::cout << "doAssignment final assign[" << tLeft << "] of type[" << typeOfStorage(storage) << "] scope[" << &rootScope << "]\n";
rootScope.locals.value[tLeft] = storage;
jsDisplayScope(&rootScope, 0);
left = ""; // reset left
assignfile << tLeft << "=" << it << "\n";
}
}
state = 0;
} else {
// collect params
params = it;
}
}
// { starts JSON capture (should be exactly one block before the } token)
// you create a scope for that variable and recurse
@@ -2322,6 +2445,7 @@ js_internal_storage **getObjectKeyPointer(const std::string input, const js_func

js_internal_storage *dereferenceObject(const std::string input, const js_function *scope) {
// FIXME: too simple, catches quoted strings with . in them
// FIXME: make sure we're not inside quotes
size_t dotPos = input.find('.');
if (dotPos != std::string::npos) {
std::string baseObj = input.substr(0, dotPos);
@@ -2595,7 +2719,7 @@ js_internal_storage *jsParseTokens(const std::vector<std::string> &tokens, js_fu

void JavaScript::parse(const std::string source) {
// tokenize source
std::cout << "JavaScript::parse source[" << source << "]\n\n";
//std::cout << "JavaScript::parse source[" << source << "]\n\n";
this->tokens = jsGetTokens(source, 0);
jsParseTokens(this->tokens, &this->rootScope);
}

Loading…
Cancel
Save