General Purpose library for Freestanding C++ and POSIX systems
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

957 lines
27 KiB

  1. #pragma once
  2. #include "gp/containers/array.hpp"
  3. #include "gp/containers/vector.hpp"
  4. #include "gp/text/ascii.hpp"
  5. using string = gp::vector<char>;
  6. #define FOREACH_LEXEME_TYPE \
  7. LEX(leftBracket) \
  8. LEX(rightBracket) \
  9. LEX(leftParenthesis) \
  10. LEX(rightParenthesis) \
  11. LEX(leftCurlyBrace) \
  12. LEX(rightCurlyBrace) \
  13. LEX(period) \
  14. LEX(semicolon) \
  15. LEX(colon) \
  16. LEX(doubleColon) \
  17. LEX(comma) \
  18. LEX(at) \
  19. LEX(pointer) \
  20. LEX(as) \
  21. LEX(try_) \
  22. LEX(catch_) \
  23. LEX(raise_) \
  24. LEX(defer) \
  25. LEX(assign) \
  26. LEX(addAssign) \
  27. LEX(substractAssign) \
  28. LEX(multiplyAssign) \
  29. LEX(divideAssign) \
  30. LEX(concatenateAssign) \
  31. LEX(remainderAssign) \
  32. LEX(powerAssign) \
  33. LEX(plus) \
  34. LEX(minus) \
  35. LEX(add) \
  36. LEX(substract) \
  37. LEX(multiply) \
  38. LEX(divide) \
  39. LEX(concatenate) \
  40. LEX(remainder) \
  41. LEX(power) \
  42. LEX(equal) \
  43. LEX(doubleEqual) \
  44. LEX(threeWayComparison) \
  45. LEX(notEqual) \
  46. LEX(greaterOrEqual) \
  47. LEX(greater) \
  48. LEX(lesserOrEqual) \
  49. LEX(lesser) \
  50. LEX(leftShift) \
  51. LEX(rightShift) \
  52. LEX(and_) \
  53. LEX(or_) \
  54. LEX(xor_) \
  55. LEX(not_) \
  56. LEX(increment) \
  57. LEX(decrement) \
  58. LEX(identifier) \
  59. LEX(integer) \
  60. LEX(float_) \
  61. LEX(boolean) \
  62. LEX(string_) \
  63. LEX(null_) \
  64. LEX(public_) \
  65. LEX(main_) \
  66. LEX(type_) \
  67. LEX(event_) \
  68. LEX(class_) \
  69. LEX(enum_) \
  70. LEX(template_) \
  71. LEX(new_) \
  72. LEX(copy) \
  73. LEX(send) \
  74. LEX(receive) \
  75. LEX(intType) \
  76. LEX(floatType) \
  77. LEX(boolType) \
  78. LEX(stringType) \
  79. LEX(arrayType) \
  80. LEX(functionType) \
  81. LEX(taskType) \
  82. LEX(chanType) \
  83. LEX(autoType) \
  84. LEX(if_) \
  85. LEX(unless) \
  86. LEX(else_) \
  87. LEX(switch_) \
  88. LEX(select) \
  89. LEX(case_) \
  90. LEX(while_) \
  91. LEX(do_) \
  92. LEX(until) \
  93. LEX(for_) \
  94. LEX(loop) \
  95. LEX(return_) \
  96. LEX(self) \
  97. LEX(kill) \
  98. LEX(killAll) \
  99. LEX(yield) \
  100. LEX(break_) \
  101. LEX(continue_)
  102. #define LEX(x) x,
  103. enum class gr_lexeme_type {
  104. FOREACH_LEXEME_TYPE
  105. };
  106. #undef LEX
  107. #define LEX(x) case gr_lexeme_type::x: return #x;
  108. constexpr inline const char* to_string(const gr_lexeme_type& value) {
  109. switch(value) {
  110. FOREACH_LEXEME_TYPE
  111. }
  112. }
  113. #undef LEX
  114. #define LEX(x) +1
  115. constexpr inline const char* to_pretty_string(const gr_lexeme_type& value) {
  116. constexpr gp::array<const char*, 0 + FOREACH_LEXEME_TYPE> names = {
  117. "[", "]", "(", ")", "{", "}", ".", ";", ":", "::", ",", "@", "&", "as",
  118. "try", "catch", "raise", "defer", "=", "+=", "-=", "*=", "/=", "~=",
  119. "%=", "^=", "+", "-", "+", "-", "*", "/", "~", "%", "^", "==", "===",
  120. "<=>", "!=", ">=", ">", "<=", "<", "<<", ">>", "and", "or", "xor", "not", "++",
  121. "--", "identifier", "const_int", "const_float", "const_bool",
  122. "const_str", "null", "pub", "main", "type", "event", "class", "enum",
  123. "template", "new", "copy", "send", "receive", "int", "float", "bool",
  124. "string", "array", "func", "task", "chan", "let", "if", "unless",
  125. "else", "switch", "select", "case", "while", "do", "until", "for", "loop",
  126. "return", "self", "kill", "killall", "yield", "break", "continue"
  127. };
  128. return names[(uint64_t)value];
  129. }
  130. #undef LEX
  131. struct gr_lexeme;
  132. class gr_lexer {
  133. public:
  134. using file_loader_t = gp::function<gp::vector<char>(const gp::vector<char>&)>;
  135. gp::allocator& _allocator;
  136. file_loader_t file_loader;
  137. private:
  138. gp::vector<string> _files_to_import, _files_imported, _lines;
  139. string _file, _text;
  140. uint64_t _line, _current, _position_of_line, _file_id;
  141. gp::vector<gr_lexeme> _lexemes;
  142. char get(ssize_t offset = 0);
  143. bool advance(bool start_from_current = false);
  144. void scan_script();
  145. void scan_number();
  146. void scan_string();
  147. void scan_operator();
  148. void scan_word();
  149. void scan_file_path();
  150. void scan_use();
  151. string convert_path_to_import(string&);
  152. public:
  153. gr_lexer(gp::allocator& alloc, file_loader_t& loader)
  154. : _allocator(alloc)
  155. , file_loader(loader)
  156. , _files_to_import(_allocator)
  157. , _files_imported(_allocator)
  158. , _lines(_allocator)
  159. , _file(_allocator)
  160. , _text(_allocator)
  161. , _lexemes(_allocator)
  162. {}
  163. const gp::vector<gr_lexeme>& lexemes() {
  164. return _lexemes;
  165. }
  166. void scan_file(gp::vector<char>& file_name);
  167. const string& get_line(const gr_lexeme&) const;
  168. const string& get_file(const gr_lexeme&) const;
  169. const string& get_file(const size_t&) const;
  170. };
  171. struct gr_lexeme {
  172. const gr_lexer& lexer;
  173. size_t _file_id;
  174. size_t _line, _column, _text_length = 1;
  175. gr_lexeme_type type;
  176. bool
  177. is_literal,
  178. is_operator,
  179. is_keyword,
  180. is_type;
  181. int ivalue;
  182. float fvalue;
  183. bool bvalue;
  184. string svalue;
  185. gr_lexeme(const gr_lexer& v)
  186. : lexer(v)
  187. , svalue(v._allocator)
  188. {}
  189. const string& get_line() const {
  190. return lexer.get_line(*this);
  191. }
  192. const string& get_file() {
  193. return lexer.get_file(*this);
  194. }
  195. };
  196. inline char gr_lexer::get(ssize_t offset) {
  197. const uint position = ssize_t(_current) + offset;
  198. gp_config::assertion(!(position < 0 || position >= _text.size()), "Unexpected end of script");
  199. return _text[position];
  200. }
  201. inline const string& gr_lexer::get_line(const gr_lexeme& lex) const {
  202. gp_config::assertion(!(lex._file_id >= _files_imported.size()), "Lexeme file id out of bounds");
  203. // TODO: Implement this
  204. return _files_imported[lex._file_id];
  205. }
  206. inline const string& gr_lexer::get_file(const gr_lexeme& lex) const {
  207. gp_config::assertion(!(lex._file_id >= _files_imported.size()), "Lexeme file id out of bounds");
  208. return _files_imported[lex._file_id];
  209. }
  210. inline const string& gr_lexer::get_file(const size_t& file_id) const {
  211. gp_config::assertion(!(file_id >= _files_imported.size()), "File id out of bounds");
  212. return _files_imported[file_id];
  213. }
  214. inline bool gr_lexer::advance(bool start_from_current) {
  215. if(!start_from_current) {
  216. _current++;
  217. }
  218. if(_current >= _text.size()) {
  219. return false;
  220. }
  221. char symbol = _text[_current];
  222. whileLoop: while(symbol <= 0x20 || symbol == '/' || symbol == '#') {
  223. if(_current >= _text.size()) {
  224. return false;
  225. }
  226. symbol = _text[_current];
  227. if(symbol == '\n') {
  228. _position_of_line = _current;
  229. _line++;
  230. }
  231. else if(symbol == '#')
  232. {
  233. do {
  234. if(_current >= _text.size()) return false;
  235. _current++;
  236. } while (_text[_current] != '\n');
  237. _position_of_line = _current;
  238. _line++;
  239. }
  240. else if(symbol == '/')
  241. {
  242. if((_current + 1) >= _text.size()) {
  243. return false;
  244. }
  245. switch(_text[_current + 1]) {
  246. case '/': {
  247. do {
  248. if(_current >= _text.size()) {
  249. return false;
  250. }
  251. } while(_current < _text.size() && _text[_current] != '\n');
  252. _position_of_line = _current;
  253. _line++;
  254. }break;
  255. case '*': {
  256. for(;;) {
  257. if((_current + 1) >= _text.size()) {
  258. _current++;
  259. return false;
  260. }
  261. if(_text[_current] == '\n') {
  262. _position_of_line = _current;
  263. _line++;
  264. }
  265. if(_text[_current] == '*' && _text[_current + 1] == '/') {
  266. _current++;
  267. break;
  268. }
  269. _current++;
  270. }
  271. }break;
  272. default:
  273. // Goto honorable
  274. goto whileLoop;
  275. }
  276. }
  277. _current++;
  278. if(_current >= _text.size()) {
  279. return false;
  280. }
  281. symbol = _text[_current];
  282. }
  283. return true;
  284. }
  285. inline void gr_lexer::scan_script() {
  286. advance(true);
  287. constexpr static auto is_operator = [](char v) {
  288. if(v == '!') return true;
  289. if(v >= '#' && v <='&') return true;
  290. if(v >= '(' && v <='-') return true;
  291. if(v == '/') return true;
  292. if(v >= ':' && v <='@') return true;
  293. if(v >= '[' && v <='^') return true;
  294. if(v >= '{' && v <='~') return true;
  295. return false;
  296. };
  297. do {
  298. if (_current >= _text.size())
  299. break;
  300. auto c = get();
  301. if(is_digit(c)) scan_number();
  302. else if(c == '.') {
  303. if (get(1) >= '0' && get(1) <= '9')
  304. scan_number();
  305. else
  306. scan_operator();
  307. }
  308. else if(is_operator(c)) scan_operator();
  309. else if(c == '\"') scan_string();
  310. else scan_word();
  311. }while (advance());
  312. }
  313. inline void gr_lexer::scan_number(){
  314. gr_lexeme lex = gr_lexeme(*this);
  315. lex.is_literal = true;
  316. bool isFloat;
  317. string buffer(_allocator);
  318. for (;;) {
  319. char symbol = get();
  320. if (symbol >= '0' && symbol <= '9')
  321. buffer.push_back(symbol);
  322. else if (symbol == '_') {
  323. // Do nothing, only cosmetic (e.g. 1_000_000).
  324. }
  325. else if (symbol == '.') {
  326. if (isFloat)
  327. break;
  328. isFloat = true;
  329. buffer.push_back(symbol);
  330. }
  331. else if (symbol == 'f') {
  332. isFloat = true;
  333. break;
  334. }
  335. else {
  336. if (_current)
  337. _current--;
  338. break;
  339. }
  340. _current++;
  341. if (_current >= _text.size())
  342. break;
  343. }
  344. }
  345. inline void gr_lexer::scan_string(){
  346. gr_lexeme lex = gr_lexeme(*this);
  347. lex.type = gr_lexeme_type::string_;
  348. lex.is_literal = true;
  349. gp_config::assertion(get() != '\"',"Expected \'\"\' at the beginning of the string.");
  350. _current++;
  351. string buffer(_allocator);
  352. bool escape = false;
  353. bool wasEscape = false;
  354. for (;;) {
  355. gp_config::assertion(_current >= _text.size(),"Missing \'\"\' character.");
  356. char symbol = get();
  357. if (symbol == '\n') {
  358. _position_of_line = _current;
  359. _line++;
  360. }
  361. else if (symbol == '\"' && (!wasEscape))
  362. break;
  363. else if (symbol == '\\' && (!wasEscape)) {
  364. escape = true;
  365. }
  366. if (!escape) {
  367. if (!wasEscape) {
  368. buffer.push_back(symbol);
  369. }
  370. else {
  371. if (symbol == 'n')
  372. buffer.push_back('\n');
  373. else
  374. buffer.push_back(symbol);
  375. }
  376. }
  377. wasEscape = escape;
  378. escape = false;
  379. _current++;
  380. }
  381. lex._text_length = size_t(buffer.size() + 2u);
  382. lex.svalue = buffer;
  383. _lexemes.push_back(lex);
  384. }
  385. inline void gr_lexer::scan_operator(){
  386. gr_lexeme lex = gr_lexeme(*this);
  387. lex.is_operator = true;
  388. switch (get()) {
  389. case '{':
  390. lex.type = gr_lexeme_type::leftCurlyBrace;
  391. break;
  392. case '}':
  393. lex.type = gr_lexeme_type::rightCurlyBrace;
  394. break;
  395. case '(':
  396. lex.type = gr_lexeme_type::leftParenthesis;
  397. break;
  398. case ')':
  399. lex.type = gr_lexeme_type::rightParenthesis;
  400. break;
  401. case '[':
  402. lex.type = gr_lexeme_type::leftBracket;
  403. break;
  404. case ']':
  405. lex.type = gr_lexeme_type::rightBracket;
  406. break;
  407. case '.':
  408. lex.type = gr_lexeme_type::period;
  409. break;
  410. case ';':
  411. lex.type = gr_lexeme_type::semicolon;
  412. break;
  413. case ':':
  414. lex.type = gr_lexeme_type::colon;
  415. if (_current + 1 >= _text.size())
  416. break;
  417. if (get(1) == ':') {
  418. lex.type = gr_lexeme_type::doubleColon;
  419. lex._text_length = 2;
  420. _current++;
  421. }
  422. break;
  423. case ',':
  424. lex.type = gr_lexeme_type::comma;
  425. break;
  426. case '^':
  427. lex.type = gr_lexeme_type::power;
  428. if (_current + 1 >= _text.size())
  429. break;
  430. if (get(1) == '=') {
  431. lex.type = gr_lexeme_type::powerAssign;
  432. lex._text_length = 2;
  433. _current++;
  434. }
  435. break;
  436. case '@':
  437. lex.type = gr_lexeme_type::at;
  438. break;
  439. case '&':
  440. lex.type = gr_lexeme_type::pointer;
  441. break;
  442. case '~':
  443. lex.type = gr_lexeme_type::concatenate;
  444. if (_current + 1 >= _text.size())
  445. break;
  446. if (get(1) == '=') {
  447. lex.type = gr_lexeme_type::concatenateAssign;
  448. lex._text_length = 2;
  449. _current++;
  450. }
  451. break;
  452. case '+':
  453. lex.type = gr_lexeme_type::add;
  454. if (_current + 1 >= _text.size())
  455. break;
  456. switch (get(1)) {
  457. case '=':
  458. lex.type = gr_lexeme_type::addAssign;
  459. lex._text_length = 2;
  460. _current++;
  461. break;
  462. case '+':
  463. lex.type = gr_lexeme_type::increment;
  464. lex._text_length = 2;
  465. _current++;
  466. break;
  467. default:
  468. break;
  469. }
  470. break;
  471. case '-':
  472. lex.type = gr_lexeme_type::substract;
  473. if (_current + 1 >= _text.size())
  474. break;
  475. switch (get(1)) {
  476. case '=':
  477. lex.type = gr_lexeme_type::substractAssign;
  478. lex._text_length = 2;
  479. _current++;
  480. break;
  481. case '-':
  482. lex.type = gr_lexeme_type::decrement;
  483. lex._text_length = 2;
  484. _current++;
  485. break;
  486. default:
  487. break;
  488. }
  489. break;
  490. case '*':
  491. lex.type = gr_lexeme_type::multiply;
  492. if (_current + 1 >= _text.size())
  493. break;
  494. if (get(1) == '=') {
  495. lex.type = gr_lexeme_type::multiplyAssign;
  496. lex._text_length = 2;
  497. _current++;
  498. }
  499. break;
  500. case '/':
  501. lex.type = gr_lexeme_type::divide;
  502. if (_current + 1 >= _text.size())
  503. break;
  504. if (get(1) == '=') {
  505. lex.type = gr_lexeme_type::divideAssign;
  506. lex._text_length = 2;
  507. _current++;
  508. }
  509. break;
  510. case '%':
  511. lex.type = gr_lexeme_type::remainder;
  512. if (_current + 1 >= _text.size())
  513. break;
  514. if (get(1) == '=') {
  515. lex.type = gr_lexeme_type::remainderAssign;
  516. lex._text_length = 2;
  517. _current++;
  518. }
  519. break;
  520. case '=':
  521. lex.type = gr_lexeme_type::assign;
  522. if (_current + 1 >= _text.size())
  523. break;
  524. if (get(1) == '=') {
  525. lex.type = gr_lexeme_type::equal;
  526. lex._text_length = 2;
  527. _current++;
  528. if (_current + 1 >= _text.size())
  529. break;
  530. if (get(1) == '=') {
  531. lex.type = gr_lexeme_type::doubleEqual;
  532. lex._text_length = 3;
  533. _current++;
  534. }
  535. }
  536. break;
  537. case '<':
  538. lex.type = gr_lexeme_type::lesser;
  539. if (_current + 1 >= _text.size())
  540. break;
  541. if (get(1) == '=') {
  542. lex.type = gr_lexeme_type::lesserOrEqual;
  543. lex._text_length = 2;
  544. _current++;
  545. if (_current + 1 >= _text.size())
  546. break;
  547. if (get(1) == '>') {
  548. lex.type = gr_lexeme_type::threeWayComparison;
  549. lex._text_length = 3;
  550. _current++;
  551. }
  552. }
  553. else if (get(1) == '-') {
  554. lex.type = gr_lexeme_type::send;
  555. lex._text_length = 2;
  556. _current++;
  557. }
  558. else if (get(1) == '<') {
  559. lex.type = gr_lexeme_type::leftShift;
  560. lex._text_length = 2;
  561. _current++;
  562. }
  563. break;
  564. case '>':
  565. lex.type = gr_lexeme_type::greater;
  566. if (_current + 1 >= _text.size())
  567. break;
  568. if (get(1) == '=') {
  569. lex.type = gr_lexeme_type::greaterOrEqual;
  570. lex._text_length = 2;
  571. _current++;
  572. }
  573. else if (get(1) == '>') {
  574. lex.type = gr_lexeme_type::rightShift;
  575. lex._text_length = 2;
  576. _current++;
  577. }
  578. break;
  579. case '!':
  580. lex.type = gr_lexeme_type::not_;
  581. if (_current + 1 >= _text.size())
  582. break;
  583. if (get(1) == '=') {
  584. lex.type = gr_lexeme_type::notEqual;
  585. lex._text_length = 2;
  586. _current++;
  587. }
  588. break;
  589. default:
  590. gp_config::assertion(false, "GrLexer: invalid operator");
  591. }
  592. _lexemes.push_back(lex);
  593. }
  594. namespace _hidden {
  595. bool operator==(const gp::vector<char>& lhs, const char* rhs) {
  596. for(size_t index = 0; index < lhs.size() && rhs[index] != 0; index++){
  597. if(lhs[index] != rhs[index]) return false;
  598. }
  599. return true;
  600. }
  601. }
  602. inline void gr_lexer::scan_word(){
  603. gr_lexeme lex = gr_lexeme(*this);
  604. lex.is_keyword = true;
  605. string symbol_buffer(_allocator);
  606. for (;;) {
  607. if (_current >= _text.size())
  608. break;
  609. char symbol = get();
  610. if (symbol == '!' || symbol == '?') {
  611. symbol_buffer.push_back(symbol);
  612. _current++;
  613. break;
  614. }
  615. if (symbol <= '&' || (symbol >= '(' && symbol <= '/') || (symbol >= ':'
  616. && symbol <= '@') || (symbol >= '[' && symbol <= '^')
  617. || (symbol >= '{' && symbol <= 0x7F))
  618. break;
  619. symbol_buffer.push_back(symbol);
  620. _current++;
  621. }
  622. _current--;
  623. lex._text_length = symbol_buffer.size();
  624. using namespace _hidden;
  625. if(symbol_buffer == "use"){
  626. scan_use();
  627. return;
  628. }
  629. else if(symbol_buffer == "pub"){
  630. lex.type = gr_lexeme_type::public_;
  631. }
  632. else if(symbol_buffer == "main"){
  633. lex.type = gr_lexeme_type::main_;
  634. }
  635. else if(symbol_buffer == "type"){
  636. lex.type = gr_lexeme_type::type_;
  637. }
  638. else if(symbol_buffer == "event"){
  639. lex.type = gr_lexeme_type::event_;
  640. }
  641. else if(symbol_buffer == "class"){
  642. lex.type = gr_lexeme_type::class_;
  643. }
  644. else if(symbol_buffer == "enum"){
  645. lex.type = gr_lexeme_type::enum_;
  646. }
  647. else if(symbol_buffer == "template"){
  648. lex.type = gr_lexeme_type::template_;
  649. }
  650. else if(symbol_buffer == "if"){
  651. lex.type = gr_lexeme_type::if_;
  652. }
  653. else if(symbol_buffer == "unless"){
  654. lex.type = gr_lexeme_type::unless;
  655. }
  656. else if(symbol_buffer == "else"){
  657. lex.type = gr_lexeme_type::else_;
  658. }
  659. else if(symbol_buffer == "switch"){
  660. lex.type = gr_lexeme_type::switch_;
  661. }
  662. else if(symbol_buffer == "select"){
  663. lex.type = gr_lexeme_type::select;
  664. }
  665. else if(symbol_buffer == "case"){
  666. lex.type = gr_lexeme_type::case_;
  667. }
  668. else if(symbol_buffer == "while"){
  669. lex.type = gr_lexeme_type::while_;
  670. }
  671. else if(symbol_buffer == "do"){
  672. lex.type = gr_lexeme_type::do_;
  673. }
  674. else if(symbol_buffer == "until"){
  675. lex.type = gr_lexeme_type::until;
  676. }
  677. else if(symbol_buffer == "for"){
  678. lex.type = gr_lexeme_type::for_;
  679. }
  680. else if(symbol_buffer == "loop"){
  681. lex.type = gr_lexeme_type::loop;
  682. }
  683. else if(symbol_buffer == "return"){
  684. lex.type = gr_lexeme_type::return_;
  685. }
  686. else if(symbol_buffer == "self"){
  687. lex.type = gr_lexeme_type::self;
  688. }
  689. else if(symbol_buffer == "kill"){
  690. lex.type = gr_lexeme_type::kill;
  691. }
  692. else if(symbol_buffer == "killall"){
  693. lex.type = gr_lexeme_type::killAll;
  694. }
  695. else if(symbol_buffer == "yield"){
  696. lex.type = gr_lexeme_type::yield;
  697. }
  698. else if(symbol_buffer == "break"){
  699. lex.type = gr_lexeme_type::break_;
  700. }
  701. else if(symbol_buffer == "continue"){
  702. lex.type = gr_lexeme_type::continue_;
  703. }
  704. else if(symbol_buffer == "as"){
  705. lex.type = gr_lexeme_type::as;
  706. }
  707. else if(symbol_buffer == "try"){
  708. lex.type = gr_lexeme_type::try_;
  709. }
  710. else if(symbol_buffer == "catch"){
  711. lex.type = gr_lexeme_type::catch_;
  712. }
  713. else if(symbol_buffer == "raise"){
  714. lex.type = gr_lexeme_type::raise_;
  715. }
  716. else if(symbol_buffer == "defer"){
  717. lex.type = gr_lexeme_type::defer;
  718. }
  719. else if(symbol_buffer == "task"){
  720. lex.type = gr_lexeme_type::taskType;
  721. lex.is_type = true;
  722. }
  723. else if(symbol_buffer == "func"){
  724. lex.type = gr_lexeme_type::functionType;
  725. lex.is_type = true;
  726. }
  727. else if(symbol_buffer == "int"){
  728. lex.type = gr_lexeme_type::intType;
  729. lex.is_type = true;
  730. }
  731. else if(symbol_buffer == "float"){
  732. lex.type = gr_lexeme_type::floatType;
  733. lex.is_type = true;
  734. }
  735. else if(symbol_buffer == "bool"){
  736. lex.type = gr_lexeme_type::boolType;
  737. lex.is_type = true;
  738. }
  739. else if(symbol_buffer == "string"){
  740. lex.type = gr_lexeme_type::stringType;
  741. lex.is_type = true;
  742. }
  743. else if(symbol_buffer == "array"){
  744. lex.type = gr_lexeme_type::arrayType;
  745. lex.is_type = true;
  746. }
  747. else if(symbol_buffer == "chan"){
  748. lex.type = gr_lexeme_type::chanType;
  749. lex.is_type = true;
  750. }
  751. else if(symbol_buffer == "new"){
  752. lex.type = gr_lexeme_type::new_;
  753. lex.is_type = false;
  754. }
  755. else if(symbol_buffer == "let"){
  756. lex.type = gr_lexeme_type::autoType;
  757. lex.is_type = false;
  758. }
  759. else if(symbol_buffer == "true"){
  760. lex.type = gr_lexeme_type::boolean;
  761. lex.is_keyword = false;
  762. lex.is_literal = true;
  763. lex.bvalue = true;
  764. }
  765. else if(symbol_buffer == "false"){
  766. lex.type = gr_lexeme_type::boolean;
  767. lex.is_keyword = false;
  768. lex.is_literal = true;
  769. lex.bvalue = false;
  770. }
  771. else if(symbol_buffer == "null"){
  772. lex.type = gr_lexeme_type::null_;
  773. lex.is_keyword = false;
  774. lex.is_literal = true;
  775. }
  776. else if(symbol_buffer == "not"){
  777. lex.type = gr_lexeme_type::not_;
  778. lex.is_keyword = false;
  779. lex.is_operator = true;
  780. }
  781. else if(symbol_buffer == "and"){
  782. lex.type = gr_lexeme_type::and_;
  783. lex.is_keyword = false;
  784. lex.is_operator = true;
  785. }
  786. else if(symbol_buffer == "or"){
  787. lex.type = gr_lexeme_type::or_;
  788. lex.is_keyword = false;
  789. lex.is_operator = true;
  790. }
  791. else if(symbol_buffer == "xor"){
  792. lex.type = gr_lexeme_type::xor_;
  793. lex.is_keyword = false;
  794. lex.is_operator = true;
  795. } else {
  796. lex.is_keyword = false;
  797. lex.type = gr_lexeme_type::identifier;
  798. lex.svalue = symbol_buffer;
  799. }
  800. _lexemes.push_back(lex);
  801. }
  802. inline string gr_lexer::convert_path_to_import(string& path) {
  803. return path;
  804. }
  805. inline void gr_lexer::scan_file(gp::vector<char>& file_name){
  806. _files_to_import.push_back(file_name);
  807. while (_files_to_import.size()) {
  808. _file = _files_to_import[_files_to_import.size()-1];
  809. _files_imported.push_back(_file);
  810. _text = file_loader(file_name);
  811. _files_to_import.pop_back();
  812. _line = 0u;
  813. _current = 0u;
  814. _lines = gp::vector<string>(_allocator);
  815. gp::vector<char> tmp(_allocator);
  816. for(char c : _text) {
  817. if(c == '\n') {
  818. _lines.push_back(tmp);
  819. tmp = gp::vector<char>(_allocator);
  820. } else {
  821. tmp.push_back(c);
  822. }
  823. }
  824. scan_script();
  825. _file_id++;
  826. }
  827. }
  828. inline void gr_lexer::scan_file_path(){
  829. gp_config::assertion(get() != '\"', "Expected \'\"\' at the beginning of the import.");
  830. _current++;
  831. string buffer(_allocator);
  832. for (;;) {
  833. gp_config::assertion(_current >= _text.size(), "Missing \'\"\' character.");
  834. char symbol = get();
  835. if (symbol == '\n') {
  836. _position_of_line = _current;
  837. _line++;
  838. }
  839. else if (symbol == '\"')
  840. break;
  841. buffer.push_back(symbol);
  842. _current++;
  843. }
  844. buffer = convert_path_to_import(buffer);
  845. for(auto& file : _files_imported) {
  846. if(file == buffer) return;
  847. }
  848. for(auto& file : _files_to_import) {
  849. if(file == buffer) return;
  850. }
  851. _files_to_import.push_back(buffer);
  852. }
  853. inline void gr_lexer::scan_use(){
  854. advance();
  855. // Multiple files import.
  856. if (get() == '{') {
  857. advance();
  858. bool isFirst = true;
  859. for (;;) {
  860. if (isFirst)
  861. isFirst = false;
  862. else if (get() == '\"')
  863. advance();
  864. else
  865. gp_config::assertion(false, "Missing \'}\' after import list.");
  866. // EOF
  867. gp_config::assertion(_current >= _text.size(), "Missing \'}\' after import list.");
  868. // End of the import list.
  869. if (get() == '}')
  870. break;
  871. // Scan
  872. scan_file_path();
  873. }
  874. }
  875. else {
  876. scan_file_path();
  877. }
  878. }