@ -285,8 +285,7 @@ js_internal_storage *doFunctionCall(js_function *func, std::string params, js_fu
@@ -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) {
@@ -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) {
@@ -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) {
@@ -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) {
@@ -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) {
@@ -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) {
@@ -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) {
@@ -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) {
@@ -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) {
@@ -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) {
@@ -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) {
@@ -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) {
@@ -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) {
@@ -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) {
@@ -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
@@ -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
@@ -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 ) ;
}