repl.js 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108
  1. Sk.configure({
  2. output: write,
  3. read: read,
  4. systemexit: true,
  5. retainglobals: true,
  6. inputfun: readline
  7. });
  8. var compilableLines = [],
  9. //finds lines starting with "print"
  10. re = new RegExp("\\s*print"),
  11. //finds import statements
  12. importre = new RegExp("\\s*import"),
  13. //finds multuline string constants
  14. mls = new RegExp("'''"),
  15. //finds defining statements
  16. defre = new RegExp("def.*|class.*"),
  17. //test for empty line.
  18. emptyline = new RegExp("^\\s*$"),
  19. comment = new RegExp("^#.*"),
  20. //a regex to check if a line is an assignment
  21. //this regex checks whether or not a line starts with
  22. //an identifier followed with some whitspace and then an = and then some more white space.
  23. //it also checks if the identifier is a tuple.
  24. assignment = /^((\s*\(\s*(\s*((\s*((\s*[_a-zA-Z]\w*\s*)|(\s*\(\s*(\s*[_a-zA-Z]\w*\s*,)*\s*[_a-zA-Z]\w*\s*\)\s*))\s*)|(\s*\(\s*(\s*((\s*[_a-zA-Z]\w*\s*)|(\s*\(\s*(\s*[_a-zA-Z]\w*\s*,)*\s*[_a-zA-Z]\w*\s*\)\s*))\s*,)*\s*((\s*[_a-zA-Z]\w*\s*)|(\s*\(\s*(\s*[_a-zA-Z]\w*\s*,)*\s*[_a-zA-Z]\w*\s*\)\s*))\s*\)\s*))\s*,)*\s*((\s*((\s*[_a-zA-Z]\w*\s*)|(\s*\(\s*(\s*[_a-zA-Z]\w*\s*,)*\s*[_a-zA-Z]\w*\s*\)\s*))\s*)|(\s*\(\s*(\s*((\s*[_a-zA-Z]\w*\s*)|(\s*\(\s*(\s*[_a-zA-Z]\w*\s*,)*\s*[_a-zA-Z]\w*\s*\)\s*))\s*,)*\s*((\s*[_a-zA-Z]\w*\s*)|(\s*\(\s*(\s*[_a-zA-Z]\w*\s*,)*\s*[_a-zA-Z]\w*\s*\)\s*))\s*\)\s*))\s*\)\s*)|(\s*\s*(\s*((\s*((\s*[_a-zA-Z]\w*\s*)|(\s*\(\s*(\s*[_a-zA-Z]\w*\s*,)*\s*[_a-zA-Z]\w*\s*\)\s*))\s*)|(\s*\(\s*(\s*((\s*[_a-zA-Z]\w*\s*)|(\s*\(\s*(\s*[_a-zA-Z]\w*\s*,)*\s*[_a-zA-Z]\w*\s*\)\s*))\s*,)*\s*((\s*[_a-zA-Z]\w*\s*)|(\s*\(\s*(\s*[_a-zA-Z]\w*\s*,)*\s*[_a-zA-Z]\w*\s*\)\s*))\s*\)\s*))\s*,)*\s*((\s*((\s*[_a-zA-Z]\w*\s*)|(\s*\(\s*(\s*[_a-zA-Z]\w*\s*,)*\s*[_a-zA-Z]\w*\s*\)\s*))\s*)|(\s*\(\s*(\s*((\s*[_a-zA-Z]\w*\s*)|(\s*\(\s*(\s*[_a-zA-Z]\w*\s*,)*\s*[_a-zA-Z]\w*\s*\)\s*))\s*,)*\s*((\s*[_a-zA-Z]\w*\s*)|(\s*\(\s*(\s*[_a-zA-Z]\w*\s*,)*\s*[_a-zA-Z]\w*\s*\)\s*))\s*\)\s*))\s*\s*))([+-/*%&\^\|]?|[/<>*]{2})=/,
  25. lines = [];
  26. print("Python 2.6(ish) (skulpt, " + new Date() + ")");
  27. print("[v8: " + version() + "] on a system");
  28. print('Don\'t type "help", "copyright", "credits" or "license" unless you\'ve assigned something to them');
  29. function isBalanced(lines) {
  30. 'use strict';
  31. var depth = 0,
  32. mlsopened = false,
  33. l;
  34. for (l = 0; l < lines.length; l = l + 1) {
  35. if (lines[l] !== undefined) {
  36. if (lines[l].match(/'''/) !== null && lines[l].match(/'''/).length === 1) {
  37. mlsopened = !mlsopened;
  38. }
  39. if (!mlsopened && lines[l].substr(lines[l].length - 1) === ":") {
  40. depth = depth + 1;
  41. }
  42. if (!mlsopened && lines[l] === "" && depth > 0) {
  43. depth = 0;
  44. }
  45. }
  46. }
  47. return depth === 0 && !mlsopened;
  48. }
  49. //Loop
  50. while (true) {
  51. write(isBalanced(lines) ? '>>> ' : '... ');
  52. //Read
  53. lines.push(readline());
  54. //See if it is ready to be evaluated;
  55. if (!isBalanced(lines)) { continue; }
  56. //it's a onliner
  57. if (lines.length === 1) {
  58. //if it's a statement that should be printed (not containing an = or def or class or an empty line)
  59. if (!assignment.test(lines[0]) && !defre.test(lines[0]) && !importre.test(lines[0]) && !comment.test(lines[0]) && lines[0].length > 0) {
  60. //if it doesn't contain print make sure it doesn't print None
  61. if (!re.test(lines[0])) {
  62. //remove the statement
  63. //evaluate it if nessecary
  64. lines.push("evaluationresult = " + lines.pop());
  65. //print the result if not None
  66. lines.push("if not evaluationresult == None: print repr(evaluationresult)");
  67. }
  68. }
  69. }
  70. try {
  71. //Evaluate
  72. if (!lines || /^\s*$/.test(lines)) {
  73. continue
  74. }
  75. else {
  76. Sk.importMainWithBody("repl", false, lines.join('\n'));
  77. }
  78. } catch (err) {
  79. if (err instanceof Sk.builtin.SystemExit) {
  80. quit();
  81. }
  82. print(err);
  83. var index = -1;
  84. //find the line number
  85. if ((index = err.toString().indexOf("on line")) !== -1) {
  86. index = parseInt(err.toString().substr(index + 8), 10);
  87. }
  88. var line = 0;
  89. //print the accumulated code with a ">" before the broken line.
  90. //Don't add the last statement to the accumulated code
  91. print(lines.map(function (str) {
  92. return ++line + (index === line ? ">" : " ") + ": " + str;
  93. }).join('\n'));
  94. } finally {
  95. lines = [];
  96. }
  97. }