gd_tokenizer.cpp 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973
  1. /*************************************************************************/
  2. /* gd_tokenizer.cpp */
  3. /*************************************************************************/
  4. /* This file is part of: */
  5. /* GODOT ENGINE */
  6. /* http://www.godotengine.org */
  7. /*************************************************************************/
  8. /* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
  9. /* */
  10. /* Permission is hereby granted, free of charge, to any person obtaining */
  11. /* a copy of this software and associated documentation files (the */
  12. /* "Software"), to deal in the Software without restriction, including */
  13. /* without limitation the rights to use, copy, modify, merge, publish, */
  14. /* distribute, sublicense, and/or sell copies of the Software, and to */
  15. /* permit persons to whom the Software is furnished to do so, subject to */
  16. /* the following conditions: */
  17. /* */
  18. /* The above copyright notice and this permission notice shall be */
  19. /* included in all copies or substantial portions of the Software. */
  20. /* */
  21. /* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
  22. /* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
  23. /* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
  24. /* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
  25. /* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
  26. /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
  27. /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
  28. /*************************************************************************/
  29. #include "gd_tokenizer.h"
  30. #include "print_string.h"
  31. #include "gd_functions.h"
  32. const char* GDTokenizer::token_names[TK_MAX]={
  33. "Empty",
  34. "Identifier",
  35. "Constant",
  36. "Self",
  37. "Built-In Type",
  38. "Built-In Func",
  39. "In",
  40. "'=='",
  41. "'!='",
  42. "'<'",
  43. "'<='",
  44. "'>'",
  45. "'>='",
  46. "'and'",
  47. "'or'",
  48. "'not'",
  49. "'+'",
  50. "'-'",
  51. "'*'",
  52. "'/'",
  53. "'%'",
  54. "'<<'",
  55. "'>>'",
  56. "'='",
  57. "'+='",
  58. "'-='",
  59. "'*='",
  60. "'/='",
  61. "'%='",
  62. "'<<='",
  63. "'>>='",
  64. "'&='",
  65. "'|='",
  66. "'^='",
  67. "'&'",
  68. "'|'",
  69. "'^'",
  70. "'~'",
  71. //"Plus Plus",
  72. //"Minus Minus",
  73. "if",
  74. "elif",
  75. "else",
  76. "for",
  77. "do",
  78. "while",
  79. "switch",
  80. "case",
  81. "break",
  82. "continue",
  83. "pass",
  84. "return",
  85. "func",
  86. "class",
  87. "extends",
  88. "tool",
  89. "static",
  90. "export",
  91. "const",
  92. "var",
  93. "preload",
  94. "assert",
  95. "'['",
  96. "']'",
  97. "'{'",
  98. "'}'",
  99. "'('",
  100. "')'",
  101. "','",
  102. "';'",
  103. "'.'",
  104. "'?'",
  105. "':'",
  106. "'\\n'",
  107. "Error",
  108. "EOF"};
  109. const char *GDTokenizer::get_token_name(Token p_token) {
  110. ERR_FAIL_INDEX_V(p_token,TK_MAX,"<error>");
  111. return token_names[p_token];
  112. }
  113. static bool _is_text_char(CharType c) {
  114. return (c>='a' && c<='z') || (c>='A' && c<='Z') || (c>='0' && c<='9') || c=='_';
  115. }
  116. static bool _is_number(CharType c) {
  117. return (c>='0' && c<='9');
  118. }
  119. static bool _is_hex(CharType c) {
  120. return (c>='0' && c<='9') || (c>='a' && c<='f') || (c>='A' && c<='F');
  121. }
  122. void GDTokenizer::_make_token(Token p_type) {
  123. TokenData &tk=tk_rb[tk_rb_pos];
  124. tk.type=p_type;
  125. tk.line=line;
  126. tk.col=column;
  127. tk_rb_pos=(tk_rb_pos+1)%TK_RB_SIZE;
  128. }
  129. void GDTokenizer::_make_identifier(const StringName& p_identifier) {
  130. TokenData &tk=tk_rb[tk_rb_pos];
  131. tk.type=TK_IDENTIFIER;
  132. tk.identifier=p_identifier;
  133. tk.line=line;
  134. tk.col=column;
  135. tk_rb_pos=(tk_rb_pos+1)%TK_RB_SIZE;
  136. }
  137. void GDTokenizer::_make_built_in_func(GDFunctions::Function p_func) {
  138. TokenData &tk=tk_rb[tk_rb_pos];
  139. tk.type=TK_BUILT_IN_FUNC;
  140. tk.func=p_func;
  141. tk.line=line;
  142. tk.col=column;
  143. tk_rb_pos=(tk_rb_pos+1)%TK_RB_SIZE;
  144. }
  145. void GDTokenizer::_make_constant(const Variant& p_constant) {
  146. TokenData &tk=tk_rb[tk_rb_pos];
  147. tk.type=TK_CONSTANT;
  148. tk.constant=p_constant;
  149. tk.line=line;
  150. tk.col=column;
  151. tk_rb_pos=(tk_rb_pos+1)%TK_RB_SIZE;
  152. }
  153. void GDTokenizer::_make_type(const Variant::Type& p_type) {
  154. TokenData &tk=tk_rb[tk_rb_pos];
  155. tk.type=TK_BUILT_IN_TYPE;
  156. tk.vtype=p_type;
  157. tk.line=line;
  158. tk.col=column;
  159. tk_rb_pos=(tk_rb_pos+1)%TK_RB_SIZE;
  160. }
  161. void GDTokenizer::_make_error(const String& p_error) {
  162. error_flag=true;
  163. last_error=p_error;
  164. TokenData &tk=tk_rb[tk_rb_pos];
  165. tk.type=TK_ERROR;
  166. tk.constant=p_error;
  167. tk.line=line;
  168. tk.col=column;
  169. tk_rb_pos=(tk_rb_pos+1)%TK_RB_SIZE;
  170. }
  171. void GDTokenizer::_make_newline(int p_spaces) {
  172. TokenData &tk=tk_rb[tk_rb_pos];
  173. tk.type=TK_NEWLINE;
  174. tk.constant=p_spaces;
  175. tk.line=line;
  176. tk.col=column;
  177. tk_rb_pos=(tk_rb_pos+1)%TK_RB_SIZE;
  178. }
  179. void GDTokenizer::_advance() {
  180. if (error_flag) {
  181. //parser broke
  182. _make_error(last_error);
  183. return;
  184. }
  185. if (code_pos>=len) {
  186. _make_token(TK_EOF);
  187. return;
  188. }
  189. #define GETCHAR(m_ofs) ((m_ofs+code_pos)>=len?0:_code[m_ofs+code_pos])
  190. #define INCPOS(m_amount) { code_pos+=m_amount; column+=m_amount; }
  191. while (true) {
  192. bool is_node_path=false;
  193. switch(GETCHAR(0)) {
  194. case 0:
  195. _make_token(TK_EOF);
  196. break;
  197. case '\t':
  198. case '\r':
  199. case ' ':
  200. INCPOS(1);
  201. continue;
  202. case '\n': {
  203. line++;
  204. INCPOS(1);
  205. column=0;
  206. int i=0;
  207. while(GETCHAR(i)==' ' || GETCHAR(i)=='\t') {
  208. i++;
  209. }
  210. _make_newline(i);
  211. return;
  212. }
  213. #if 1 //py style tokenizer
  214. case '#': { // line comment skip
  215. while(GETCHAR(0)!='\n') {
  216. code_pos++;
  217. if (GETCHAR(0)==0) { //end of file
  218. _make_error("Unterminated Comment");
  219. return;
  220. }
  221. }
  222. INCPOS(1);
  223. column=0;
  224. line++;
  225. int i=0;
  226. while(GETCHAR(i)==' ' || GETCHAR(i)=='\t') {
  227. i++;
  228. }
  229. _make_newline(i);
  230. return;
  231. } break;
  232. #endif
  233. case '/': {
  234. switch(GETCHAR(1)) {
  235. #if 0 // c style tokenizer
  236. case '*': { // block comment
  237. int pos = code_pos+2;
  238. int new_line=line;
  239. int new_col=column+2;
  240. while(true) {
  241. if (_code[pos]=='0') {
  242. _make_error("Unterminated Comment");
  243. code_pos=pos;
  244. return;
  245. }
  246. if (_code[pos]=='*' && _code[pos+1]=='/') {
  247. new_col+=2;
  248. pos+=2; //compensate
  249. break;
  250. } else if (_code[pos]=='\n') {
  251. new_line++;
  252. new_col=0;
  253. } else {
  254. new_col++;
  255. }
  256. pos++;
  257. }
  258. column=new_col;
  259. line=new_line;
  260. code_pos=pos;
  261. continue;
  262. } break;
  263. case '/': { // line comment skip
  264. while(GETCHAR(0)!='\n') {
  265. code_pos++;
  266. if (GETCHAR(0)==0) { //end of file
  267. _make_error("Unterminated Comment");
  268. return;
  269. }
  270. }
  271. INCPOS(1);
  272. column=0;
  273. line++;
  274. continue;
  275. } break;
  276. #endif
  277. case '=': { // diveq
  278. _make_token(TK_OP_ASSIGN_DIV);
  279. INCPOS(1);
  280. } break;
  281. default:
  282. _make_token(TK_OP_DIV);
  283. }
  284. } break;
  285. case '=': {
  286. if (GETCHAR(1)=='=') {
  287. _make_token(TK_OP_EQUAL);
  288. INCPOS(1);
  289. } else
  290. _make_token(TK_OP_ASSIGN);
  291. } break;
  292. case '<': {
  293. if (GETCHAR(1)=='=') {
  294. _make_token(TK_OP_LESS_EQUAL);
  295. INCPOS(1);
  296. } else if (GETCHAR(1)=='<') {
  297. if (GETCHAR(2)=='=') {
  298. _make_token(TK_OP_ASSIGN_SHIFT_LEFT);
  299. INCPOS(1);
  300. } else {
  301. _make_token(TK_OP_SHIFT_LEFT);
  302. }
  303. INCPOS(1);
  304. } else
  305. _make_token(TK_OP_LESS);
  306. } break;
  307. case '>': {
  308. if (GETCHAR(1)=='=') {
  309. _make_token(TK_OP_GREATER_EQUAL);
  310. INCPOS(1);
  311. } else if (GETCHAR(1)=='>') {
  312. if (GETCHAR(2)=='=') {
  313. _make_token(TK_OP_ASSIGN_SHIFT_RIGHT);
  314. INCPOS(1);
  315. } else {
  316. _make_token(TK_OP_SHIFT_RIGHT);
  317. }
  318. INCPOS(1);
  319. } else {
  320. _make_token(TK_OP_GREATER);
  321. }
  322. } break;
  323. case '!': {
  324. if (GETCHAR(1)=='=') {
  325. _make_token(TK_OP_NOT_EQUAL);
  326. INCPOS(1);
  327. } else {
  328. _make_token(TK_OP_NOT);
  329. }
  330. } break;
  331. //case '"' //string - no strings in shader
  332. //case '\'' //string - no strings in shader
  333. case '{':
  334. _make_token(TK_CURLY_BRACKET_OPEN);
  335. break;
  336. case '}':
  337. _make_token(TK_CURLY_BRACKET_CLOSE);
  338. break;
  339. case '[':
  340. _make_token(TK_BRACKET_OPEN);
  341. break;
  342. case ']':
  343. _make_token(TK_BRACKET_CLOSE);
  344. break;
  345. case '(':
  346. _make_token(TK_PARENTHESIS_OPEN);
  347. break;
  348. case ')':
  349. _make_token(TK_PARENTHESIS_CLOSE);
  350. break;
  351. case ',':
  352. _make_token(TK_COMMA);
  353. break;
  354. case ';':
  355. _make_token(TK_SEMICOLON);
  356. break;
  357. case '?':
  358. _make_token(TK_QUESTION_MARK);
  359. break;
  360. case ':':
  361. _make_token(TK_COLON); //for methods maybe but now useless.
  362. break;
  363. case '^': {
  364. if (GETCHAR(1)=='=') {
  365. _make_token(TK_OP_ASSIGN_BIT_XOR);
  366. INCPOS(1);
  367. } else {
  368. _make_token(TK_OP_BIT_XOR);
  369. }
  370. } break;
  371. case '~':
  372. _make_token(TK_OP_BIT_INVERT);
  373. break;
  374. case '&': {
  375. if (GETCHAR(1)=='&') {
  376. _make_token(TK_OP_AND);
  377. INCPOS(1);
  378. } else if (GETCHAR(1)=='=') {
  379. _make_token(TK_OP_ASSIGN_BIT_AND);
  380. INCPOS(1);
  381. } else {
  382. _make_token(TK_OP_BIT_AND);
  383. }
  384. } break;
  385. case '|': {
  386. if (GETCHAR(1)=='|') {
  387. _make_token(TK_OP_OR);
  388. INCPOS(1);
  389. } else if (GETCHAR(1)=='=') {
  390. _make_token(TK_OP_ASSIGN_BIT_OR);
  391. INCPOS(1);
  392. } else {
  393. _make_token(TK_OP_BIT_OR);
  394. }
  395. } break;
  396. case '*': {
  397. if (GETCHAR(1)=='=') {
  398. _make_token(TK_OP_ASSIGN_MUL);
  399. INCPOS(1);
  400. } else {
  401. _make_token(TK_OP_MUL);
  402. }
  403. } break;
  404. case '+': {
  405. if (GETCHAR(1)=='=') {
  406. _make_token(TK_OP_ASSIGN_ADD);
  407. INCPOS(1);
  408. //} else if (GETCHAR(1)=='+') {
  409. // _make_token(TK_OP_PLUS_PLUS);
  410. // INCPOS(1);
  411. } else {
  412. _make_token(TK_OP_ADD);
  413. }
  414. } break;
  415. case '-': {
  416. if (GETCHAR(1)=='=') {
  417. _make_token(TK_OP_ASSIGN_SUB);
  418. INCPOS(1);
  419. //} else if (GETCHAR(1)=='-') {
  420. // _make_token(TK_OP_MINUS_MINUS);
  421. // INCPOS(1);
  422. } else {
  423. _make_token(TK_OP_SUB);
  424. }
  425. } break;
  426. case '%': {
  427. if (GETCHAR(1)=='=') {
  428. _make_token(TK_OP_ASSIGN_MOD);
  429. INCPOS(1);
  430. } else {
  431. _make_token(TK_OP_MOD);
  432. }
  433. } break;
  434. case '@':
  435. if (CharType(GETCHAR(1))!='"') {
  436. _make_error("Unexpected '@'");
  437. return;
  438. }
  439. INCPOS(1);
  440. is_node_path=true;
  441. case '"': {
  442. int i=1;
  443. String str;
  444. while(true) {
  445. if (CharType(GETCHAR(i)==0)) {
  446. _make_error("Unterminated String");
  447. return;
  448. } else if (CharType(GETCHAR(i)=='"')) {
  449. break;
  450. } else if (CharType(GETCHAR(i)=='\\')) {
  451. //escaped characters...
  452. i++;
  453. CharType next = GETCHAR(i);
  454. if (next==0) {
  455. _make_error("Unterminated String");
  456. return;
  457. }
  458. CharType res=0;
  459. switch(next) {
  460. case 'a': res=7; break;
  461. case 'b': res=8; break;
  462. case 't': res=9; break;
  463. case 'n': res=10; break;
  464. case 'v': res=11; break;
  465. case 'f': res=12; break;
  466. case 'r': res=13; break;
  467. case '\'': res='\''; break;
  468. case '\"': res='\"'; break;
  469. case '\\': res='\\'; break;
  470. case 'x': {
  471. //hexnumbarh - oct is deprecated
  472. int read=0;
  473. for(int j=0;j<4;j++) {
  474. CharType c = GETCHAR(i+j);
  475. if (c==0) {
  476. _make_error("Unterminated String");
  477. return;
  478. }
  479. if (!_is_hex(c)) {
  480. if (j==0 || !(j&1)) {
  481. _make_error("Malformed hex constant in string");
  482. return;
  483. } else
  484. break;
  485. }
  486. CharType v;
  487. if (c>='0' && c<='9') {
  488. v=c-'0';
  489. } else if (c>='a' && c<='f') {
  490. v=c-'a';
  491. v+=10;
  492. } else if (c>='A' && c<='F') {
  493. v=c-'A';
  494. v+=10;
  495. } else {
  496. ERR_PRINT("BUG");
  497. v=0;
  498. }
  499. res<<=4;
  500. res|=v;
  501. read++;
  502. }
  503. i+=read-1;
  504. } break;
  505. default: {
  506. _make_error("Invalid escape sequence");
  507. return;
  508. } break;
  509. }
  510. str+=res;
  511. } else {
  512. str+=CharType(GETCHAR(i));
  513. }
  514. i++;
  515. }
  516. INCPOS(i);
  517. if (is_node_path) {
  518. _make_constant(NodePath(str));
  519. } else {
  520. _make_constant(str);
  521. }
  522. } break;
  523. default: {
  524. if (_is_number(GETCHAR(0)) || (GETCHAR(0)=='.' && _is_number(GETCHAR(1)))) {
  525. // parse number
  526. bool period_found=false;
  527. bool exponent_found=false;
  528. bool hexa_found=false;
  529. bool sign_found=false;
  530. String str;
  531. int i=0;
  532. while(true) {
  533. if (GETCHAR(i)=='.') {
  534. if (period_found || exponent_found) {
  535. _make_error("Invalid numeric constant at '.'");
  536. return;
  537. }
  538. period_found=true;
  539. } else if (GETCHAR(i)=='x') {
  540. if (hexa_found || str.length()!=1 || !( (i==1 && str[0]=='0') || (i==2 && str[1]=='0' && str[0]=='-') ) ) {
  541. _make_error("Invalid numeric constant at 'x'");
  542. return;
  543. }
  544. hexa_found=true;
  545. } else if (!hexa_found && GETCHAR(i)=='e') {
  546. if (hexa_found || exponent_found) {
  547. _make_error("Invalid numeric constant at 'e'");
  548. return;
  549. }
  550. exponent_found=true;
  551. } else if (_is_number(GETCHAR(i))) {
  552. //all ok
  553. } else if (hexa_found && _is_hex(GETCHAR(i))) {
  554. } else if ((GETCHAR(i)=='-' || GETCHAR(i)=='+') && exponent_found) {
  555. if (sign_found) {
  556. _make_error("Invalid numeric constant at '-'");
  557. return;
  558. }
  559. sign_found=true;
  560. } else
  561. break;
  562. str+=CharType(GETCHAR(i));
  563. i++;
  564. }
  565. if (!( _is_number(str[str.length()-1]) || (hexa_found && _is_hex(str[str.length()-1])))) {
  566. _make_error("Invalid numeric constant: "+str);
  567. return;
  568. }
  569. INCPOS(str.length());
  570. if (hexa_found) {
  571. int val = str.hex_to_int();
  572. _make_constant(val);
  573. } else if (period_found) {
  574. real_t val = str.to_double();
  575. //print_line("*%*%*%*% to convert: "+str+" result: "+rtos(val));
  576. _make_constant(val);
  577. } else {
  578. int val = str.to_int();
  579. _make_constant(val);
  580. }
  581. return;
  582. }
  583. if (GETCHAR(0)=='.') {
  584. //parse period
  585. _make_token(TK_PERIOD);
  586. break;
  587. }
  588. if (_is_text_char(GETCHAR(0))) {
  589. // parse identifier
  590. String str;
  591. str+=CharType(GETCHAR(0));
  592. int i=1;
  593. while(_is_text_char(GETCHAR(i))) {
  594. str+=CharType(GETCHAR(i));
  595. i++;
  596. }
  597. bool identifier=false;
  598. if (str=="null") {
  599. _make_constant(Variant());
  600. } else if (str=="true") {
  601. _make_constant(true);
  602. } else if (str=="false") {
  603. _make_constant(false);
  604. } else {
  605. bool found=false;
  606. struct _bit { Variant::Type type; const char *text;};
  607. //built in types
  608. static const _bit type_list[]={
  609. //types
  610. {Variant::BOOL,"bool"},
  611. {Variant::INT,"int"},
  612. {Variant::REAL,"float"},
  613. {Variant::STRING,"String"},
  614. {Variant::VECTOR2,"vec2"},
  615. {Variant::VECTOR2,"Vector2"},
  616. {Variant::RECT2,"Rect2"},
  617. {Variant::MATRIX32,"Matrix32"},
  618. {Variant::MATRIX32,"mat32"},
  619. {Variant::VECTOR3,"vec3"},
  620. {Variant::VECTOR3,"Vector3"},
  621. {Variant::_AABB,"AABB"},
  622. {Variant::_AABB,"Rect3"},
  623. {Variant::PLANE,"Plane"},
  624. {Variant::QUAT,"Quat"},
  625. {Variant::MATRIX3,"mat3"},
  626. {Variant::MATRIX3,"Matrix3"},
  627. {Variant::TRANSFORM,"trn"},
  628. {Variant::TRANSFORM,"Transform"},
  629. {Variant::COLOR,"Color"},
  630. {Variant::IMAGE,"Image"},
  631. {Variant::_RID,"RID"},
  632. {Variant::OBJECT,"Object"},
  633. {Variant::INPUT_EVENT,"InputEvent"},
  634. {Variant::DICTIONARY,"dict"},
  635. {Variant::DICTIONARY,"Dictionary"},
  636. {Variant::ARRAY,"Array"},
  637. {Variant::RAW_ARRAY,"RawArray"},
  638. {Variant::INT_ARRAY,"IntArray"},
  639. {Variant::REAL_ARRAY,"FloatArray"},
  640. {Variant::STRING_ARRAY,"StringArray"},
  641. {Variant::VECTOR2_ARRAY,"Vector2Array"},
  642. {Variant::VECTOR3_ARRAY,"Vector3Array"},
  643. {Variant::COLOR_ARRAY,"ColorArray"},
  644. {Variant::VARIANT_MAX,NULL},
  645. };
  646. {
  647. int idx=0;
  648. while(type_list[idx].text) {
  649. if (str==type_list[idx].text) {
  650. _make_type(type_list[idx].type);
  651. found=true;
  652. break;
  653. }
  654. idx++;
  655. }
  656. }
  657. if (!found) {
  658. //built in func?
  659. for(int i=0;i<GDFunctions::FUNC_MAX;i++) {
  660. if (str==GDFunctions::get_func_name(GDFunctions::Function(i))) {
  661. _make_built_in_func(GDFunctions::Function(i));
  662. found=true;
  663. break;
  664. }
  665. }
  666. //keywor
  667. }
  668. if (!found) {
  669. struct _kws { Token token; const char *text;};
  670. static const _kws keyword_list[]={
  671. //ops
  672. {TK_OP_IN,"in"},
  673. {TK_OP_NOT,"not"},
  674. {TK_OP_OR,"or"},
  675. {TK_OP_AND,"and"},
  676. //func
  677. {TK_PR_FUNCTION,"func"},
  678. {TK_PR_FUNCTION,"function"},
  679. {TK_PR_CLASS,"class"},
  680. {TK_PR_EXTENDS,"extends"},
  681. {TK_PR_TOOL,"tool"},
  682. {TK_PR_STATIC,"static"},
  683. {TK_PR_EXPORT,"export"},
  684. {TK_PR_VAR,"var"},
  685. {TK_PR_PRELOAD,"preload"},
  686. {TK_PR_ASSERT,"assert"},
  687. {TK_PR_CONST,"const"},
  688. //controlflow
  689. {TK_CF_IF,"if"},
  690. {TK_CF_ELIF,"elif"},
  691. {TK_CF_ELSE,"else"},
  692. {TK_CF_FOR,"for"},
  693. {TK_CF_WHILE,"while"},
  694. {TK_CF_DO,"do"},
  695. {TK_CF_SWITCH,"switch"},
  696. {TK_CF_BREAK,"break"},
  697. {TK_CF_CONTINUE,"continue"},
  698. {TK_CF_RETURN,"return"},
  699. {TK_CF_PASS,"pass"},
  700. {TK_SELF,"self"},
  701. {TK_ERROR,NULL}
  702. };
  703. int idx=0;
  704. found=false;
  705. while(keyword_list[idx].text) {
  706. if (str==keyword_list[idx].text) {
  707. _make_token(keyword_list[idx].token);
  708. found=true;
  709. break;
  710. }
  711. idx++;
  712. }
  713. }
  714. if (!found)
  715. identifier=true;
  716. }
  717. if (identifier) {
  718. _make_identifier(str);
  719. }
  720. INCPOS(str.length());
  721. return;
  722. }
  723. _make_error("Unknown character");
  724. return;
  725. } break;
  726. }
  727. INCPOS(1);
  728. break;
  729. }
  730. }
  731. void GDTokenizer::set_code(const String& p_code) {
  732. code=p_code;
  733. len = p_code.length();
  734. if (len) {
  735. _code=&code[0];
  736. } else {
  737. _code=NULL;
  738. }
  739. code_pos=0;
  740. line=1; //it is stand-ar-ized that lines begin in 1 in code..
  741. column=0;
  742. tk_rb_pos=0;
  743. error_flag=false;
  744. last_error="";
  745. for(int i=0;i<MAX_LOOKAHEAD+1;i++)
  746. _advance();
  747. }
  748. GDTokenizer::Token GDTokenizer::get_token(int p_offset) const {
  749. ERR_FAIL_COND_V( p_offset <= -MAX_LOOKAHEAD, TK_ERROR);
  750. ERR_FAIL_COND_V( p_offset >= MAX_LOOKAHEAD, TK_ERROR);
  751. int ofs = (TK_RB_SIZE + tk_rb_pos + p_offset - MAX_LOOKAHEAD -1)%TK_RB_SIZE;
  752. return tk_rb[ofs].type;
  753. }
  754. int GDTokenizer::get_token_line(int p_offset) const {
  755. ERR_FAIL_COND_V( p_offset <= -MAX_LOOKAHEAD, -1);
  756. ERR_FAIL_COND_V( p_offset >= MAX_LOOKAHEAD, -1);
  757. int ofs = (TK_RB_SIZE + tk_rb_pos + p_offset - MAX_LOOKAHEAD -1)%TK_RB_SIZE;
  758. return tk_rb[ofs].line;
  759. }
  760. int GDTokenizer::get_token_column(int p_offset) const {
  761. ERR_FAIL_COND_V( p_offset <= -MAX_LOOKAHEAD, -1);
  762. ERR_FAIL_COND_V( p_offset >= MAX_LOOKAHEAD, -1);
  763. int ofs = (TK_RB_SIZE + tk_rb_pos + p_offset - MAX_LOOKAHEAD -1)%TK_RB_SIZE;
  764. return tk_rb[ofs].col;
  765. }
  766. const Variant& GDTokenizer::get_token_constant(int p_offset) const {
  767. ERR_FAIL_COND_V( p_offset <= -MAX_LOOKAHEAD, tk_rb[0].constant);
  768. ERR_FAIL_COND_V( p_offset >= MAX_LOOKAHEAD, tk_rb[0].constant);
  769. int ofs = (TK_RB_SIZE + tk_rb_pos + p_offset - MAX_LOOKAHEAD -1)%TK_RB_SIZE;
  770. ERR_FAIL_COND_V(tk_rb[ofs].type!=TK_CONSTANT,tk_rb[0].constant);
  771. return tk_rb[ofs].constant;
  772. }
  773. StringName GDTokenizer::get_token_identifier(int p_offset) const {
  774. ERR_FAIL_COND_V( p_offset <= -MAX_LOOKAHEAD, StringName());
  775. ERR_FAIL_COND_V( p_offset >= MAX_LOOKAHEAD, StringName());
  776. int ofs = (TK_RB_SIZE + tk_rb_pos + p_offset - MAX_LOOKAHEAD -1)%TK_RB_SIZE;
  777. ERR_FAIL_COND_V(tk_rb[ofs].type!=TK_IDENTIFIER,StringName());
  778. return tk_rb[ofs].identifier;
  779. }
  780. GDFunctions::Function GDTokenizer::get_token_built_in_func(int p_offset) const {
  781. ERR_FAIL_COND_V( p_offset <= -MAX_LOOKAHEAD, GDFunctions::FUNC_MAX);
  782. ERR_FAIL_COND_V( p_offset >= MAX_LOOKAHEAD, GDFunctions::FUNC_MAX);
  783. int ofs = (TK_RB_SIZE + tk_rb_pos + p_offset - MAX_LOOKAHEAD -1)%TK_RB_SIZE;
  784. ERR_FAIL_COND_V(tk_rb[ofs].type!=TK_BUILT_IN_FUNC,GDFunctions::FUNC_MAX);
  785. return tk_rb[ofs].func;
  786. }
  787. Variant::Type GDTokenizer::get_token_type(int p_offset) const {
  788. ERR_FAIL_COND_V( p_offset <= -MAX_LOOKAHEAD, Variant::NIL);
  789. ERR_FAIL_COND_V( p_offset >= MAX_LOOKAHEAD, Variant::NIL);
  790. int ofs = (TK_RB_SIZE + tk_rb_pos + p_offset - MAX_LOOKAHEAD -1)%TK_RB_SIZE;
  791. ERR_FAIL_COND_V(tk_rb[ofs].type!=TK_BUILT_IN_TYPE,Variant::NIL);
  792. return tk_rb[ofs].vtype;
  793. }
  794. int GDTokenizer::get_token_line_indent(int p_offset) const {
  795. ERR_FAIL_COND_V( p_offset <= -MAX_LOOKAHEAD, 0);
  796. ERR_FAIL_COND_V( p_offset >= MAX_LOOKAHEAD, 0);
  797. int ofs = (TK_RB_SIZE + tk_rb_pos + p_offset - MAX_LOOKAHEAD -1)%TK_RB_SIZE;
  798. ERR_FAIL_COND_V(tk_rb[ofs].type!=TK_NEWLINE,0);
  799. return tk_rb[ofs].constant;
  800. }
  801. String GDTokenizer::get_token_error(int p_offset) const {
  802. ERR_FAIL_COND_V( p_offset <= -MAX_LOOKAHEAD, String());
  803. ERR_FAIL_COND_V( p_offset >= MAX_LOOKAHEAD, String());
  804. int ofs = (TK_RB_SIZE + tk_rb_pos + p_offset - MAX_LOOKAHEAD -1)%TK_RB_SIZE;
  805. ERR_FAIL_COND_V(tk_rb[ofs].type!=TK_ERROR,String());
  806. return tk_rb[ofs].constant;
  807. }
  808. void GDTokenizer::advance(int p_amount) {
  809. ERR_FAIL_COND( p_amount <=0 );
  810. for(int i=0;i<p_amount;i++)
  811. _advance();
  812. }