repl.js 5.1 KB

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