Browse Source

initial for support, deindexing arrays, dereferenceStorage(), resolveStringToKey(), Initial ternany support, prototype/param function call improvement, handle assignment to stack

Odilitime 2 months ago
parent
commit
5995a4b562
1 changed files with 301 additions and 17 deletions
  1. 301
    17
      src/parsers/scripting/javascript/JSParser.cpp

+ 301
- 17
src/parsers/scripting/javascript/JSParser.cpp View File

@@ -33,6 +33,14 @@ std::string typeOfStorage(js_internal_storage *storage) {
33 33
     return "unknown";
34 34
 }
35 35
 
36
+bool isStrInt(std::string s) {
37
+  return (s.find_first_not_of( "0123456789" ) == std::string::npos);
38
+}
39
+
40
+bool isStrRational(std::string s) {
41
+  return (s.find_first_not_of( "0123456789." ) == std::string::npos);
42
+}
43
+
36 44
 bool jsIsFalse(js_internal_storage *generic) {
37 45
     std::string type = typeOfStorage(generic);
38 46
     if (type == "string") {
@@ -291,14 +299,42 @@ std::vector<std::string> jsGetTokens(const std::string &source, const size_t sta
291 299
     return tokens;
292 300
 }
293 301
 
294
-js_internal_storage *jsFunctionCall(std::string funcName, js_function *func, std::string params, js_function &scope) {
302
+js_internal_storage *jsFunctionCall(std::string funcName, js_function *func, std::string paramsStr, js_function &scope) {
295 303
     if (isConstruct(funcName)) {
296
-        return executeConstruct(funcName, params, scope);
304
+        return executeConstruct(funcName, paramsStr, scope);
297 305
     } else {
298 306
         if (func == nullptr) {
299
-            std::cout << "passed null into jsFunctionCall\n";
307
+            std::cout << "HALT passed null into jsFunctionCall" << std::endl;
300 308
             return nullptr;
301 309
         }
310
+        // what about the params?
311
+        if (paramsStr != "") {
312
+          // FIXME: need to parse them ...
313
+          std::vector<std::string> opens, closes;
314
+          opens.push_back("{");
315
+          opens.push_back("'");
316
+          opens.push_back("\"");
317
+          closes.push_back("}");
318
+          closes.push_back("'");
319
+          closes.push_back("\"");
320
+          auto params = parseSepButNotBetween(paramsStr, ",", opens, closes);
321
+          // get the prototype, so we know where to assign this variables into the scope
322
+          //std::cout << "parameters supported [" << func->parameters.size() << "]" << std::endl;
323
+          uint16_t i = 0;
324
+          for(auto it = func->parameters.begin(); it != func->parameters.end(); ++it) {
325
+            std::string value = "";
326
+            if (i < params.size()) {
327
+              value = params[i];
328
+            }
329
+            js_internal_storage *storeVal = doExpression(scope, value);
330
+            std::cout << "Assigning prototype[" << *it << "] = [" << value << "]" << std::endl;
331
+            scope.locals.value[*it] = storeVal;
332
+            assignfile << *it << "=" << value << "\n";
333
+            i++;
334
+          }
335
+          // well it's implemented, just not sure how well
336
+          //std::cout << "HALT/writeme! jsFunctionCall has params[" << paramsStr << "]!" << std::endl;
337
+        }
302 338
         return jsParseTokens(func->tokens, &scope);
303 339
     }
304 340
 }
@@ -621,6 +657,31 @@ js_internal_storage *doExpression(js_function &rootScope, std::string token) {
621 657
                 continue;
622 658
             }
623 659
 
660
+            // handle assignemnt to stack
661
+            if (trimmedToken == "=") {
662
+              state = 6;
663
+              continue;
664
+            }
665
+            /*
666
+            if (trimmedToken[0] == '[') {
667
+              // like [0] potentially longer?
668
+              size_t n = std::count(trimmedToken.begin(), trimmedToken.end(), ']');
669
+              if (n != 1) {
670
+                std::cout << "we dont support multiple deindexes, write me\n";
671
+              }
672
+              // deindex
673
+              js_array *arr = dynamic_cast<js_array *>(stack);
674
+              if (!arr) {
675
+                std::cout << "we only deindex arrarys [" << typeOfStorage(stack) << "], write me\n";
676
+              } else {
677
+                
678
+              }
679
+              // don't try and deference (object.value)
680
+              continue;
681
+            }
682
+            */
683
+
684
+          
624 685
             // function name
625 686
             // (
626 687
             if (trimmedToken == "(") {
@@ -650,9 +711,13 @@ js_internal_storage *doExpression(js_function &rootScope, std::string token) {
650 711
 
651 712
             // variable
652 713
             
653
-            // object.property
714
+            // object.property or object[property] or [0]
715
+            // well first lets parse the key out
716
+            // then resolve the key
717
+            // then resolve the value
654 718
             bool deref = dereferenceHasBase(trimmedToken, &rootScope);
655 719
             if (deref) {
720
+                // if trimmedToken is [0] it needs the stack...
656 721
                 js_internal_storage *dereferenceTest = dereferenceObject(trimmedToken, &rootScope);
657 722
                 if (dereferenceTest) {
658 723
                     if (typeOfStorage(dereferenceTest)=="func") {
@@ -697,6 +762,8 @@ js_internal_storage *doExpression(js_function &rootScope, std::string token) {
697 762
                 continue;
698 763
             }
699 764
             // number constant
765
+            bool allDigits = isStrRational(trimmedToken);
766
+            /*
700 767
             bool allDigits = true;
701 768
             for(auto it2 : trimmedToken) {
702 769
                 if (it2 >= '0' && it2 <= '9') {
@@ -707,14 +774,16 @@ js_internal_storage *doExpression(js_function &rootScope, std::string token) {
707 774
                     }
708 775
                 }
709 776
             }
777
+            */
710 778
             if (allDigits) {
711 779
                 js_number *jnum = new js_number;
780
+                // FIXME: float double support
712 781
                 jnum->value =  std::stoi(trimmedToken);
713 782
                 std::cout << "allDigits value[" << trimmedToken << "] => jnum[" << jnum->value << "]\n";
714 783
                 stack = jnum;
715 784
                 continue;
716 785
             }
717
-            
786
+          
718 787
             js_internal_storage **isVar = getObjectKeyPointer(it, &rootScope);
719 788
             if (isVar != nullptr) {
720 789
                 std::cout << "isVar [" << isVar << "]\n";
@@ -758,6 +827,7 @@ js_internal_storage *doExpression(js_function &rootScope, std::string token) {
758 827
                             rootScope.locals.value[remainingExpr] = new js_internal_storage;
759 828
                           }
760 829
                           stack = rootScope.locals.value[remainingExpr];
830
+                          
761 831
                           /*
762 832
                           rootScope.locals.value[remainingExpr] = new js_internal_storage;
763 833
                           js_internal_storage *exprRes = doExpression(rootScope, remainingExpr);
@@ -779,7 +849,7 @@ js_internal_storage *doExpression(js_function &rootScope, std::string token) {
779 849
                     }
780 850
                 }
781 851
             }
782
-        } else if (state == 1) {
852
+        } else if (state == 1) { // call function?
783 853
             // in func call, double check the (
784 854
             if (it == "(") {
785 855
                 state = 2;
@@ -789,10 +859,10 @@ js_internal_storage *doExpression(js_function &rootScope, std::string token) {
789 859
                 stack = callFunc;
790 860
                 state = 0;
791 861
             }
792
-        } else if (state == 2) {
862
+        } else if (state == 2) { // start function call?
793 863
             params = it;
794 864
             state = 3;
795
-        } else if (state == 3) {
865
+        } else if (state == 3) { // finish function call
796 866
             // in func call, double check the )
797 867
             if (it == ")") {
798 868
                 /*
@@ -815,14 +885,14 @@ js_internal_storage *doExpression(js_function &rootScope, std::string token) {
815 885
                 stack = callFunc;
816 886
                 state = 0;
817 887
             }
818
-        } else if (state == 4) {
888
+        } else if (state == 4) { // NOT operator
819 889
             js_internal_storage *expRes = doExpression(rootScope, it);
820 890
             // invert expRes;
821 891
             js_bool *jb = new js_bool;
822 892
             jb->value = !jsIsFalse(expRes);
823 893
             stack = jb;
824 894
             state = 0;
825
-        } else if (state == 5) {
895
+        } else if (state == 5) { // JSON
826 896
             /*
827 897
             js_function *objectScope = new js_function;
828 898
             js_object *newObject = new js_object;
@@ -840,6 +910,9 @@ js_internal_storage *doExpression(js_function &rootScope, std::string token) {
840 910
             stack = jsGetObject(rootScope, it);
841 911
             std::cout << "doExpression getObject got [" << stack << "]\n";
842 912
             state = 0;
913
+        } else if (state == 6) { // stack =
914
+            std::cout << "State 6 = got [" << it << "]\n";
915
+            params += it;
843 916
         } else {
844 917
             std::cout << "doExpression unknown state[" << std::to_string(state) << "]\n";
845 918
         }
@@ -851,6 +924,14 @@ js_internal_storage *doExpression(js_function &rootScope, std::string token) {
851 924
         std::cout << "doExpressionEND1 - stack is [" << stack << "] will now have to set it to [" << callFunc << "]\n";
852 925
         stack = callFunc;
853 926
         state = 0;
927
+    } else
928
+    if (state == 6) {
929
+      std::cout << "Finishing state 6 [" << params << "]\n";
930
+      std::cout << "Store result in [" << typeOfStorage(stack) << "]\n";
931
+      auto resStack = doExpression(rootScope, params);
932
+      // store resStack where ever stack is pointing
933
+      params = "";
934
+      state = 0;
854 935
     }
855 936
     if (state != 0) {
856 937
         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 1119
     size_t parenLevel = 0;
1039 1120
     size_t stateStart = 0;
1040 1121
     for (size_t cursor = start; cursor < source.length(); cursor++) {
1041
-        std::cout << std::string(getNextExpressionLevel * 2, ' ') << "getNextExpression(" << getNextExpressionLevel << ") scanning[" << source[cursor] << "] at[" << cursor << "/" << source.length() << "] state[" << std::to_string(state) << "] parenLevel[" << parenLevel << "]\n";
1122
+        //std::cout << std::string(getNextExpressionLevel * 2, ' ') << "getNextExpression(" << getNextExpressionLevel << ") scanning[" << source[cursor] << "] at[" << cursor << "/" << source.length() << "] state[" << std::to_string(state) << "] parenLevel[" << parenLevel << "]\n";
1042 1123
         switch(state) {
1043 1124
             case 0:
1044 1125
                 // start function call
@@ -1342,7 +1423,9 @@ js_function *makeFunctionFromString(const std::string body, const std::string pr
1342 1423
     std::cout << "makeFunctionFromString [" << prototype << "][" << body << "]\n";
1343 1424
     js_function *func = new js_function;
1344 1425
     func->tokens = jsGetTokens(body, 0);
1426
+    // FIXME: needs to be smarter
1345 1427
     func->parameters = split(prototype, ',');
1428
+    //for(auto it = func->parameters.begin(); it != func->)
1346 1429
     if (!func->tokens.size()) {
1347 1430
         std::cout << "empty function?\n";
1348 1431
     }
@@ -1355,7 +1438,7 @@ js_array *jsGetArray(js_function &rootScope, std::string token) {
1355 1438
     js_array *jsArr = new js_array;
1356 1439
     parseJSON(*objectScope, token);
1357 1440
     for(auto it2 : objectScope->locals.value) {
1358
-        jsArr->value.push_back(*it2.second);
1441
+        jsArr->value.push_back(it2.second);
1359 1442
     }
1360 1443
     return jsArr;
1361 1444
 }
@@ -1820,6 +1903,7 @@ void parseJSON(js_function &rootScope, std::string token) {
1820 1903
 }
1821 1904
 
1822 1905
 // return value is if there was any error (false for error, true for no error)
1906
+// actually assignments are expressions
1823 1907
 int doAssignmentLevel = 0;
1824 1908
 bool doAssignment(js_function &rootScope, std::string token) {
1825 1909
     doAssignmentLevel++;
@@ -2168,6 +2252,7 @@ bool doAssignment(js_function &rootScope, std::string token) {
2168 2252
         std::cout << std::string(doAssignmentLevel * 2, ' ') << "doAssignment expression(" << doAssignmentLevel << ") token[" << it << "]" << std::to_string(state) << std::endl;
2169 2253
         // default: put token in left, get op (usually =) and then get right side
2170 2254
         std::string trimmedToken = trim(it);
2255
+        if (trimmedToken == "") continue; // whitespace should be meaningless
2171 2256
         if (state==0) {
2172 2257
             negate = false;
2173 2258
             prototype = "";
@@ -2193,15 +2278,26 @@ bool doAssignment(js_function &rootScope, std::string token) {
2193 2278
                 std::cout << std::string(doAssignmentLevel * 2, ' ') << "doAssignment - function expr start Adjust left[" << left << "] to [" << left.substr(0, cursor) << "]\n";
2194 2279
                 state = 3;
2195 2280
             }
2281
+            if (trimmedToken == "?") {
2282
+              std::cout << "Ternany" << std::endl;
2283
+              // FIXME: our current value should determine what expr we replace our value with
2284
+              state = 11; // ternary operator
2285
+              continue;
2286
+            }
2196 2287
             // most likely a function call
2197 2288
             // but also can be an expression
2198 2289
             // (function() {}())
2199 2290
             // token will matter here
2200 2291
             // check for ()
2201 2292
             if (trimmedToken == "(") {
2293
+                if (lastToken == "for") {
2294
+                  std::cout << "not an assignment, fix doExpression\n";
2295
+                }
2296
+                callFuncName = lastToken;
2202 2297
                 state = 8;
2203 2298
             }
2204 2299
         } else if (state == 1) {
2300
+            // expression part of the assignment (the value part of what we're setting)
2205 2301
             if (trimmedToken == "") continue; // skip empties, don't fire the assignment too early
2206 2302
             if (it == " ") continue; // skip empties, don't fire the assignment too early
2207 2303
             if (trimmedToken == "!") continue; // valid expression
@@ -2236,13 +2332,18 @@ bool doAssignment(js_function &rootScope, std::string token) {
2236 2332
                 if (storage) {
2237 2333
                     // state 1 can be an expression that we need to push the result onto the stack for && ||
2238 2334
                     stack = storage;
2335
+                  
2336
+                    // if it's a function value, it's a function naming (var bob = func), not a call
2337
+                    /*
2239 2338
                     js_function *funcTest = dynamic_cast<js_function*>(storage);
2240 2339
                     if (funcTest) {
2340
+                        std::cout << "assigning " << trimmedToken << " to some value" << std::endl;
2241 2341
                         callFuncName = trimmedToken;
2242 2342
                         callFunc = funcTest;
2243 2343
                         state = 9;
2244 2344
                         continue;
2245 2345
                     }
2346
+                    */
2246 2347
                     std::string tLeft = trim(left);
2247 2348
                     if (tLeft[0]=='"' && tLeft[tLeft.length() - 1]=='"') {
2248 2349
                         //std::cout << "dequoting[" << tLeft << "]" << std::endl;
@@ -2257,6 +2358,9 @@ bool doAssignment(js_function &rootScope, std::string token) {
2257 2358
                             alreadySet = true;
2258 2359
                             *key = storage;
2259 2360
                         }
2361
+                    } else {
2362
+                      // no dot
2363
+                      std::cout << "Does tLeft[" << tLeft << "] has .?" << std::endl;
2260 2364
                     }
2261 2365
                     if (!alreadySet) {
2262 2366
                         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 2368
                         jsDisplayScope(&rootScope, 0);
2265 2369
                         left = ""; // reset left
2266 2370
                         assignfile << tLeft << "=" << it << "\n";
2371
+                    } else {
2372
+                      std::cout << "doAssignment final re-assigned[" << tLeft << "] of type[" << typeOfStorage(storage) << "] storageFalse[" << jsIsFalse(storage) <<"] scope[" << &rootScope << "]" << std::endl;
2373
+                      rootScope.locals.value[tLeft] = storage;
2374
+                      left = ""; // reset left
2375
+                      assignfile << tLeft << "=" << it << "\n";
2267 2376
                     }
2268 2377
                 } else {
2269 2378
                     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 2492
             if (trimmedToken == ")") {
2384 2493
                 state = 0; // reset state
2385 2494
             } else {
2386
-                // call params
2387
-                std::cout << std::string(doAssignmentLevel * 2, ' ') << "HALT need to parse these params[" << it << "]\n";
2495
+              // call params
2496
+              // we pass the params str to jsFunctionCall
2497
+              
2498
+              //js_internal_storage *paramValue = doExpression(rootScope, trimmedToken);
2499
+              // actually call function?
2500
+              // resolve func by name
2501
+              std::cout << "calling function [" << callFuncName << "](" << params << ")\n";
2502
+              
2503
+              js_internal_storage *func = jsLocateKey(&rootScope, callFuncName);
2504
+              if (!func) {
2505
+                std::cout << "function 404[" << callFuncName << "]\n";
2506
+              }
2507
+              callFunc = dynamic_cast<js_function *>(func);
2508
+              if (!callFunc) {
2509
+                std::cout << "found but not a function[" << callFuncName << "]\n";
2510
+              }
2511
+              js_internal_storage *storage = jsFunctionCall(callFuncName, callFunc, trimmedToken, rootScope);
2512
+              std::cout << std::string(doAssignmentLevel * 2, ' ') << "HALT need to parse these params[" << it << "]\n";
2388 2513
             }
2389 2514
         } else if (state == 9) { // are we a function call with return value, or assigning a function reference
2390 2515
             js_internal_storage *storage = nullptr;
@@ -2460,13 +2585,24 @@ bool doAssignment(js_function &rootScope, std::string token) {
2460 2585
                 // collect params
2461 2586
                 params = trimmedToken;
2462 2587
             }
2588
+        } else if (state == 11) { // lastToken ? expr1 : expr2
2589
+          std::cout << "next token: [" << trimmedToken << "]" << std::endl;
2590
+          state = 12;
2591
+        } else if (state == 12) { // : expr2
2592
+          if (trimmedToken == ":") {
2593
+            state = 13;
2594
+          } else {
2595
+            std::cout << "need to handle: [" << trimmedToken << "]" << std::endl;
2596
+          }
2597
+        } else if (state == 13) { // expr2
2598
+          std::cout << "final token: [" << trimmedToken << "]" << std::endl;
2463 2599
         }
2464 2600
         // { starts JSON capture (should be exactly one block before the } token)
2465 2601
         // you create a scope for that variable and recurse
2466 2602
         lastToken = it;
2467 2603
     }
2468 2604
     std::cout << std::string(doAssignmentLevel * 2, ' ') << "expression end, state " << std::to_string(state) << std::endl << std::endl;
2469
-    //displayScope(&rootScope, 0);
2605
+    //jsDisplayScope(&rootScope, 0);
2470 2606
     /*
2471 2607
     auto hasTripleEqual = token.find("===");
2472 2608
     auto hasDoubleEqual = std::string::npos;
@@ -2595,6 +2731,58 @@ bool dereferenceHasBase(const std::string input, const js_function *scope) {
2595 2731
     return false;
2596 2732
 }
2597 2733
 
2734
+// detect stirng constants, rationals and variables
2735
+js_internal_storage *resolveStringToKey(const std::string key, js_function &scope) {
2736
+  char lastChar = key[key.length() - 1];
2737
+  if (isStrRational(key)) {
2738
+    js_number *num = new js_number;
2739
+    num->value = std::stoi(key);
2740
+    return num;
2741
+  } else if((key[0] == '"' && lastChar == '"') || (key[0] == '\'' && lastChar == '\'')) {
2742
+    js_string *str = new js_string;
2743
+    str->value = key.substr(1, key.length() - 2);
2744
+    return str;
2745
+  } else {
2746
+    // get variable's value
2747
+    return doExpression(scope, key);
2748
+  }
2749
+  return nullptr;
2750
+}
2751
+
2752
+/// 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
2753
+// key can be a stirng constant or a number
2754
+// what about variable? you figure that before hand and deference it and get it's current value and pass that in
2755
+js_internal_storage *dereferenceStorage(js_internal_storage *stack, const std::string key, const js_function *scope) {
2756
+  js_object *jobj = dynamic_cast<js_object*>(stack);
2757
+  if (jobj) {
2758
+    std::cout << "deindexObject bracket style [<" << key << ">\n";
2759
+    if (jobj->value.find(key) != jobj->value.end()) {
2760
+      std::cout << "dereferenceObject - number[" << key << "] is inside base" << std::endl;
2761
+      return jobj->value[key]; // we will now point to this storage
2762
+    }
2763
+  }
2764
+  js_array *arr = dynamic_cast<js_array *>(stack);
2765
+  if (arr) {
2766
+    std::cout << "deindexArray bracket style [<" << key << ">\n";
2767
+    int idx = std::stoi(key);
2768
+    if (arr->value.size() > idx) {
2769
+      return arr->value[idx];
2770
+    }
2771
+  }
2772
+  js_string *str = dynamic_cast<js_string *>(stack);
2773
+  if (str) {
2774
+    std::cout << "deindexString bracket style [<" << key << ">\n";
2775
+    int idx = std::stoi(key);
2776
+    if (str->value.size() > idx) {
2777
+      js_string *nchar = new js_string();
2778
+      nchar->value = std::string(1, str->value[idx]);
2779
+      return nchar;
2780
+    }
2781
+  }
2782
+  std::cout << "Couldn't deindex [" << key <<"] on type [" << typeOfStorage(stack) << "]\n";
2783
+  return nullptr; // or should we return a js_bool false? probably should return js_undefined
2784
+}
2785
+
2598 2786
 js_internal_storage *dereferenceObject(const std::string input, const js_function *scope) {
2599 2787
     // FIXME: too simple, catches quoted strings with . in them
2600 2788
     // FIXME: make sure we're not inside quotes
@@ -2635,7 +2823,36 @@ js_internal_storage *dereferenceObject(const std::string input, const js_functio
2635 2823
                 char lastChar = part2[part2.length() - 1];
2636 2824
                 // probably should run this through doExpression...
2637 2825
                 // FIXME: "asdf" + var + "zxcv"
2638
-                if ((part2[0] == '"' && lastChar == '"') || (part2[0] == '\'' && lastChar == '\'')) {
2826
+                if (isStrRational(part2)) {
2827
+                  // part2 is just an index because array[0]
2828
+                  js_object *jobj = dynamic_cast<js_object*>(baseStorage);
2829
+                  if (jobj) {
2830
+                    std::cout << "deindexObject bracket style <" << baseObj << ">[<" << part2 << "><" << input.substr(end) << ">\n";
2831
+                    if (jobj->value.find(part2) != jobj->value.end()) {
2832
+                      std::cout << "dereferenceObject - number[" << part2 << "] is inside base" << std::endl;
2833
+                      return jobj->value[part2]; // we will now point to this storage
2834
+                    }
2835
+                  }
2836
+                  js_array *arr = dynamic_cast<js_array *>(baseStorage);
2837
+                  if (arr) {
2838
+                    std::cout << "deindexArray bracket style <" << baseObj << ">[<" << part2 << "><" << input.substr(end) << ">\n";
2839
+                    int idx = std::stoi(part2);
2840
+                    if (arr->value.size() > idx) {
2841
+                      return arr->value[idx];
2842
+                    }
2843
+                  }
2844
+                  js_string *str = dynamic_cast<js_string *>(baseStorage);
2845
+                  if (str) {
2846
+                    std::cout << "deindexString bracket style <" << baseObj << ">[<" << part2 << "><" << input.substr(end) << ">\n";
2847
+                    int idx = std::stoi(part2);
2848
+                    if (str->value.size() > idx) {
2849
+                      js_string *nchar = new js_string();
2850
+                      nchar->value = std::string(1, str->value[idx]);
2851
+                      return nchar;
2852
+                    }
2853
+                  }
2854
+                  std::cout << "Couldn't deindex [" << part2 <<"] on type [" << typeOfStorage(baseStorage) << "] baseObj[" << baseObj << "] lastChar[" << input.substr(end) << "]\n";
2855
+                } else if ((part2[0] == '"' && lastChar == '"') || (part2[0] == '\'' && lastChar == '\'')) {
2639 2856
                     js_object *jobj = dynamic_cast<js_object*>(baseStorage);
2640 2857
                     if (jobj) {
2641 2858
                         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 2942
                 // now execute remaining code
2726 2943
                 // FIXME: there should be no expressions after an if statement
2727 2944
                 js_internal_storage *lastRes = doExpression(*scope, lastToken);
2945
+                // FIXME: what do we with lastRes, do we have a stack?
2728 2946
             }
2729 2947
             //std::cout << "HALT if not implemented" << std::endl;
2730 2948
             //return nullptr;
2949
+        } else if (ttoken.substr(0, 3)=="for") {
2950
+            std::cout << "ForToken[" << ttoken << "]\n";
2951
+          
2952
+            // FIXME: detect for in
2953
+
2954
+            size_t pos = findClosing(ttoken, 0, '(', ')');
2955
+            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 )
2956
+            std::cout << "afterFor[" << afterFor << "]\n";
2957
+          
2958
+            std::string forScope = ttoken.substr(pos + 2);
2959
+            std::cout << "forScope[" << forScope << "]\n";
2960
+          
2961
+          
2962
+            // good idea but getNextExpression goes up to first comma (var x,y) and we need to first ;
2963
+            /*
2964
+            size_t end = getNextExpression(afterFor, 0); // works great so far
2965
+            //end = ifStr.find(')');
2966
+            std::string forStages = afterFor.substr(0, end);
2967
+            std::cout << "initialization[" << forStages << "]\n";
2968
+
2969
+            size_t end2 = getNextExpression(afterFor, end); // works great so far
2970
+            std::string forStages2 = afterFor.substr(end, end2);
2971
+            std::cout << "condition[" << forStages2 << "]\n";
2972
+
2973
+            //size_t end3 = getNextExpression(afterFor, end2); // works great so far
2974
+            std::string forStages3 = afterFor.substr(end2);
2975
+            std::cout << "iterator[" << forStages3 << "]\n";
2976
+            */
2977
+
2978
+            // get initializer, condition and iterator
2979
+            std::vector<std::string> opens, closes;
2980
+            opens.push_back("(");
2981
+            opens.push_back("'");
2982
+            opens.push_back("\"");
2983
+            closes.push_back(")");
2984
+            closes.push_back("'");
2985
+            closes.push_back("\"");
2986
+            auto varList = parseSepButNotBetween(afterFor, ";", opens, closes);
2987
+            if (varList.size() < 3) {
2988
+              std::cout << "HALT/badjs - not enough params for FOR loop\n";
2989
+            }
2990
+            std::string initialization = varList[0];
2991
+            std::string condition = varList[1];
2992
+            std::string iterator = varList[2];
2993
+            std::cout << "initialization[" << initialization << "]\n";
2994
+            std::cout << "condition[" << condition << "]\n";
2995
+            std::cout << "iterator[" << iterator << "]\n";
2996
+          
2997
+            // FIXME: we probably should populate this current scope but nest a new one
2998
+            doExpression(*scope, initialization); // for initialization ignores the return value of it
2999
+            js_internal_storage *condRes = doExpression(*scope, condition);
3000
+            while(!jsIsFalse(condRes)) {
3001
+              // run content...
3002
+              // run jsParseTokens forScope
3003
+              // FIXME: handle break / return
3004
+              doExpression(*scope, iterator); // for iterator ignores the return value of it
3005
+              condRes = doExpression(*scope, condition); // check condition again
3006
+            }
3007
+
3008
+            std::cout << "HALT writeme! for loop" << std::endl;
2731 3009
         } else if (ttoken.substr(0, 3)=="var") {
2732 3010
             std::string listStr = it.substr(3);
2733 3011
             // 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 3074
             // find { (func start)
2797 3075
             end = defStr.find('{');
2798 3076
             defStr = defStr.substr(end + 1, defStr.size() - 2); // from { to the end
3077
+          
3078
+            js_function *newFunc = makeFunctionFromString(defStr, prototype, scope);
3079
+          
3080
+            /*
2799 3081
             //std::cout << "jsParseTokens Function Declartion start[" << defStr[0] << "] last[" << defStr[defStr.length() - 1] << "]\n";
2800 3082
             auto funcTokens = jsGetTokens(defStr, 0);
2801 3083
             //std::cout << "function [" << funcName << "] prototype [" << prototype << "] has [" << funcTokens.size() << "] tokens" << std::endl;
2802 3084
             // __netrunner_function_definition is 31 chars
2803 3085
             //scope->variables[funcName] = "__netrunner_function_definition = { prototype: \"" + prototype + "\", code: \"" + defStr + "\" }";
2804 3086
             js_function *newFunc = new js_function;
3087
+            newFunc->parameters.push_back(prototype);
2805 3088
             newFunc->tokens = funcTokens;
2806 3089
             newFunc->parentScope = scope;
3090
+             */
2807 3091
             scope->locals.value[funcName] = newFunc;
2808
-            execfile << "function declaration [" << funcName << "](" << prototype << ") tokens[" << funcTokens.size() << "]\n";
3092
+            execfile << "function declaration [" << funcName << "](" << prototype << ") tokens[" << newFunc->tokens.size() << "]\n";
2809 3093
         } else if (ttoken.substr(0, 6)=="return") {
2810 3094
             std::string afterReturn = ttoken.substr(7);
2811 3095
             return doExpression(*scope, afterReturn);

Loading…
Cancel
Save