@ -33,6 +33,14 @@ std::string typeOfStorage(js_internal_storage *storage) {
@@ -33,6 +33,14 @@ std::string typeOfStorage(js_internal_storage *storage) {
return " unknown " ;
}
bool isStrInt ( std : : string s ) {
return ( s . find_first_not_of ( " 0123456789 " ) = = std : : string : : npos ) ;
}
bool isStrRational ( std : : string s ) {
return ( s . find_first_not_of ( " 0123456789. " ) = = std : : string : : npos ) ;
}
bool jsIsFalse ( js_internal_storage * generic ) {
std : : string type = typeOfStorage ( generic ) ;
if ( type = = " string " ) {
@ -291,14 +299,42 @@ std::vector<std::string> jsGetTokens(const std::string &source, const size_t sta
@@ -291,14 +299,42 @@ std::vector<std::string> jsGetTokens(const std::string &source, const size_t sta
return tokens ;
}
js_internal_storage * jsFunctionCall ( std : : string funcName , js_function * func , std : : string params , js_function & scope ) {
js_internal_storage * jsFunctionCall ( std : : string funcName , js_function * func , std : : string paramsStr , js_function & scope ) {
if ( isConstruct ( funcName ) ) {
return executeConstruct ( funcName , params , scope ) ;
return executeConstruct ( funcName , paramsStr , scope ) ;
} else {
if ( func = = nullptr ) {
std : : cout < < " passed null into jsFunctionCall \n " ;
std : : cout < < " HALT passed null into jsFunctionCall" < < std : : endl ;
return nullptr ;
}
// what about the params?
if ( paramsStr ! = " " ) {
// FIXME: need to parse them ...
std : : vector < std : : string > opens , closes ;
opens . push_back ( " { " ) ;
opens . push_back ( " ' " ) ;
opens . push_back ( " \" " ) ;
closes . push_back ( " } " ) ;
closes . push_back ( " ' " ) ;
closes . push_back ( " \" " ) ;
auto params = parseSepButNotBetween ( paramsStr , " , " , opens , closes ) ;
// get the prototype, so we know where to assign this variables into the scope
//std::cout << "parameters supported [" << func->parameters.size() << "]" << std::endl;
uint16_t i = 0 ;
for ( auto it = func - > parameters . begin ( ) ; it ! = func - > parameters . end ( ) ; + + it ) {
std : : string value = " " ;
if ( i < params . size ( ) ) {
value = params [ i ] ;
}
js_internal_storage * storeVal = doExpression ( scope , value ) ;
std : : cout < < " Assigning prototype[ " < < * it < < " ] = [ " < < value < < " ] " < < std : : endl ;
scope . locals . value [ * it ] = storeVal ;
assignfile < < * it < < " = " < < value < < " \n " ;
i + + ;
}
// well it's implemented, just not sure how well
//std::cout << "HALT/writeme! jsFunctionCall has params[" << paramsStr << "]!" << std::endl;
}
return jsParseTokens ( func - > tokens , & scope ) ;
}
}
@ -621,6 +657,31 @@ js_internal_storage *doExpression(js_function &rootScope, std::string token) {
@@ -621,6 +657,31 @@ js_internal_storage *doExpression(js_function &rootScope, std::string token) {
continue ;
}
// handle assignemnt to stack
if ( trimmedToken = = " = " ) {
state = 6 ;
continue ;
}
/*
if ( trimmedToken [ 0 ] = = ' [ ' ) {
// like [0] potentially longer?
size_t n = std : : count ( trimmedToken . begin ( ) , trimmedToken . end ( ) , ' ] ' ) ;
if ( n ! = 1 ) {
std : : cout < < " we dont support multiple deindexes, write me \n " ;
}
// deindex
js_array * arr = dynamic_cast < js_array * > ( stack ) ;
if ( ! arr ) {
std : : cout < < " we only deindex arrarys [ " < < typeOfStorage ( stack ) < < " ], write me \n " ;
} else {
}
// don't try and deference (object.value)
continue ;
}
*/
// function name
// (
if ( trimmedToken = = " ( " ) {
@ -650,9 +711,13 @@ js_internal_storage *doExpression(js_function &rootScope, std::string token) {
@@ -650,9 +711,13 @@ js_internal_storage *doExpression(js_function &rootScope, std::string token) {
// variable
// object.property
// object.property or object[property] or [0]
// well first lets parse the key out
// then resolve the key
// then resolve the value
bool deref = dereferenceHasBase ( trimmedToken , & rootScope ) ;
if ( deref ) {
// if trimmedToken is [0] it needs the stack...
js_internal_storage * dereferenceTest = dereferenceObject ( trimmedToken , & rootScope ) ;
if ( dereferenceTest ) {
if ( typeOfStorage ( dereferenceTest ) = = " func " ) {
@ -697,6 +762,8 @@ js_internal_storage *doExpression(js_function &rootScope, std::string token) {
@@ -697,6 +762,8 @@ js_internal_storage *doExpression(js_function &rootScope, std::string token) {
continue ;
}
// number constant
bool allDigits = isStrRational ( trimmedToken ) ;
/*
bool allDigits = true ;
for ( auto it2 : trimmedToken ) {
if ( it2 > = ' 0 ' & & it2 < = ' 9 ' ) {
@ -707,14 +774,16 @@ js_internal_storage *doExpression(js_function &rootScope, std::string token) {
@@ -707,14 +774,16 @@ js_internal_storage *doExpression(js_function &rootScope, std::string token) {
}
}
}
*/
if ( allDigits ) {
js_number * jnum = new js_number ;
// FIXME: float double support
jnum - > value = std : : stoi ( trimmedToken ) ;
std : : cout < < " allDigits value[ " < < trimmedToken < < " ] => jnum[ " < < jnum - > value < < " ] \n " ;
stack = jnum ;
continue ;
}
js_internal_storage * * isVar = getObjectKeyPointer ( it , & rootScope ) ;
if ( isVar ! = nullptr ) {
std : : cout < < " isVar [ " < < isVar < < " ] \n " ;
@ -758,6 +827,7 @@ js_internal_storage *doExpression(js_function &rootScope, std::string token) {
@@ -758,6 +827,7 @@ js_internal_storage *doExpression(js_function &rootScope, std::string token) {
rootScope . locals . value [ remainingExpr ] = new js_internal_storage ;
}
stack = rootScope . locals . value [ remainingExpr ] ;
/*
rootScope . locals . value [ remainingExpr ] = new js_internal_storage ;
js_internal_storage * exprRes = doExpression ( rootScope , remainingExpr ) ;
@ -779,7 +849,7 @@ js_internal_storage *doExpression(js_function &rootScope, std::string token) {
@@ -779,7 +849,7 @@ js_internal_storage *doExpression(js_function &rootScope, std::string token) {
}
}
}
} else if ( state = = 1 ) {
} else if ( state = = 1 ) { // call function?
// in func call, double check the (
if ( it = = " ( " ) {
state = 2 ;
@ -789,10 +859,10 @@ js_internal_storage *doExpression(js_function &rootScope, std::string token) {
@@ -789,10 +859,10 @@ js_internal_storage *doExpression(js_function &rootScope, std::string token) {
stack = callFunc ;
state = 0 ;
}
} else if ( state = = 2 ) {
} else if ( state = = 2 ) { // start function call?
params = it ;
state = 3 ;
} else if ( state = = 3 ) {
} else if ( state = = 3 ) { // finish function call
// in func call, double check the )
if ( it = = " ) " ) {
/*
@ -815,14 +885,14 @@ js_internal_storage *doExpression(js_function &rootScope, std::string token) {
@@ -815,14 +885,14 @@ js_internal_storage *doExpression(js_function &rootScope, std::string token) {
stack = callFunc ;
state = 0 ;
}
} else if ( state = = 4 ) {
} else if ( state = = 4 ) { // NOT operator
js_internal_storage * expRes = doExpression ( rootScope , it ) ;
// invert expRes;
js_bool * jb = new js_bool ;
jb - > value = ! jsIsFalse ( expRes ) ;
stack = jb ;
state = 0 ;
} else if ( state = = 5 ) {
} else if ( state = = 5 ) { // JSON
/*
js_function * objectScope = new js_function ;
js_object * newObject = new js_object ;
@ -840,6 +910,9 @@ js_internal_storage *doExpression(js_function &rootScope, std::string token) {
@@ -840,6 +910,9 @@ js_internal_storage *doExpression(js_function &rootScope, std::string token) {
stack = jsGetObject ( rootScope , it ) ;
std : : cout < < " doExpression getObject got [ " < < stack < < " ] \n " ;
state = 0 ;
} else if ( state = = 6 ) { // stack =
std : : cout < < " State 6 = got [ " < < it < < " ] \n " ;
params + = it ;
} else {
std : : cout < < " doExpression unknown state[ " < < std : : to_string ( state ) < < " ] \n " ;
}
@ -851,6 +924,14 @@ js_internal_storage *doExpression(js_function &rootScope, std::string token) {
@@ -851,6 +924,14 @@ js_internal_storage *doExpression(js_function &rootScope, std::string token) {
std : : cout < < " doExpressionEND1 - stack is [ " < < stack < < " ] will now have to set it to [ " < < callFunc < < " ] \n " ;
stack = callFunc ;
state = 0 ;
} else
if ( state = = 6 ) {
std : : cout < < " Finishing state 6 [ " < < params < < " ] \n " ;
std : : cout < < " Store result in [ " < < typeOfStorage ( stack ) < < " ] \n " ;
auto resStack = doExpression ( rootScope , params ) ;
// store resStack where ever stack is pointing
params = " " ;
state = 0 ;
}
if ( state ! = 0 ) {
std : : cout < < " doExpression final state[ " < < std : : to_string ( state ) < < " ] \n " ;
@ -1038,7 +1119,7 @@ size_t getNextExpression(const std::string source, const size_t start) {
@@ -1038,7 +1119,7 @@ size_t getNextExpression(const std::string source, const size_t start) {
size_t parenLevel = 0 ;
size_t stateStart = 0 ;
for ( size_t cursor = start ; cursor < source . length ( ) ; cursor + + ) {
std : : cout < < std : : string ( getNextExpressionLevel * 2 , ' ' ) < < " getNextExpression( " < < getNextExpressionLevel < < " ) scanning[ " < < source [ cursor ] < < " ] at[ " < < cursor < < " / " < < source . length ( ) < < " ] state[ " < < std : : to_string ( state ) < < " ] parenLevel[ " < < parenLevel < < " ] \n " ;
//std::cout << std::string(getNextExpressionLevel * 2, ' ') << "getNextExpression(" << getNextExpressionLevel << ") scanning[" << source[cursor] << "] at[" << cursor << "/" << source.length() << "] state[" << std::to_string(state) << "] parenLevel[" << parenLevel << "]\n";
switch ( state ) {
case 0 :
// start function call
@ -1342,7 +1423,9 @@ js_function *makeFunctionFromString(const std::string body, const std::string pr
@@ -1342,7 +1423,9 @@ js_function *makeFunctionFromString(const std::string body, const std::string pr
std : : cout < < " makeFunctionFromString [ " < < prototype < < " ][ " < < body < < " ] \n " ;
js_function * func = new js_function ;
func - > tokens = jsGetTokens ( body , 0 ) ;
// FIXME: needs to be smarter
func - > parameters = split ( prototype , ' , ' ) ;
//for(auto it = func->parameters.begin(); it != func->)
if ( ! func - > tokens . size ( ) ) {
std : : cout < < " empty function? \n " ;
}
@ -1355,7 +1438,7 @@ js_array *jsGetArray(js_function &rootScope, std::string token) {
@@ -1355,7 +1438,7 @@ js_array *jsGetArray(js_function &rootScope, std::string token) {
js_array * jsArr = new js_array ;
parseJSON ( * objectScope , token ) ;
for ( auto it2 : objectScope - > locals . value ) {
jsArr - > value . push_back ( * it2 . second ) ;
jsArr - > value . push_back ( it2 . second ) ;
}
return jsArr ;
}
@ -1820,6 +1903,7 @@ void parseJSON(js_function &rootScope, std::string token) {
@@ -1820,6 +1903,7 @@ void parseJSON(js_function &rootScope, std::string token) {
}
// return value is if there was any error (false for error, true for no error)
// actually assignments are expressions
int doAssignmentLevel = 0 ;
bool doAssignment ( js_function & rootScope , std : : string token ) {
doAssignmentLevel + + ;
@ -2168,6 +2252,7 @@ bool doAssignment(js_function &rootScope, std::string token) {
@@ -2168,6 +2252,7 @@ bool doAssignment(js_function &rootScope, std::string token) {
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
std : : string trimmedToken = trim ( it ) ;
if ( trimmedToken = = " " ) continue ; // whitespace should be meaningless
if ( state = = 0 ) {
negate = false ;
prototype = " " ;
@ -2193,15 +2278,26 @@ bool doAssignment(js_function &rootScope, std::string token) {
@@ -2193,15 +2278,26 @@ bool doAssignment(js_function &rootScope, std::string token) {
std : : cout < < std : : string ( doAssignmentLevel * 2 , ' ' ) < < " doAssignment - function expr start Adjust left[ " < < left < < " ] to [ " < < left . substr ( 0 , cursor ) < < " ] \n " ;
state = 3 ;
}
if ( trimmedToken = = " ? " ) {
std : : cout < < " Ternany " < < std : : endl ;
// FIXME: our current value should determine what expr we replace our value with
state = 11 ; // ternary operator
continue ;
}
// most likely a function call
// but also can be an expression
// (function() {}())
// token will matter here
// check for ()
if ( trimmedToken = = " ( " ) {
if ( lastToken = = " for " ) {
std : : cout < < " not an assignment, fix doExpression \n " ;
}
callFuncName = lastToken ;
state = 8 ;
}
} else if ( state = = 1 ) {
// expression part of the assignment (the value part of what we're setting)
if ( trimmedToken = = " " ) continue ; // skip empties, don't fire the assignment too early
if ( it = = " " ) continue ; // skip empties, don't fire the assignment too early
if ( trimmedToken = = " ! " ) continue ; // valid expression
@ -2236,13 +2332,18 @@ bool doAssignment(js_function &rootScope, std::string token) {
@@ -2236,13 +2332,18 @@ bool doAssignment(js_function &rootScope, std::string token) {
if ( storage ) {
// state 1 can be an expression that we need to push the result onto the stack for && ||
stack = storage ;
// if it's a function value, it's a function naming (var bob = func), not a call
/*
js_function * funcTest = dynamic_cast < js_function * > ( storage ) ;
if ( funcTest ) {
std : : cout < < " assigning " < < trimmedToken < < " to some value " < < std : : endl ;
callFuncName = trimmedToken ;
callFunc = funcTest ;
state = 9 ;
continue ;
}
*/
std : : string tLeft = trim ( left ) ;
if ( tLeft [ 0 ] = = ' " ' & & tLeft [ tLeft . length ( ) - 1 ] = = ' " ' ) {
//std::cout << "dequoting[" << tLeft << "]" << std::endl;
@ -2257,6 +2358,9 @@ bool doAssignment(js_function &rootScope, std::string token) {
@@ -2257,6 +2358,9 @@ bool doAssignment(js_function &rootScope, std::string token) {
alreadySet = true ;
* key = storage ;
}
} else {
// no dot
std : : cout < < " Does tLeft[ " < < tLeft < < " ] has .? " < < std : : endl ;
}
if ( ! alreadySet ) {
std : : cout < < " doAssignment final assign[ " < < tLeft < < " ] of type[ " < < typeOfStorage ( storage ) < < " ] storageFalse[ " < < jsIsFalse ( storage ) < < " ] scope[ " < < & rootScope < < " ] \n " ;
@ -2264,6 +2368,11 @@ bool doAssignment(js_function &rootScope, std::string token) {
@@ -2264,6 +2368,11 @@ bool doAssignment(js_function &rootScope, std::string token) {
jsDisplayScope ( & rootScope , 0 ) ;
left = " " ; // reset left
assignfile < < tLeft < < " = " < < it < < " \n " ;
} else {
std : : cout < < " doAssignment final re-assigned[ " < < tLeft < < " ] of type[ " < < typeOfStorage ( storage ) < < " ] storageFalse[ " < < jsIsFalse ( storage ) < < " ] scope[ " < < & rootScope < < " ] " < < std : : endl ;
rootScope . locals . value [ tLeft ] = storage ;
left = " " ; // reset left
assignfile < < tLeft < < " = " < < it < < " \n " ;
}
} else {
std : : cout < < std : : string ( doAssignmentLevel * 2 , ' ' ) < < " HALT can't get value from [ " < < it < < " ] \n " ;
@ -2383,8 +2492,24 @@ bool doAssignment(js_function &rootScope, std::string token) {
@@ -2383,8 +2492,24 @@ bool doAssignment(js_function &rootScope, std::string token) {
if ( trimmedToken = = " ) " ) {
state = 0 ; // reset state
} else {
// call params
std : : cout < < std : : string ( doAssignmentLevel * 2 , ' ' ) < < " HALT need to parse these params[ " < < it < < " ] \n " ;
// call params
// we pass the params str to jsFunctionCall
//js_internal_storage *paramValue = doExpression(rootScope, trimmedToken);
// actually call function?
// resolve func by name
std : : cout < < " calling function [ " < < callFuncName < < " ]( " < < params < < " ) \n " ;
js_internal_storage * func = jsLocateKey ( & rootScope , callFuncName ) ;
if ( ! func ) {
std : : cout < < " function 404[ " < < callFuncName < < " ] \n " ;
}
callFunc = dynamic_cast < js_function * > ( func ) ;
if ( ! callFunc ) {
std : : cout < < " found but not a function[ " < < callFuncName < < " ] \n " ;
}
js_internal_storage * storage = jsFunctionCall ( callFuncName , callFunc , trimmedToken , rootScope ) ;
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 ;
@ -2460,13 +2585,24 @@ bool doAssignment(js_function &rootScope, std::string token) {
@@ -2460,13 +2585,24 @@ bool doAssignment(js_function &rootScope, std::string token) {
// collect params
params = trimmedToken ;
}
} else if ( state = = 11 ) { // lastToken ? expr1 : expr2
std : : cout < < " next token: [ " < < trimmedToken < < " ] " < < std : : endl ;
state = 12 ;
} else if ( state = = 12 ) { // : expr2
if ( trimmedToken = = " : " ) {
state = 13 ;
} else {
std : : cout < < " need to handle: [ " < < trimmedToken < < " ] " < < std : : endl ;
}
} else if ( state = = 13 ) { // expr2
std : : cout < < " final token: [ " < < trimmedToken < < " ] " < < std : : endl ;
}
// { starts JSON capture (should be exactly one block before the } token)
// you create a scope for that variable and recurse
lastToken = it ;
}
std : : cout < < std : : string ( doAssignmentLevel * 2 , ' ' ) < < " expression end, state " < < std : : to_string ( state ) < < std : : endl < < std : : endl ;
//displayScope(&rootScope, 0);
//jsD isplayScope(&rootScope, 0);
/*
auto hasTripleEqual = token . find ( " === " ) ;
auto hasDoubleEqual = std : : string : : npos ;
@ -2595,6 +2731,58 @@ bool dereferenceHasBase(const std::string input, const js_function *scope) {
@@ -2595,6 +2731,58 @@ bool dereferenceHasBase(const std::string input, const js_function *scope) {
return false ;
}
// detect stirng constants, rationals and variables
js_internal_storage * resolveStringToKey ( const std : : string key , js_function & scope ) {
char lastChar = key [ key . length ( ) - 1 ] ;
if ( isStrRational ( key ) ) {
js_number * num = new js_number ;
num - > value = std : : stoi ( key ) ;
return num ;
} else if ( ( key [ 0 ] = = ' " ' & & lastChar = = ' " ' ) | | ( key [ 0 ] = = ' \' ' & & lastChar = = ' \' ' ) ) {
js_string * str = new js_string ;
str - > value = key . substr ( 1 , key . length ( ) - 2 ) ;
return str ;
} else {
// get variable's value
return doExpression ( scope , key ) ;
}
return nullptr ;
}
/// look into stack for key (stack.key or stack[key]), think `return bob()[0]` where the stack isn't going to be in the string
// key can be a stirng constant or a number
// what about variable? you figure that before hand and deference it and get it's current value and pass that in
js_internal_storage * dereferenceStorage ( js_internal_storage * stack , const std : : string key , const js_function * scope ) {
js_object * jobj = dynamic_cast < js_object * > ( stack ) ;
if ( jobj ) {
std : : cout < < " deindexObject bracket style [< " < < key < < " > \n " ;
if ( jobj - > value . find ( key ) ! = jobj - > value . end ( ) ) {
std : : cout < < " dereferenceObject - number[ " < < key < < " ] is inside base " < < std : : endl ;
return jobj - > value [ key ] ; // we will now point to this storage
}
}
js_array * arr = dynamic_cast < js_array * > ( stack ) ;
if ( arr ) {
std : : cout < < " deindexArray bracket style [< " < < key < < " > \n " ;
int idx = std : : stoi ( key ) ;
if ( arr - > value . size ( ) > idx ) {
return arr - > value [ idx ] ;
}
}
js_string * str = dynamic_cast < js_string * > ( stack ) ;
if ( str ) {
std : : cout < < " deindexString bracket style [< " < < key < < " > \n " ;
int idx = std : : stoi ( key ) ;
if ( str - > value . size ( ) > idx ) {
js_string * nchar = new js_string ( ) ;
nchar - > value = std : : string ( 1 , str - > value [ idx ] ) ;
return nchar ;
}
}
std : : cout < < " Couldn't deindex [ " < < key < < " ] on type [ " < < typeOfStorage ( stack ) < < " ] \n " ;
return nullptr ; // or should we return a js_bool false? probably should return js_undefined
}
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
@ -2635,7 +2823,36 @@ js_internal_storage *dereferenceObject(const std::string input, const js_functio
@@ -2635,7 +2823,36 @@ js_internal_storage *dereferenceObject(const std::string input, const js_functio
char lastChar = part2 [ part2 . length ( ) - 1 ] ;
// probably should run this through doExpression...
// FIXME: "asdf" + var + "zxcv"
if ( ( part2 [ 0 ] = = ' " ' & & lastChar = = ' " ' ) | | ( part2 [ 0 ] = = ' \' ' & & lastChar = = ' \' ' ) ) {
if ( isStrRational ( part2 ) ) {
// part2 is just an index because array[0]
js_object * jobj = dynamic_cast < js_object * > ( baseStorage ) ;
if ( jobj ) {
std : : cout < < " deindexObject bracket style < " < < baseObj < < " >[< " < < part2 < < " >< " < < input . substr ( end ) < < " > \n " ;
if ( jobj - > value . find ( part2 ) ! = jobj - > value . end ( ) ) {
std : : cout < < " dereferenceObject - number[ " < < part2 < < " ] is inside base " < < std : : endl ;
return jobj - > value [ part2 ] ; // we will now point to this storage
}
}
js_array * arr = dynamic_cast < js_array * > ( baseStorage ) ;
if ( arr ) {
std : : cout < < " deindexArray bracket style < " < < baseObj < < " >[< " < < part2 < < " >< " < < input . substr ( end ) < < " > \n " ;
int idx = std : : stoi ( part2 ) ;
if ( arr - > value . size ( ) > idx ) {
return arr - > value [ idx ] ;
}
}
js_string * str = dynamic_cast < js_string * > ( baseStorage ) ;
if ( str ) {
std : : cout < < " deindexString bracket style < " < < baseObj < < " >[< " < < part2 < < " >< " < < input . substr ( end ) < < " > \n " ;
int idx = std : : stoi ( part2 ) ;
if ( str - > value . size ( ) > idx ) {
js_string * nchar = new js_string ( ) ;
nchar - > value = std : : string ( 1 , str - > value [ idx ] ) ;
return nchar ;
}
}
std : : cout < < " Couldn't deindex [ " < < part2 < < " ] on type [ " < < typeOfStorage ( baseStorage ) < < " ] baseObj[ " < < baseObj < < " ] lastChar[ " < < input . substr ( end ) < < " ] \n " ;
} else if ( ( part2 [ 0 ] = = ' " ' & & lastChar = = ' " ' ) | | ( part2 [ 0 ] = = ' \' ' & & lastChar = = ' \' ' ) ) {
js_object * jobj = dynamic_cast < js_object * > ( baseStorage ) ;
if ( jobj ) {
std : : cout < < " dereferenceObject bracket style < " < < baseObj < < " >[< " < < part2 < < " >< " < < input . substr ( end ) < < " > \n " ;
@ -2725,9 +2942,70 @@ js_internal_storage *jsParseTokens(const std::vector<std::string> &tokens, js_fu
@@ -2725,9 +2942,70 @@ js_internal_storage *jsParseTokens(const std::vector<std::string> &tokens, js_fu
// now execute remaining code
// FIXME: there should be no expressions after an if statement
js_internal_storage * lastRes = doExpression ( * scope , lastToken ) ;
// FIXME: what do we with lastRes, do we have a stack?
}
//std::cout << "HALT if not implemented" << std::endl;
//return nullptr;
} else if ( ttoken . substr ( 0 , 3 ) = = " for " ) {
std : : cout < < " ForToken[ " < < ttoken < < " ] \n " ;
// FIXME: detect for in
size_t pos = findClosing ( ttoken , 0 , ' ( ' , ' ) ' ) ;
std : : string afterFor = ttoken . substr ( 4 , pos - 4 ) ; // -4 because we started at 4 (it's a size, not pos) but won't include ( or )
std : : cout < < " afterFor[ " < < afterFor < < " ] \n " ;
std : : string forScope = ttoken . substr ( pos + 2 ) ;
std : : cout < < " forScope[ " < < forScope < < " ] \n " ;
// good idea but getNextExpression goes up to first comma (var x,y) and we need to first ;
/*
size_t end = getNextExpression ( afterFor , 0 ) ; // works great so far
//end = ifStr.find(')');
std : : string forStages = afterFor . substr ( 0 , end ) ;
std : : cout < < " initialization[ " < < forStages < < " ] \n " ;
size_t end2 = getNextExpression ( afterFor , end ) ; // works great so far
std : : string forStages2 = afterFor . substr ( end , end2 ) ;
std : : cout < < " condition[ " < < forStages2 < < " ] \n " ;
//size_t end3 = getNextExpression(afterFor, end2); // works great so far
std : : string forStages3 = afterFor . substr ( end2 ) ;
std : : cout < < " iterator[ " < < forStages3 < < " ] \n " ;
*/
// get initializer, condition and iterator
std : : vector < std : : string > opens , closes ;
opens . push_back ( " ( " ) ;
opens . push_back ( " ' " ) ;
opens . push_back ( " \" " ) ;
closes . push_back ( " ) " ) ;
closes . push_back ( " ' " ) ;
closes . push_back ( " \" " ) ;
auto varList = parseSepButNotBetween ( afterFor , " ; " , opens , closes ) ;
if ( varList . size ( ) < 3 ) {
std : : cout < < " HALT/badjs - not enough params for FOR loop \n " ;
}
std : : string initialization = varList [ 0 ] ;
std : : string condition = varList [ 1 ] ;
std : : string iterator = varList [ 2 ] ;
std : : cout < < " initialization[ " < < initialization < < " ] \n " ;
std : : cout < < " condition[ " < < condition < < " ] \n " ;
std : : cout < < " iterator[ " < < iterator < < " ] \n " ;
// FIXME: we probably should populate this current scope but nest a new one
doExpression ( * scope , initialization ) ; // for initialization ignores the return value of it
js_internal_storage * condRes = doExpression ( * scope , condition ) ;
while ( ! jsIsFalse ( condRes ) ) {
// run content...
// run jsParseTokens forScope
// FIXME: handle break / return
doExpression ( * scope , iterator ) ; // for iterator ignores the return value of it
condRes = doExpression ( * scope , condition ) ; // check condition again
}
std : : cout < < " HALT writeme! for loop " < < std : : endl ;
} else if ( ttoken . substr ( 0 , 3 ) = = " var " ) {
std : : string listStr = it . substr ( 3 ) ;
// FIXME: , in quotes or {} (JSON) <= top priority for 4chan
@ -2796,16 +3074,22 @@ js_internal_storage *jsParseTokens(const std::vector<std::string> &tokens, js_fu
@@ -2796,16 +3074,22 @@ js_internal_storage *jsParseTokens(const std::vector<std::string> &tokens, js_fu
// find { (func start)
end = defStr . find ( ' { ' ) ;
defStr = defStr . substr ( end + 1 , defStr . size ( ) - 2 ) ; // from { to the end
js_function * newFunc = makeFunctionFromString ( defStr , prototype , scope ) ;
/*
//std::cout << "jsParseTokens Function Declartion start[" << defStr[0] << "] last[" << defStr[defStr.length() - 1] << "]\n";
auto funcTokens = jsGetTokens ( defStr , 0 ) ;
//std::cout << "function [" << funcName << "] prototype [" << prototype << "] has [" << funcTokens.size() << "] tokens" << std::endl;
// __netrunner_function_definition is 31 chars
//scope->variables[funcName] = "__netrunner_function_definition = { prototype: \"" + prototype + "\", code: \"" + defStr + "\" }";
js_function * newFunc = new js_function ;
newFunc - > parameters . push_back ( prototype ) ;
newFunc - > tokens = funcTokens ;
newFunc - > parentScope = scope ;
*/
scope - > locals . value [ funcName ] = newFunc ;
execfile < < " function declaration [ " < < funcName < < " ]( " < < prototype < < " ) tokens[ " < < funcT okens. size ( ) < < " ] \n " ;
execfile < < " function declaration [ " < < funcName < < " ]( " < < prototype < < " ) tokens[ " < < newFunc - > t okens. size ( ) < < " ] \n " ;
} else if ( ttoken . substr ( 0 , 6 ) = = " return " ) {
std : : string afterReturn = ttoken . substr ( 7 ) ;
return doExpression ( * scope , afterReturn ) ;