/winxedst0.cpp

http://github.com/NotFound/winxed · C++ · 6494 lines · 5816 code · 541 blank · 137 comment · 799 complexity · 48432d18214d862feaa6834e8061c257 MD5 · raw file

Large files are truncated click here to view the full file

  1. // winxedst0.cpp
  2. // Revision 25-jun-2012
  3. // Winxed compiler stage 0.
  4. #include "token.h"
  5. #include "errors.h"
  6. #include "emit.h"
  7. #include <string>
  8. #include <iostream>
  9. #include <istream>
  10. #include <fstream>
  11. #include <sstream>
  12. #include <cctype>
  13. #include <vector>
  14. #include <map>
  15. #include <algorithm>
  16. #include <stdexcept>
  17. #include <string.h>
  18. #include <errno.h>
  19. #include <typeinfo>
  20. //**********************************************************************
  21. // Register types
  22. const char REGint = 'I';
  23. const char REGstring = 'S';
  24. const char REGvar = 'P';
  25. // Pseudotypes for builtins
  26. const char REGany = '?';
  27. const char REGnone = '\0'; // void return
  28. static const char * nameoftype(char ctype)
  29. {
  30. switch (ctype)
  31. {
  32. case REGint: return "int";
  33. case REGstring: return "string";
  34. case REGvar: return "pmc";
  35. default:
  36. throw CompileError("Invalid type");
  37. }
  38. }
  39. char nativetype(const Token &name)
  40. {
  41. if (name.iskeyword("int")) return REGint;
  42. else if (name.iskeyword("string")) return REGstring;
  43. else if (name.iskeyword("var")) return REGvar;
  44. else return '\0';
  45. }
  46. //**********************************************************************
  47. #define INDENT " "
  48. #define INDENTLABEL " "
  49. inline
  50. std::string op(const char *name, const std::string &op1)
  51. {
  52. return INDENT + std::string(name) + ' ' + op1;
  53. }
  54. inline
  55. std::string op(const char *name,
  56. const std::string &op1, const std::string &op2)
  57. {
  58. return INDENT + std::string(name) + ' ' + op1 + ", " + op2;
  59. }
  60. inline
  61. std::string op(const char *name,
  62. const std::string &op1,
  63. const std::string &op2, const std::string &op3)
  64. {
  65. return INDENT + std::string(name) + ' ' + op1 + ", " + op2 + ", " + op3;
  66. }
  67. inline
  68. std::string op_inc(const std::string &op1)
  69. {
  70. return op("inc", op1);
  71. }
  72. inline
  73. std::string op_dec(const std::string &op1)
  74. {
  75. return op("dec", op1);
  76. }
  77. inline
  78. std::string op_set(const std::string &res, const std::string &op1)
  79. {
  80. return op("set", res, op1);
  81. }
  82. inline
  83. std::string op_assign(const std::string &res, const std::string &op1)
  84. {
  85. return op("assign", res, op1);
  86. }
  87. inline
  88. std::string op_box(const std::string &res, const std::string &op1)
  89. {
  90. return op("box", res, op1);
  91. }
  92. inline
  93. std::string op_add(const std::string &res,
  94. const std::string &op1, const std::string &op2)
  95. {
  96. return op("add", res, op1, op2);
  97. }
  98. inline
  99. std::string op_sub(const std::string &res,
  100. const std::string &op1, const std::string &op2)
  101. {
  102. return op("sub", res, op1, op2);
  103. }
  104. inline
  105. std::string op_mul(const std::string &res,
  106. const std::string &op1, const std::string &op2)
  107. {
  108. return op("mul", res, op1, op2);
  109. }
  110. inline
  111. std::string op_div(const std::string &res,
  112. const std::string &op1, const std::string &op2)
  113. {
  114. return op("div", res, op1, op2);
  115. }
  116. inline
  117. std::string op_mod(const std::string &res,
  118. const std::string &op1, const std::string &op2)
  119. {
  120. return op("mod", res, op1, op2);
  121. }
  122. inline
  123. std::string op_cmod(const std::string &res,
  124. const std::string &op1, const std::string &op2)
  125. {
  126. return op("cmod", res, op1, op2);
  127. }
  128. inline
  129. std::string op_null(const std::string &res)
  130. {
  131. return op("null", res);
  132. }
  133. inline
  134. std::string op_isnull(const std::string &res, const std::string &op1)
  135. {
  136. return op("isnull", res, op1);
  137. }
  138. inline
  139. std::string op_iseq(const std::string &res,
  140. const std::string &op1, const std::string &op2)
  141. {
  142. return op("iseq", res, op1, op2);
  143. }
  144. inline
  145. std::string op_isne(const std::string &res,
  146. const std::string &op1, const std::string &op2)
  147. {
  148. return op("isne", res, op1, op2);
  149. }
  150. inline
  151. std::string op_islt(const std::string &res,
  152. const std::string &op1, const std::string &op2)
  153. {
  154. return op("islt", res, op1, op2);
  155. }
  156. inline
  157. std::string op_isgt(const std::string &res,
  158. const std::string &op1, const std::string &op2)
  159. {
  160. return op("isgt", res, op1, op2);
  161. }
  162. inline
  163. std::string op_isle(const std::string &res,
  164. const std::string &op1, const std::string &op2)
  165. {
  166. return op("isle", res, op1, op2);
  167. }
  168. inline
  169. std::string op_isge(const std::string &res,
  170. const std::string &op1, const std::string &op2)
  171. {
  172. return op("isge", res, op1, op2);
  173. }
  174. inline
  175. std::string op_isa(const std::string &res,
  176. const std::string &op1, const std::string &op2)
  177. {
  178. return op("isa", res, op1, op2);
  179. }
  180. //**********************************************************************
  181. inline void RequireOp(char name, const Token &t)
  182. {
  183. if (! t.isop(name) )
  184. throw Expected (name, t);
  185. }
  186. inline void ExpectOp(char name, Tokenizer &tk)
  187. {
  188. Token t= tk.get();
  189. RequireOp(name, t);
  190. }
  191. //**********************************************************************
  192. template <typename T>
  193. void emit_group(const std::vector<T *> &group, Emit &e)
  194. {
  195. for (size_t i= 0; i < group.size(); ++i)
  196. group[i]->emit(e);
  197. }
  198. //**********************************************************************
  199. class BuiltinFunction
  200. {
  201. public:
  202. static const int VarArgs = -1;
  203. BuiltinFunction(const std::string &name, char typeresult, int nargs) :
  204. pname(name),
  205. tresult(typeresult),
  206. n(nargs)
  207. {
  208. }
  209. BuiltinFunction(const std::string &name, char typeresult) :
  210. pname(name),
  211. tresult(typeresult),
  212. n(VarArgs)
  213. {
  214. }
  215. static const BuiltinFunction *find(const std::string &name,
  216. size_t numargs);
  217. bool name_is(const std::string &name) const
  218. { return pname == name; }
  219. size_t numargs() const { return n; }
  220. char resulttype() const { return tresult; }
  221. virtual char paramtype(size_t n) const = 0;
  222. virtual void emit(Emit &e, const std::string &result,
  223. const std::vector<std::string> args) const = 0;
  224. private:
  225. static const BuiltinFunction *builtins[];
  226. static const size_t numbuiltins;
  227. const std::string pname;
  228. char tresult;
  229. unsigned int n;
  230. };
  231. class BuiltinFunctionFixargs : public BuiltinFunction
  232. {
  233. public:
  234. BuiltinFunctionFixargs(const std::string &name,
  235. const std::string &body,
  236. char typeresult,
  237. char type0= '\0',
  238. char type1= '\0',
  239. char type2= '\0',
  240. char type3= '\0');
  241. private:
  242. void emit(Emit &e, const std::string &result,
  243. const std::vector<std::string> args) const;
  244. char paramtype(size_t n) const
  245. {
  246. switch(n)
  247. {
  248. case 0: return t0;
  249. case 1: return t1;
  250. case 2: return t2;
  251. case 3: return t3;
  252. default: return '\0';
  253. }
  254. }
  255. char t0, t1, t2, t3;
  256. std::vector<std::string> chunks;
  257. std::vector<int> marks;
  258. };
  259. class BuiltinFunctionVarargs : public BuiltinFunction
  260. {
  261. protected:
  262. BuiltinFunctionVarargs(const std::string &name,
  263. char typeresult) :
  264. BuiltinFunction(name, typeresult)
  265. { }
  266. char paramtype(size_t /*unused*/) const
  267. {
  268. return REGany;
  269. }
  270. };
  271. class Builtin_print : public BuiltinFunctionVarargs
  272. {
  273. public:
  274. Builtin_print() : BuiltinFunctionVarargs("print", REGnone)
  275. { }
  276. private:
  277. void emit(Emit &e, const std::string &,
  278. const std::vector<std::string> args) const
  279. {
  280. const size_t n = args.size();
  281. for (size_t i= 0; i < n; ++i)
  282. e << INDENT "print " << args[i] << '\n';
  283. }
  284. };
  285. class Builtin_say : public BuiltinFunctionVarargs
  286. {
  287. public:
  288. Builtin_say() : BuiltinFunctionVarargs("say", REGnone)
  289. { }
  290. private:
  291. void emit(Emit &e, const std::string &,
  292. const std::vector<std::string> args) const
  293. {
  294. const size_t n = args.size();
  295. if (n > 0) {
  296. for (size_t i= 0; i < n - 1; ++i)
  297. e << INDENT "print " << args[i] << '\n';
  298. e << INDENT "say " << args[n-1] << '\n';
  299. }
  300. else
  301. e << INDENT "say ''\n";
  302. }
  303. };
  304. class Builtin_cry : public BuiltinFunctionVarargs
  305. {
  306. public:
  307. Builtin_cry() : BuiltinFunctionVarargs("cry", REGnone)
  308. { }
  309. private:
  310. void emit(Emit &e, const std::string &,
  311. const std::vector<std::string> args) const
  312. {
  313. e <<
  314. INDENT "getstderr $P0\n";
  315. const size_t n = args.size();
  316. for (size_t i= 0; i < n; ++i)
  317. e << INDENT "$P0.'print'(" << args[i] << ")\n";
  318. e << INDENT "$P0.'print'(\"\\n\")\n";
  319. }
  320. };
  321. class Builtin_ASSERT : public BuiltinFunction
  322. {
  323. public:
  324. Builtin_ASSERT() : BuiltinFunction("__ASSERT__", REGnone, 1)
  325. { }
  326. char paramtype(size_t n) const { return REGint; }
  327. void emit(Emit &e, const std::string &,
  328. const std::vector<std::string> args) const
  329. {
  330. if (e.getDebug())
  331. {
  332. e <<
  333. INDENT ".const 'Sub' __WINXED_ASSERT_check ='__WINXED_ASSERT_check'\n"
  334. INDENT "__WINXED_ASSERT_check(" << args[0] << ")\n";
  335. }
  336. }
  337. };
  338. const BuiltinFunction *BuiltinFunction::builtins[]= {
  339. new Builtin_ASSERT(),
  340. new Builtin_print(),
  341. new Builtin_say(),
  342. new Builtin_cry(),
  343. new BuiltinFunctionFixargs("int",
  344. "{res} = {arg0}",
  345. REGint, REGany),
  346. new BuiltinFunctionFixargs("string",
  347. "{res} = {arg0}",
  348. REGstring, REGany),
  349. new BuiltinFunctionFixargs("exit",
  350. "exit {arg0}",
  351. REGnone, REGint),
  352. new BuiltinFunctionFixargs("spawnw",
  353. "spawnw {res}, {arg0}",
  354. REGint, REGvar),
  355. new BuiltinFunctionFixargs("getstdin",
  356. "getstdin {res}",
  357. REGvar),
  358. new BuiltinFunctionFixargs("getstdout",
  359. "getstdout {res}",
  360. REGvar),
  361. new BuiltinFunctionFixargs("getstderr",
  362. "getstderr {res}",
  363. REGvar),
  364. new BuiltinFunctionFixargs("open",
  365. "root_new {res}, ['parrot';'FileHandle']\n"
  366. "{res}.'open'({arg0})",
  367. REGvar, REGstring),
  368. new BuiltinFunctionFixargs("open",
  369. "root_new {res}, ['parrot';'FileHandle']\n"
  370. "{res}.'open'({arg0},{arg1})",
  371. REGvar, REGstring, REGstring),
  372. new BuiltinFunctionFixargs("Error",
  373. "root_new {res}, ['parrot';'Exception']\n"
  374. "{res}['message'] = {arg0}\n"
  375. , REGvar, REGstring),
  376. new BuiltinFunctionFixargs("Error",
  377. "root_new {res}, ['parrot';'Exception']\n"
  378. "{res}['message'] = {arg0}\n"
  379. "{res}['severity'] = {arg1}\n"
  380. , REGvar, REGstring, REGint),
  381. new BuiltinFunctionFixargs("Error",
  382. "root_new {res}, ['parrot';'Exception']\n"
  383. "{res}['message'] = {arg0}\n"
  384. "{res}['severity'] = {arg1}\n"
  385. "{res}['type'] = {arg2}\n"
  386. , REGvar, REGstring, REGint, REGint),
  387. new BuiltinFunctionFixargs("Error",
  388. "root_new {res}, ['parrot';'Exception']\n"
  389. "{res}['message'] = {arg0}\n"
  390. "{res}['severity'] = {arg1}\n"
  391. "{res}['type'] = {arg2}\n"
  392. "{res}['payload'] = {arg3}\n"
  393. , REGvar, REGstring, REGint, REGint, REGvar),
  394. new BuiltinFunctionFixargs("elements",
  395. "elements {res}, {arg0}",
  396. REGint, REGvar),
  397. new BuiltinFunctionFixargs("length",
  398. "length {res}, {arg0}",
  399. REGint, REGstring),
  400. new BuiltinFunctionFixargs("bytelength",
  401. "bytelength {res}, {arg0}",
  402. REGint, REGstring),
  403. new BuiltinFunctionFixargs("chr",
  404. "chr $S0, {arg0}\n"
  405. "find_encoding $I0, 'utf8'\n"
  406. "trans_encoding {res}, $S0, $I0\n",
  407. REGstring, REGint),
  408. new BuiltinFunctionFixargs("ord",
  409. "ord {res}, {arg0}",
  410. REGint, REGstring),
  411. new BuiltinFunctionFixargs("ord",
  412. "ord {res}, {arg0}, {arg1}",
  413. REGint, REGstring, REGint),
  414. new BuiltinFunctionFixargs("substr",
  415. "substr {res}, {arg0}, {arg1}",
  416. REGstring, REGstring, REGint),
  417. new BuiltinFunctionFixargs("substr",
  418. "substr {res}, {arg0}, {arg1}, {arg2}",
  419. REGstring, REGstring, REGint, REGint),
  420. new BuiltinFunctionFixargs("replace",
  421. "replace {res}, {arg0}, {arg1}, {arg2}, {arg3}",
  422. REGstring, REGstring, REGint, REGint, REGstring),
  423. new BuiltinFunctionFixargs("indexof",
  424. "index {res}, {arg0}, {arg1}",
  425. REGint, REGstring, REGstring),
  426. new BuiltinFunctionFixargs("indexof",
  427. "index {res}, {arg0}, {arg1}, {arg2}",
  428. REGint, REGstring, REGstring, REGint),
  429. new BuiltinFunctionFixargs("escape",
  430. "escape {res}, {arg0}",
  431. REGstring, REGstring),
  432. new BuiltinFunctionFixargs("unescape",
  433. "$P0 = new ['String']\n"
  434. "$P0 = {arg0}\n"
  435. "{res} = $P0.'unescape'('utf8')\n",
  436. REGstring, REGstring),
  437. new BuiltinFunctionFixargs("unescape",
  438. "$P0 = new ['String']\n"
  439. "$P0 = {arg0}\n"
  440. "{res} = $P0.'unescape'({arg1})\n",
  441. REGstring, REGstring, REGstring),
  442. new BuiltinFunctionFixargs("upcase",
  443. "upcase {res}, {arg0}",
  444. REGstring, REGstring),
  445. new BuiltinFunctionFixargs("downcase",
  446. "downcase {res}, {arg0}",
  447. REGstring, REGstring),
  448. new BuiltinFunctionFixargs("titlecase",
  449. "titlecase {res}, {arg0}",
  450. REGstring, REGstring),
  451. new BuiltinFunctionFixargs("join",
  452. "join {res}, {arg0}, {arg1}",
  453. REGstring, REGstring, REGvar),
  454. new BuiltinFunctionFixargs("split",
  455. "split {res}, {arg0}, {arg1}",
  456. REGvar, REGstring, REGstring),
  457. new BuiltinFunctionFixargs("push",
  458. "push {arg0}, {arg1}",
  459. REGnone, REGvar, REGany),
  460. new BuiltinFunctionFixargs("getinterp",
  461. "getinterp {res}",
  462. REGvar),
  463. new BuiltinFunctionFixargs("get_class",
  464. "get_class {res}, {arg0}",
  465. REGvar, REGstring),
  466. new BuiltinFunctionFixargs("typeof",
  467. "typeof {res}, {arg0}",
  468. REGvar, REGvar),
  469. new BuiltinFunctionFixargs("clone",
  470. "clone {res}, {arg0}",
  471. REGvar, REGvar),
  472. new BuiltinFunctionFixargs("compreg",
  473. "compreg {res}, {arg0}",
  474. REGvar, REGstring),
  475. new BuiltinFunctionFixargs("compreg",
  476. "compreg {arg0}, {arg1}",
  477. REGnone, REGstring, REGvar),
  478. new BuiltinFunctionFixargs("load_language",
  479. "load_language {arg0}\n"
  480. "compreg {res}, {arg0}",
  481. REGvar, REGstring),
  482. new BuiltinFunctionFixargs("load_language",
  483. "load_language {arg0}\n"
  484. "compreg {res}, {arg1}",
  485. REGvar, REGstring, REGstring),
  486. new BuiltinFunctionFixargs("loadlib",
  487. "loadlib {res}, {arg0}",
  488. REGvar, REGstring),
  489. new BuiltinFunctionFixargs("load_bytecode",
  490. "load_bytecode {arg0}",
  491. REGvar, REGstring),
  492. new BuiltinFunctionFixargs("sprintf",
  493. "sprintf {res}, {arg0}, {arg1}",
  494. REGstring, REGstring, REGvar)
  495. };
  496. const size_t BuiltinFunction::numbuiltins =
  497. sizeof(BuiltinFunction::builtins) / sizeof(BuiltinFunction::builtins[0]);
  498. const BuiltinFunction *BuiltinFunction::find(const std::string &name,
  499. size_t numargs)
  500. {
  501. for (size_t i= 0; i < numbuiltins; ++i) {
  502. int n = builtins[i]->n;
  503. if ((n == BuiltinFunction::VarArgs || n == int(numargs)) &&
  504. builtins[i]->name_is(name) )
  505. return builtins[i];
  506. }
  507. return 0;
  508. }
  509. BuiltinFunctionFixargs::BuiltinFunctionFixargs(const std::string &name,
  510. const std::string &body,
  511. char typeresult,
  512. char type0, char type1, char type2, char type3) :
  513. BuiltinFunction(name, typeresult,
  514. bool(type0) +bool(type1) + bool(type2) + bool(type3) ),
  515. t0(type0), t1(type1), t2(type2), t3(type3)
  516. {
  517. const size_t ntags = 5;
  518. const std::string tags[ntags] =
  519. { "{res}", "{arg0}", "{arg1}", "{arg2}", "{arg3}" };
  520. std::string::size_type pos[ntags];
  521. std::string aux = body;
  522. for (;;)
  523. {
  524. for (size_t i = 0; i < ntags; ++i)
  525. pos[i] = aux.find(tags[i]);
  526. const std::string::size_type *minp = std::min_element(pos, pos + ntags);
  527. size_t minpos = minp - pos;
  528. std::string::size_type mpos = pos[minpos];
  529. if (mpos == std::string::npos)
  530. break;
  531. chunks.push_back(aux.substr(0, mpos));
  532. marks.push_back(minpos);
  533. aux.erase(0, mpos + tags[minpos].length());
  534. }
  535. if (aux.length() > 0)
  536. {
  537. chunks.push_back(aux);
  538. marks.push_back(-1);
  539. }
  540. }
  541. void BuiltinFunctionFixargs::emit(Emit &e, const std::string &result,
  542. const std::vector<std::string> args) const
  543. {
  544. std::string body;
  545. size_t n = chunks.size();
  546. for (size_t i = 0; i < n; ++i)
  547. {
  548. body+= chunks[i];
  549. int m = marks[i];
  550. switch (m)
  551. {
  552. case 0:
  553. body+= result;
  554. break;
  555. case 1: case 2: case 3: case 4:
  556. body+= args[m-1];
  557. break;
  558. case -1:
  559. break;
  560. default:
  561. throw InternalError("Unexpected failure in builtin");
  562. }
  563. }
  564. size_t pos = 0;
  565. size_t prev = 0;
  566. while ((pos = body.find("\n", prev)) != std::string::npos)
  567. {
  568. e << INDENT << body.substr(prev, pos - prev + 1);
  569. prev = pos + 1;
  570. }
  571. e << INDENT << body.substr(prev) << '\n';
  572. }
  573. //**********************************************************************
  574. class Annotated
  575. {
  576. protected:
  577. Annotated(const Token & tstart) : start(tstart)
  578. { }
  579. public:
  580. void annotate(Emit &e)
  581. {
  582. e.annotate(start);
  583. }
  584. const Token & getstart() const
  585. {
  586. return start;
  587. }
  588. private:
  589. const Token start;
  590. };
  591. //**********************************************************************
  592. class ConstantValue
  593. {
  594. public:
  595. ConstantValue(char type, const Token &value) :
  596. t(type), v(value)
  597. {
  598. switch(t)
  599. {
  600. case REGint:
  601. if (!v.isinteger())
  602. throw SyntaxError("Invalid const int value", v);
  603. break;
  604. case REGstring:
  605. if (!v.isliteralstring())
  606. throw SyntaxError("Invalid const string value", v);
  607. break;
  608. case 'n':
  609. // Special case
  610. if (!v.isidentifier())
  611. throw SyntaxError("Invalid const string value", v);
  612. break;
  613. default:
  614. throw InternalError("Invalid const type");
  615. }
  616. }
  617. char type() const { return t; }
  618. Token value() const { return v; }
  619. private:
  620. char t;
  621. Token v;
  622. };
  623. //**********************************************************************
  624. class ClassStatement;
  625. typedef std::vector<std::string> ClassKey;
  626. std::string dotted(const ClassKey &ck)
  627. {
  628. size_t l = ck.size();
  629. if (l == 0)
  630. return "(anonimous)";
  631. else
  632. {
  633. std::string r = ck[0];
  634. for (size_t i = 1; i < l; ++i)
  635. {
  636. r+= '.';
  637. r+= ck[i];
  638. }
  639. return r;
  640. }
  641. }
  642. //**********************************************************************
  643. class FunctionStatement;
  644. class BlockBase
  645. {
  646. public:
  647. virtual char checklocal(const std::string &name) const = 0;
  648. virtual char checkconstant(const std::string &name) const = 0;
  649. virtual ConstantValue getconstant(const std::string &name) const = 0;
  650. virtual FunctionStatement *getfunction(const std::string &name) const = 0;
  651. virtual void genconstant(const std::string &name, char type, const Token &value) = 0;
  652. virtual std::string genlocallabel() = 0;
  653. virtual std::string genlocalregister(char type)= 0;
  654. virtual void freelocalregister(const std::string &)= 0;
  655. virtual std::string gentemp(char /*unused*/)
  656. {
  657. throw std::runtime_error("No temp registers here!");
  658. }
  659. virtual void freetempregs()
  660. {
  661. throw std::runtime_error("No temp registers here!");
  662. }
  663. virtual void genlocal(const std::string &name, char type) = 0;
  664. virtual bool islocal(std::string /*name*/) const = 0;
  665. virtual std::string getbreaklabel() const
  666. {
  667. throw std::runtime_error("No break allowed");
  668. }
  669. virtual std::string getcontinuelabel() const
  670. {
  671. throw std::runtime_error("No continue allowed");
  672. }
  673. virtual ClassStatement *findclass(const ClassKey &classkey)
  674. {
  675. std::cerr << "BlockBase::findclass **WRONG CALL**\n";
  676. return 0;
  677. }
  678. virtual ~BlockBase() { }
  679. };
  680. class Block : public BlockBase
  681. {
  682. public:
  683. Block();
  684. virtual unsigned int blockid() = 0;
  685. void genlocal(const std::string &name, char type);
  686. bool islocal(std::string name) const;
  687. void genconstant(const std::string &name, char type, const Token &value);
  688. char checklocal(const std::string &name) const;
  689. char checkconstant(const std::string &name) const;
  690. ConstantValue getconstant(const std::string &name) const;
  691. std::string genlabel();
  692. protected:
  693. typedef std::map<std::string, char> Locals;
  694. Locals locals;
  695. typedef std::map<std::string, ConstantValue> Constants;
  696. Constants constants;
  697. };
  698. class InBlock : public BlockBase
  699. {
  700. protected:
  701. InBlock(BlockBase &block) : bl(block) { };
  702. public:
  703. std::string getbreaklabel() const
  704. {
  705. return bl.getbreaklabel();
  706. }
  707. std::string getcontinuelabel() const
  708. {
  709. return bl.getcontinuelabel();
  710. }
  711. char checklocal(const std::string &name) const
  712. {
  713. return bl.checklocal(name);
  714. }
  715. char checkconstant(const std::string &name) const
  716. {
  717. return bl.checkconstant(name);
  718. }
  719. void genconstant(const std::string &name, char type, const Token &value)
  720. {
  721. bl.genconstant(name, type, value);
  722. }
  723. ConstantValue getconstant(const std::string &name) const
  724. {
  725. return bl.getconstant(name);
  726. }
  727. FunctionStatement *getfunction(const std::string &name) const
  728. {
  729. return bl.getfunction(name);
  730. }
  731. std::string genlocallabel()
  732. {
  733. return bl.genlocallabel();
  734. }
  735. std::string genlocalregister(char type)
  736. {
  737. return bl.genlocalregister(type);
  738. }
  739. void freelocalregister(const std::string &reg)
  740. {
  741. bl.freelocalregister(reg);
  742. }
  743. std::string gentemp(char type)
  744. {
  745. return bl.gentemp(type);
  746. }
  747. void freetempregs()
  748. {
  749. bl.freetempregs();
  750. }
  751. void genlocal(const std::string &name, char type)
  752. {
  753. bl.genlocal(name, type);
  754. }
  755. bool islocal(std::string name) const
  756. {
  757. return bl.islocal(name);
  758. }
  759. ClassStatement *findclass(const ClassKey &classkey)
  760. {
  761. return bl.findclass(classkey);
  762. }
  763. private:
  764. BlockBase &bl;
  765. };
  766. Block::Block()
  767. { }
  768. void Block::genlocal(const std::string &name, char type)
  769. {
  770. locals[name]= type;
  771. }
  772. bool Block::islocal(std::string name) const
  773. {
  774. return locals.find(name) != locals.end();
  775. }
  776. void Block::genconstant(const std::string &name, char type, const Token &value)
  777. {
  778. constants.insert(std::make_pair(name, ConstantValue(type, value)));
  779. }
  780. char Block::checklocal(const std::string &name) const
  781. {
  782. Locals::const_iterator it= locals.find(name);
  783. if (it != locals.end() )
  784. return it->second;
  785. Constants::const_iterator itc= constants.find(name);
  786. if (itc != constants.end() )
  787. return itc->second.type();
  788. return '\0';
  789. }
  790. char Block::checkconstant(const std::string &name) const
  791. {
  792. Constants::const_iterator itc= constants.find(name);
  793. if (itc != constants.end() )
  794. return itc->second.type();
  795. return '\0';
  796. }
  797. ConstantValue Block::getconstant(const std::string &name) const
  798. {
  799. Constants::const_iterator itc= constants.find(name);
  800. if (itc != constants.end() )
  801. return itc->second;
  802. throw InternalError("No such constant");
  803. }
  804. std::string Block::genlabel()
  805. {
  806. return genlocallabel();
  807. }
  808. //**********************************************************************
  809. class SubBlock : public Block
  810. {
  811. public:
  812. SubBlock(Block &parentblock) :
  813. parent(parentblock),
  814. id(parent.blockid()),
  815. nlabel(0)
  816. {
  817. }
  818. std::string getbreaklabel() const;
  819. std::string getcontinuelabel() const;
  820. bool islocal(std::string name) const;
  821. char checklocal(const std::string &name) const;
  822. char checkconstant(const std::string &name) const;
  823. ConstantValue getconstant(const std::string &name) const;
  824. FunctionStatement *getfunction(const std::string &name) const
  825. {
  826. return parent.getfunction(name);
  827. }
  828. std::string genlocalregister(char type)
  829. {
  830. return parent.genlocalregister(type);
  831. }
  832. void freelocalregister(const std::string &reg)
  833. {
  834. parent.freelocalregister(reg);
  835. }
  836. std::string gentemp(char type)
  837. {
  838. return parent.gentemp(type);
  839. }
  840. void freetempregs()
  841. {
  842. parent.freetempregs();
  843. }
  844. std::string genlocallabel();
  845. ClassStatement *findclass(const ClassKey &classkey)
  846. {
  847. return parent.findclass(classkey);
  848. }
  849. private:
  850. unsigned int blockid();
  851. Block &parent;
  852. unsigned int id;
  853. unsigned int nlabel;
  854. };
  855. unsigned int SubBlock::blockid()
  856. {
  857. return parent.blockid();
  858. }
  859. std::string SubBlock::getbreaklabel() const
  860. {
  861. return parent.getbreaklabel();
  862. }
  863. std::string SubBlock::getcontinuelabel() const
  864. {
  865. return parent.getcontinuelabel();
  866. }
  867. char SubBlock::checklocal(const std::string &name) const
  868. {
  869. if (char c= Block::checklocal(name))
  870. return c;
  871. else
  872. return parent.checklocal(name);
  873. }
  874. bool SubBlock::islocal(std::string name) const
  875. {
  876. return checklocal(name) != '\0';
  877. }
  878. char SubBlock::checkconstant(const std::string &name) const
  879. {
  880. char c= Block::checkconstant(name);
  881. if (c == '\0')
  882. c= parent.checkconstant(name);
  883. return c;
  884. }
  885. ConstantValue SubBlock::getconstant(const std::string &name) const
  886. {
  887. if (Block::checkconstant(name))
  888. return Block::getconstant(name);
  889. else
  890. return parent.getconstant(name);
  891. }
  892. std::string SubBlock::genlocallabel()
  893. {
  894. std::ostringstream l;
  895. l << "__label_" << id << '_' << ++nlabel;
  896. return l.str();
  897. }
  898. //**********************************************************************
  899. class NamespaceKey
  900. {
  901. typedef std::vector <std::string> key_t;
  902. public:
  903. NamespaceKey() { }
  904. NamespaceKey(const std::string &name) :
  905. key(1, name)
  906. {
  907. }
  908. NamespaceKey(const key_t &newkey) :
  909. key(newkey)
  910. {
  911. }
  912. bool isroot() const
  913. {
  914. return key.empty();
  915. }
  916. NamespaceKey parent() const
  917. {
  918. key_t newkey = key;
  919. newkey.pop_back();
  920. return NamespaceKey(newkey);
  921. }
  922. std::string get_key() const
  923. {
  924. std::string r= "[ ";
  925. for (size_t i= 0; i < key.size(); ++i)
  926. {
  927. if (i > 0)
  928. r+= "; ";
  929. r+= '\'' + key [i] + '\'';
  930. }
  931. r+= " ]";
  932. return r;
  933. }
  934. void emit (Emit &e) const
  935. {
  936. e << ".namespace " << get_key() << '\n';
  937. }
  938. private:
  939. std::vector <std::string> key;
  940. };
  941. //**********************************************************************
  942. class FunctionBlock : public SubBlock
  943. {
  944. public:
  945. FunctionBlock(Block &parent) :
  946. SubBlock(parent),
  947. subblocks(0),
  948. nreg(0), nlabel(0)
  949. {
  950. }
  951. public:
  952. std::string genlocallabel();
  953. std::string genlocalregister(char type);
  954. std::string gentemp(char type);
  955. std::string genregister(char type);
  956. void freelocalregister(const std::string &reg);
  957. void freeregister(const std::string &reg);
  958. protected:
  959. size_t tempsused() const
  960. {
  961. return tempi.size() + temps.size() + tempp.size() +
  962. + freetempi.size() + freetemps.size() + freetempp.size();
  963. }
  964. void freetempregs()
  965. {
  966. using std::copy;
  967. using std::back_inserter;
  968. copy(tempi.begin(), tempi.end(), back_inserter(freetempi));
  969. tempi= std::vector<std::string>();
  970. copy(temps.begin(), temps.end(), back_inserter(freetemps));
  971. temps= std::vector<std::string>();
  972. copy(tempp.begin(), tempp.end(), back_inserter(freetempp));
  973. tempp= std::vector<std::string>();
  974. }
  975. private:
  976. unsigned int subblocks;
  977. unsigned int nreg;
  978. unsigned int nlabel;
  979. std::vector <std::string> tempi;
  980. std::vector <std::string> temps;
  981. std::vector <std::string> tempp;
  982. std::vector <std::string> freetempi;
  983. std::vector <std::string> freetemps;
  984. std::vector <std::string> freetempp;
  985. };
  986. std::string FunctionBlock::genlocalregister(char type)
  987. {
  988. if (type != REGint && type != REGstring && type != REGvar)
  989. throw InternalError("invalid register type");
  990. std::ostringstream l;
  991. l << '$' << type << ++nreg;
  992. return l.str();
  993. }
  994. void FunctionBlock::freelocalregister(const std::string &reg)
  995. {
  996. if (reg.at(0) != '$')
  997. throw InternalError("invalid free register");
  998. switch(reg.at(1))
  999. {
  1000. case REGint: freetempi.push_back(reg); break;
  1001. case REGstring: freetemps.push_back(reg); break;
  1002. case REGvar: freetempp.push_back(reg); break;
  1003. default: throw InternalError("invalid free register");
  1004. }
  1005. }
  1006. void FunctionBlock::freeregister(const std::string &reg)
  1007. {
  1008. return freelocalregister(reg);
  1009. }
  1010. std::string FunctionBlock::genregister(char type)
  1011. {
  1012. return genlocalregister(type);
  1013. }
  1014. std::string FunctionBlock::gentemp(char type)
  1015. {
  1016. std::vector<std::string> &usefree= type == REGint ? freetempi :
  1017. type == REGstring ? freetemps : freetempp;
  1018. std::string temp;
  1019. if (usefree.size() > 0)
  1020. {
  1021. temp= usefree.back();
  1022. usefree.pop_back();
  1023. }
  1024. else
  1025. {
  1026. temp= genlocalregister(type);
  1027. switch(type)
  1028. {
  1029. case REGint: tempi.push_back(temp); break;
  1030. case REGstring: temps.push_back(temp); break;
  1031. default: tempp.push_back(temp); break;
  1032. }
  1033. }
  1034. return temp;
  1035. }
  1036. std::string FunctionBlock::genlocallabel()
  1037. {
  1038. std::ostringstream l;
  1039. l << "__label_" << ++nlabel;
  1040. return l.str();
  1041. }
  1042. //**********************************************************************
  1043. class NamespaceBlockBase;
  1044. class Expr;
  1045. //**********************************************************************
  1046. class BaseStatement
  1047. {
  1048. public:
  1049. virtual bool isempty() { return false; }
  1050. virtual void emit (Emit &e) = 0;
  1051. virtual BaseStatement *optimize() { return this; }
  1052. void optimize_branch(BaseStatement *&branch);
  1053. void optimize_branch(Expr *&branch);
  1054. virtual ~BaseStatement() { };
  1055. };
  1056. //**********************************************************************
  1057. class MultiStatement : public BaseStatement
  1058. {
  1059. public:
  1060. MultiStatement(BaseStatement *st1, BaseStatement *st2)
  1061. {
  1062. subst.push_back(st1);
  1063. subst.push_back(st2);
  1064. }
  1065. void push(BaseStatement *st)
  1066. {
  1067. subst.push_back(st);
  1068. }
  1069. private:
  1070. std::vector <BaseStatement *> subst;
  1071. BaseStatement *optimize()
  1072. {
  1073. for (size_t i= 0; i < subst.size(); ++i)
  1074. subst[i] = subst[i]->optimize();
  1075. return this;
  1076. }
  1077. void emit (Emit &e)
  1078. {
  1079. for (size_t i= 0; i < subst.size(); ++i)
  1080. subst[i]->emit(e);
  1081. }
  1082. };
  1083. BaseStatement *addtomulti(BaseStatement *oldst, BaseStatement *newst)
  1084. {
  1085. if (! oldst)
  1086. return newst;
  1087. else if (MultiStatement *multi = dynamic_cast<MultiStatement *>(oldst))
  1088. {
  1089. multi->push(newst);
  1090. return multi;
  1091. }
  1092. else
  1093. return new MultiStatement(oldst, newst);
  1094. }
  1095. //**********************************************************************
  1096. enum ClassSpecifierType
  1097. {
  1098. CLASSSPECIFIER_invalid,
  1099. CLASSSPECIFIER_parrotkey,
  1100. CLASSSPECIFIER_id
  1101. };
  1102. class ClassSpecifier : public Annotated
  1103. {
  1104. protected:
  1105. ClassSpecifier(const Token &t) : Annotated(t)
  1106. { }
  1107. public:
  1108. virtual ClassSpecifierType reftype() const
  1109. { return CLASSSPECIFIER_invalid; }
  1110. virtual ~ClassSpecifier() {}
  1111. virtual std::string basename() const = 0;
  1112. virtual void emit(Emit &e) = 0;
  1113. };
  1114. ClassSpecifier *parseClassSpecifier(const Token &start, Tokenizer &tk,
  1115. BlockBase &owner);
  1116. //**********************************************************************
  1117. class SubStatement : public BaseStatement, public InBlock
  1118. {
  1119. public:
  1120. SubStatement(Block &block);
  1121. };
  1122. SubStatement::SubStatement(Block &block) :
  1123. InBlock(block)
  1124. {
  1125. }
  1126. //**********************************************************************
  1127. class EmptyStatement : public BaseStatement
  1128. {
  1129. private:
  1130. bool isempty() { return true; }
  1131. void emit (Emit &) { };
  1132. };
  1133. //**********************************************************************
  1134. class BlockStatement : public BaseStatement, public SubBlock
  1135. {
  1136. public:
  1137. BlockStatement (Block &parentblock) :
  1138. SubBlock(parentblock)
  1139. {
  1140. }
  1141. };
  1142. //**********************************************************************
  1143. class Expr : public InBlock, public Annotated
  1144. {
  1145. public:
  1146. Expr(BlockBase &block, const Token & tstart) :
  1147. InBlock(block),
  1148. Annotated(tstart)
  1149. {
  1150. }
  1151. virtual Expr *optimize()
  1152. {
  1153. return this;
  1154. }
  1155. virtual bool isleft() const { return false; }
  1156. virtual void emitleft(Emit &)
  1157. {
  1158. std::cerr << typeid(*this).name() << '\n';
  1159. throw InternalError("Not a left-side expression");
  1160. }
  1161. virtual void emitleft(Emit &, const std::string &)
  1162. {
  1163. std::cerr << typeid(*this).name() << '\n';
  1164. throw InternalError("Not a left-side expression");
  1165. }
  1166. virtual void emitassign(Emit &, Expr &, const std::string &)
  1167. {
  1168. std::cerr << typeid(*this).name() << '\n';
  1169. throw InternalError("Not an assignable expression");
  1170. }
  1171. virtual void emit(Emit &e, const std::string &result) = 0;
  1172. virtual std::string emit_get(Emit &e);
  1173. virtual bool issimple() const { return false; }
  1174. virtual const Token &gettoken() const
  1175. {
  1176. std::cerr << typeid(*this).name() << '\n';
  1177. throw InternalError("In gettoken: Not a simple expression");
  1178. }
  1179. virtual bool isidentifier() const { return false; }
  1180. virtual std::string getidentifier() const
  1181. { throw InternalError("Not an identifier"); }
  1182. virtual bool isnull() const { return false; }
  1183. virtual bool isliteralinteger() const { return false; }
  1184. virtual bool isinteger() const { return false; }
  1185. virtual int getintegervalue () const
  1186. {
  1187. std::cerr << typeid(*this).name() << '\n';
  1188. throw InternalError("Not an integer");
  1189. }
  1190. virtual bool isliteralstring() const { return false; }
  1191. virtual std::string getstringvalue () const
  1192. { throw InternalError("Not a string"); }
  1193. virtual bool isstring() const { return false; }
  1194. virtual bool isindex() const { return false; }
  1195. char checkresult() const
  1196. {
  1197. if (isinteger() ) return REGint;
  1198. else if (isstring() ) return REGstring;
  1199. else return REGvar;
  1200. }
  1201. void optimize_branch(Expr *&branch)
  1202. { branch= branch->optimize(); }
  1203. };
  1204. Expr * parseExpr(BlockBase &block, Tokenizer &tk);
  1205. //**********************************************************************
  1206. class Condition : public InBlock
  1207. {
  1208. public:
  1209. Condition (Block &block, Tokenizer &tk);
  1210. Condition (BlockBase &block, Expr *condexpr);
  1211. Condition *optimize();
  1212. bool issimple() const;
  1213. bool isinteger() const { return true; }
  1214. //bool isstring() const { return expr->isstring(); }
  1215. bool isliteralinteger() const;
  1216. std::string value() const;
  1217. std::string emit(Emit &e);
  1218. void emit_if(Emit &e, const std::string &labeltrue);
  1219. void emit_else(Emit &e, const std::string &labelfalse);
  1220. enum Value { CVtrue, CVfalse, CVruntime };
  1221. Value getvalue() const;
  1222. private:
  1223. Expr *expr;
  1224. };
  1225. //**********************************************************************
  1226. void BaseStatement::optimize_branch(BaseStatement *&branch)
  1227. {
  1228. if (branch)
  1229. branch= branch->optimize();
  1230. }
  1231. void BaseStatement::optimize_branch(Expr *&branch)
  1232. {
  1233. if (branch)
  1234. branch= branch->optimize();
  1235. }
  1236. //**********************************************************************
  1237. class Modifier
  1238. {
  1239. public:
  1240. Modifier(BlockBase &block, Tokenizer &tk)
  1241. {
  1242. Token t= tk.get();
  1243. if (!t.isidentifier())
  1244. throw Expected("Modifier name", t);
  1245. start = t;
  1246. name= t.identifier();
  1247. t= tk.get();
  1248. if (!t.isop('('))
  1249. tk.unget(t);
  1250. else
  1251. {
  1252. do
  1253. {
  1254. args.push_back(parseExpr(block, tk));
  1255. } while ((t= tk.get()).isop(','));
  1256. RequireOp(')', t);
  1257. }
  1258. }
  1259. std::string getname() const { return name; }
  1260. Token getstart() const { return start; }
  1261. void optimize()
  1262. {
  1263. for (size_t i= 0; i < args.size(); ++i)
  1264. args[i]= args[i]->optimize();
  1265. }
  1266. size_t numargs() const { return args.size(); }
  1267. Expr *getarg(size_t narg) const
  1268. {
  1269. return args.at(narg);
  1270. }
  1271. int getintegervalue(size_t narg) const
  1272. {
  1273. Expr *arg= args.at(narg);
  1274. return arg->getintegervalue();
  1275. }
  1276. std::string getstringvalue(size_t narg) const
  1277. {
  1278. Expr *arg= args.at(narg);
  1279. return arg->getstringvalue();
  1280. }
  1281. private:
  1282. Token start;
  1283. std::string name;
  1284. std::vector <Expr *> args;
  1285. };
  1286. //**********************************************************************
  1287. class ModifierList
  1288. {
  1289. public:
  1290. bool has_modifier(const std::string &name) const
  1291. {
  1292. return modifiers.find(name) != modifiers.end();
  1293. }
  1294. const Modifier * getmodifier(const std::string &name) const
  1295. {
  1296. ModList::const_iterator it= modifiers.find(name);
  1297. if (it != modifiers.end())
  1298. return &it->second;
  1299. else
  1300. return NULL;
  1301. }
  1302. void parse(BlockBase &block, Tokenizer &tk)
  1303. {
  1304. Token t;
  1305. do {
  1306. Modifier m(block, tk);
  1307. std::string name= m.getname();
  1308. modifiers.insert(std::make_pair(name, m));
  1309. } while ((t= tk.get()).isop(','));
  1310. RequireOp(']', t);
  1311. }
  1312. void optimize()
  1313. {
  1314. for (ModList::iterator it= modifiers.begin();
  1315. it != modifiers.end(); ++it)
  1316. it->second.optimize();
  1317. }
  1318. protected:
  1319. typedef std::map<std::string, Modifier> ModList;
  1320. ModList modifiers;
  1321. };
  1322. //**********************************************************************
  1323. class FunctionModifiers : public ModifierList
  1324. {
  1325. public:
  1326. FunctionModifiers(BlockBase &block, Tokenizer &tk)
  1327. {
  1328. Token t= tk.get();
  1329. if (! t.isop('[') )
  1330. tk.unget(t);
  1331. else
  1332. parse(block, tk);
  1333. }
  1334. };
  1335. //**********************************************************************
  1336. class ArgumentModifierList : public ModifierList
  1337. {
  1338. public:
  1339. void emitmodifiers(Emit &e)
  1340. {
  1341. bool isflat = false, isnamed = false;
  1342. Expr * setname = 0;
  1343. for (ModList::iterator it = modifiers.begin(); it != modifiers.end();
  1344. ++it)
  1345. {
  1346. std::string name = it->first;
  1347. Modifier &modifier = it->second;
  1348. if (name == "flat")
  1349. isflat = true;
  1350. if (name == "named")
  1351. {
  1352. isnamed = true;
  1353. switch (modifier.numargs())
  1354. {
  1355. case 0:
  1356. break;
  1357. case 1:
  1358. setname = modifier.getarg(0);
  1359. break;
  1360. default:
  1361. throw SyntaxError("Invalid modifier", modifier.getstart());
  1362. }
  1363. }
  1364. }
  1365. if (isflat)
  1366. {
  1367. if (isnamed)
  1368. e << " :flat :named";
  1369. else
  1370. e << " :flat";
  1371. }
  1372. else if (isnamed)
  1373. {
  1374. e << " :named";
  1375. if (setname)
  1376. e << '(';
  1377. setname->emit(e, "");
  1378. e << ')';
  1379. }
  1380. }
  1381. };
  1382. class Argument
  1383. {
  1384. public:
  1385. Argument(BlockBase &block, Tokenizer &tk) :
  1386. modifiers(0)
  1387. {
  1388. expr = parseExpr(block, tk);
  1389. Token t = tk.get();
  1390. if (t.isop(':'))
  1391. {
  1392. t = tk.get();
  1393. if (! t.isop('['))
  1394. throw Expected("modifier list", t);
  1395. modifiers = new ArgumentModifierList();
  1396. modifiers->parse(block, tk);
  1397. }
  1398. else
  1399. tk.unget(t);
  1400. }
  1401. Expr *get()
  1402. {
  1403. return expr;
  1404. }
  1405. ArgumentModifierList *getmodifiers()
  1406. {
  1407. return modifiers;
  1408. }
  1409. Argument *optimize()
  1410. {
  1411. expr= expr->optimize();
  1412. return this;
  1413. }
  1414. void emit(Emit &e, const std::string &result)
  1415. {
  1416. expr->emit(e, result);
  1417. }
  1418. private:
  1419. Expr *expr;
  1420. ArgumentModifierList *modifiers;
  1421. };
  1422. class ArgumentList : public InBlock
  1423. {
  1424. public:
  1425. ArgumentList(BlockBase &block, Tokenizer &tk, char delimiter);
  1426. int numargs() const
  1427. {
  1428. return args ? args->size() : 0;
  1429. }
  1430. Expr *getfreearg(int i)
  1431. {
  1432. return args->at(i)->get();
  1433. }
  1434. void optimize();
  1435. void prepare(Emit &e);
  1436. void emit(Emit &e);
  1437. private:
  1438. std::vector <Argument *> *args;
  1439. std::vector <std::string> argregs;
  1440. };
  1441. //**********************************************************************
  1442. class ExprStatement : public BaseStatement
  1443. {
  1444. public:
  1445. ExprStatement(Block &parentblock, Tokenizer &tk);
  1446. private:
  1447. BaseStatement *optimize();
  1448. void emit (Emit &e);
  1449. Expr *expr;
  1450. };
  1451. //**********************************************************************
  1452. class CompoundStatement : public BlockStatement
  1453. {
  1454. public:
  1455. CompoundStatement(Block &parentblock, Tokenizer &tk);
  1456. BaseStatement *optimize();
  1457. void emit (Emit &e);
  1458. Token getend() const { return tend; }
  1459. private:
  1460. std::vector <BaseStatement *> subst;
  1461. Token tend;
  1462. };
  1463. //**********************************************************************
  1464. class ValueStatement : public SubStatement, public Annotated
  1465. {
  1466. public:
  1467. ValueStatement(Block & block, const Token & tstart);
  1468. protected:
  1469. void parseArray(Tokenizer &tk);
  1470. void emit (Emit &e, const std::string &name, char type);
  1471. enum ValueType { ValueSimple, ValueArray, ValueFixedArray };
  1472. ValueType vtype;
  1473. Expr *esize;
  1474. std::vector<Expr *> value;
  1475. private:
  1476. BaseStatement *optimize();
  1477. };
  1478. //**********************************************************************
  1479. class IntStatement : public ValueStatement
  1480. {
  1481. public:
  1482. IntStatement(Block & block, const Token &st, Tokenizer &tk);
  1483. void emit (Emit &e);
  1484. using ValueStatement::emit;
  1485. private:
  1486. std::string name;
  1487. };
  1488. //**********************************************************************
  1489. class StringStatement : public ValueStatement
  1490. {
  1491. public:
  1492. StringStatement(Block & block, const Token &st, Tokenizer &tk);
  1493. void emit (Emit &e);
  1494. using ValueStatement::emit;
  1495. private:
  1496. std::string name;
  1497. };
  1498. //**********************************************************************
  1499. template <class DECST>
  1500. BaseStatement *parseDeclare(Block & block, const Token &st, Tokenizer &tk)
  1501. {
  1502. BaseStatement *multi = 0;
  1503. Token t;
  1504. do {
  1505. BaseStatement *item = new DECST(block, st, tk);
  1506. multi = addtomulti(multi, item);
  1507. t= tk.get();
  1508. } while (t.isop(','));
  1509. RequireOp (';', t);
  1510. return multi;
  1511. }
  1512. //**********************************************************************
  1513. class VarStatement : public ValueStatement
  1514. {
  1515. public:
  1516. VarStatement(Block & block, const Token &st, Tokenizer &tk);
  1517. void emit (Emit &e);
  1518. private:
  1519. std::string name;
  1520. };
  1521. //**********************************************************************
  1522. class ConstStatement : public ValueStatement
  1523. {
  1524. public:
  1525. ConstStatement(Block & block, const Token &st, Tokenizer &tk, char typed);
  1526. BaseStatement *optimize();
  1527. void emit (Emit &e);
  1528. private:
  1529. char type;
  1530. std::string name;
  1531. Expr *value;
  1532. };
  1533. BaseStatement * parseConst(Block & block, const Token &st, Tokenizer &tk);
  1534. //**********************************************************************
  1535. class LabelStatement: public SubStatement
  1536. {
  1537. public:
  1538. LabelStatement(Block &block, const std::string &name);
  1539. void emit (Emit &e);
  1540. private:
  1541. std::string labelname;
  1542. std::string codename;
  1543. };
  1544. //**********************************************************************
  1545. class ReturnStatement : public SubStatement, public Annotated
  1546. {
  1547. public:
  1548. ReturnStatement(Block & block, const Token & tstart, Tokenizer &tk);
  1549. BaseStatement *optimize();
  1550. void emit (Emit &e);
  1551. private:
  1552. ArgumentList *values;
  1553. };
  1554. //**********************************************************************
  1555. class BreakStatement : public SubStatement
  1556. {
  1557. public:
  1558. BreakStatement(Block &block, Tokenizer &tk) :
  1559. SubStatement(block)
  1560. {
  1561. ExpectOp(';', tk);
  1562. }
  1563. private:
  1564. void emit (Emit &e)
  1565. {
  1566. e << INDENT "goto " << getbreaklabel() << " # break\n";
  1567. }
  1568. };
  1569. //**********************************************************************
  1570. class ContinueStatement : public SubStatement
  1571. {
  1572. public:
  1573. ContinueStatement(Block &block, Tokenizer &tk) :
  1574. SubStatement(block)
  1575. {
  1576. ExpectOp(';', tk);
  1577. }
  1578. private:
  1579. void emit (Emit &e)
  1580. {
  1581. e << INDENT "goto " << getcontinuelabel() << " # continue\n";
  1582. }
  1583. };
  1584. //**********************************************************************
  1585. class BreakableStatement : public BlockStatement
  1586. {
  1587. protected:
  1588. BreakableStatement(Block &block) :
  1589. BlockStatement(block)
  1590. { }
  1591. std::string getbreaklabel() const
  1592. {
  1593. if (breaklabel.empty())
  1594. throw InternalError("attempt to use break label before creating");
  1595. return breaklabel;
  1596. }
  1597. std::string genbreaklabel()
  1598. {
  1599. if (! breaklabel.empty())
  1600. throw InternalError("attempt to create break label twice");
  1601. breaklabel = genlabel();
  1602. return breaklabel;
  1603. }
  1604. private:
  1605. std::string breaklabel;
  1606. };
  1607. class ContinuableStatement : public BreakableStatement
  1608. {
  1609. protected:
  1610. ContinuableStatement(Block &block) :
  1611. BreakableStatement(block)
  1612. { }
  1613. std::string getcontinuelabel() const
  1614. {
  1615. if (continuelabel.empty())
  1616. throw InternalError("attempt to use continue label before creating");
  1617. return continuelabel;
  1618. }
  1619. std::string gencontinuelabel()
  1620. {
  1621. if (! continuelabel.empty())
  1622. throw InternalError("attempt to create continue label twice");
  1623. continuelabel = genlabel();
  1624. return continuelabel;
  1625. }
  1626. private:
  1627. std::string continuelabel;
  1628. };
  1629. //**********************************************************************
  1630. class SwitchBaseStatement : public BreakableStatement
  1631. {
  1632. protected:
  1633. SwitchBaseStatement(Block &block);
  1634. void parse_cases(Tokenizer &tk);
  1635. std::vector<Expr *> casevalue;
  1636. std::vector<std::vector<BaseStatement *> > casest;
  1637. std::vector<BaseStatement *> defaultst;
  1638. BaseStatement *optimize();
  1639. };
  1640. class SwitchStatement : public SwitchBaseStatement
  1641. {
  1642. public:
  1643. SwitchStatement(Block &block, Tokenizer &tk);
  1644. private:
  1645. BaseStatement *optimize();
  1646. void emit (Emit &e);
  1647. Expr *condition;
  1648. };
  1649. class SwitchCaseStatement : public SwitchBaseStatement
  1650. {
  1651. public:
  1652. SwitchCaseStatement(Block &block, Tokenizer &tk);
  1653. private:
  1654. void emit (Emit &e);
  1655. };
  1656. //**********************************************************************
  1657. class IfStatement : public BlockStatement
  1658. {
  1659. public:
  1660. IfStatement(Block &block, Tokenizer &tk);
  1661. private:
  1662. BaseStatement *optimize();
  1663. void emit (Emit &e);
  1664. Condition *condition;
  1665. BaseStatement *st;
  1666. BaseStatement *stelse;
  1667. };
  1668. //**********************************************************************
  1669. class WhileStatement : public ContinuableStatement
  1670. {
  1671. public:
  1672. WhileStatement(Block &block, Tokenizer &tk);
  1673. private:
  1674. BaseStatement *optimize();
  1675. void emit (Emit &e);
  1676. Condition *condition;
  1677. BaseStatement *st;
  1678. };
  1679. //**********************************************************************
  1680. class DoStatement : public ContinuableStatement
  1681. {
  1682. public:
  1683. DoStatement(Block &block, Tokenizer &tk);
  1684. private:
  1685. BaseStatement *optimize();
  1686. void emit (Emit &e);
  1687. Condition *condition;
  1688. BaseStatement *st;
  1689. };
  1690. //**********************************************************************
  1691. class ForeachStatement : public ContinuableStatement
  1692. {
  1693. public:
  1694. ForeachStatement(Block &block, Tokenizer &tk);
  1695. private:
  1696. BaseStatement *optimize();
  1697. void emit (Emit &e);
  1698. Token start;
  1699. std::string varname;
  1700. char vartype;
  1701. Expr * container;
  1702. BaseStatement *st;
  1703. };
  1704. //**********************************************************************
  1705. class ForStatement : public ContinuableStatement
  1706. {
  1707. public:
  1708. ForStatement(Block &block, Tokenizer &tk);
  1709. private:
  1710. BaseStatement *optimize();
  1711. void emit (Emit &e);
  1712. BaseStatement * initializer;
  1713. Expr * condition;
  1714. Expr * iteration;
  1715. BaseStatement *st;
  1716. };
  1717. //**********************************************************************
  1718. class ThrowStatement : public SubStatement
  1719. {
  1720. public:
  1721. ThrowStatement(Block &block, const Token &st, Tokenizer &tk);
  1722. private:
  1723. BaseStatement *optimize();
  1724. void emit (Emit &e);
  1725. Token pos;
  1726. Expr * excep;
  1727. };
  1728. //**********************************************************************
  1729. class TryStatement : public BlockStatement, public Annotated
  1730. {
  1731. public:
  1732. TryStatement(Block &block, const Token &st, Tokenizer &tk);
  1733. private:
  1734. BaseStatement *optimize();
  1735. void emit (Emit &e);
  1736. BaseStatement *stry;
  1737. BaseStatement *scatch;
  1738. std::string exname;
  1739. };
  1740. //**********************************************************************
  1741. class FunctionParameter
  1742. {
  1743. public:
  1744. FunctionParameter(FunctionStatement *owner, Tokenizer &tk);
  1745. char gettype() const { return type; }
  1746. std::string getname() const { return name; }
  1747. void emit (Emit &e);
  1748. private:
  1749. std::string name;
  1750. char type;
  1751. ModifierList modifiers;
  1752. bool has_modifier(const std::string &name) const
  1753. {
  1754. return modifiers.has_modifier(name);
  1755. }
  1756. };
  1757. //**********************************************************************
  1758. class FunctionStatement : protected FunctionModifiers, public FunctionBlock,
  1759. public Annotated
  1760. {
  1761. public:
  1762. FunctionStatement(Tokenizer &tk, const Token & tstart,
  1763. Block &parent,
  1764. const std::string &funcname);
  1765. virtual std::string getsubid() const;
  1766. std::string getname() const { return name; }
  1767. void optimize();
  1768. virtual void emit (Emit &e);
  1769. void local(std::string name);
  1770. bool islocal(std::st