ast.js 76 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375
  1. //
  2. // This is pretty much a straight port of ast.c from CPython 2.6.5.
  3. //
  4. // The previous version was easier to work with and more JS-ish, but having a
  5. // somewhat different ast structure than cpython makes testing more difficult.
  6. //
  7. // This way, we can use a dump from the ast module on any arbitrary python
  8. // code and know that we're the same up to ast level, at least.
  9. //
  10. var SYM = Sk.ParseTables.sym;
  11. var TOK = Sk.Tokenizer.Tokens;
  12. var COMP_GENEXP = 0;
  13. var COMP_SETCOMP = 1;
  14. /** @constructor */
  15. function Compiling (encoding, filename, c_flags) {
  16. this.c_encoding = encoding;
  17. this.c_filename = filename;
  18. this.c_flags = c_flags || 0;
  19. }
  20. /**
  21. * @return {number}
  22. */
  23. function NCH (n) {
  24. goog.asserts.assert(n !== undefined);
  25. if (n.children === null) {
  26. return 0;
  27. }
  28. return n.children.length;
  29. }
  30. function CHILD (n, i) {
  31. goog.asserts.assert(n !== undefined);
  32. goog.asserts.assert(i !== undefined);
  33. return n.children[i];
  34. }
  35. function REQ (n, type) {
  36. goog.asserts.assert(n.type === type, "node wasn't expected type");
  37. }
  38. function strobj (s) {
  39. goog.asserts.assert(typeof s === "string", "expecting string, got " + (typeof s));
  40. return new Sk.builtin.str(s);
  41. }
  42. /** @return {number} */
  43. function numStmts (n) {
  44. var ch;
  45. var i;
  46. var cnt;
  47. switch (n.type) {
  48. case SYM.single_input:
  49. if (CHILD(n, 0).type === TOK.T_NEWLINE) {
  50. return 0;
  51. }
  52. else {
  53. return numStmts(CHILD(n, 0));
  54. }
  55. case SYM.file_input:
  56. cnt = 0;
  57. for (i = 0; i < NCH(n); ++i) {
  58. ch = CHILD(n, i);
  59. if (ch.type === SYM.stmt) {
  60. cnt += numStmts(ch);
  61. }
  62. }
  63. return cnt;
  64. case SYM.stmt:
  65. return numStmts(CHILD(n, 0));
  66. case SYM.compound_stmt:
  67. return 1;
  68. case SYM.simple_stmt:
  69. return Math.floor(NCH(n) / 2); // div 2 is to remove count of ;s
  70. case SYM.suite:
  71. if (NCH(n) === 1) {
  72. return numStmts(CHILD(n, 0));
  73. }
  74. else {
  75. cnt = 0;
  76. for (i = 2; i < NCH(n) - 1; ++i) {
  77. cnt += numStmts(CHILD(n, i));
  78. }
  79. return cnt;
  80. }
  81. break;
  82. default:
  83. goog.asserts.fail("Non-statement found");
  84. }
  85. return 0;
  86. }
  87. function forbiddenCheck (c, n, x, lineno) {
  88. if (x === "None") {
  89. throw new Sk.builtin.SyntaxError("assignment to None", c.c_filename, lineno);
  90. }
  91. if (x === "True" || x === "False") {
  92. throw new Sk.builtin.SyntaxError("assignment to True or False is forbidden", c.c_filename, lineno);
  93. }
  94. }
  95. /**
  96. * Set the context ctx for e, recursively traversing e.
  97. *
  98. * Only sets context for expr kinds that can appear in assignment context as
  99. * per the asdl file.
  100. */
  101. function setContext (c, e, ctx, n) {
  102. var i;
  103. var exprName;
  104. var s;
  105. goog.asserts.assert(ctx !== AugStore && ctx !== AugLoad);
  106. s = null;
  107. exprName = null;
  108. switch (e.constructor) {
  109. case Attribute:
  110. case Name:
  111. if (ctx === Store) {
  112. forbiddenCheck(c, n, e.attr, n.lineno);
  113. }
  114. e.ctx = ctx;
  115. break;
  116. case Subscript:
  117. e.ctx = ctx;
  118. break;
  119. case List:
  120. e.ctx = ctx;
  121. s = e.elts;
  122. break;
  123. case Tuple:
  124. if (e.elts.length === 0) {
  125. throw new Sk.builtin.SyntaxError("can't assign to ()", c.c_filename, n.lineno);
  126. }
  127. e.ctx = ctx;
  128. s = e.elts;
  129. break;
  130. case Lambda:
  131. exprName = "lambda";
  132. break;
  133. case Call:
  134. exprName = "function call";
  135. break;
  136. case BoolOp:
  137. case BinOp:
  138. case UnaryOp:
  139. exprName = "operator";
  140. break;
  141. case GeneratorExp:
  142. exprName = "generator expression";
  143. break;
  144. case Yield:
  145. exprName = "yield expression";
  146. break;
  147. case ListComp:
  148. exprName = "list comprehension";
  149. break;
  150. case SetComp:
  151. exprName = "set comprehension";
  152. break;
  153. case DictComp:
  154. exprName = "dict comprehension";
  155. break;
  156. case Dict:
  157. case Set:
  158. case Num:
  159. case Str:
  160. exprName = "literal";
  161. break;
  162. case Compare:
  163. exprName = "comparison";
  164. break;
  165. case Repr:
  166. exprName = "repr";
  167. break;
  168. case IfExp:
  169. exprName = "conditional expression";
  170. break;
  171. default:
  172. goog.asserts.fail("unhandled expression in assignment");
  173. }
  174. if (exprName) {
  175. throw new Sk.builtin.SyntaxError("can't " + (ctx === Store ? "assign to" : "delete") + " " + exprName, c.c_filename, n.lineno);
  176. }
  177. if (s) {
  178. for (i = 0; i < s.length; ++i) {
  179. setContext(c, s[i], ctx, n);
  180. }
  181. }
  182. }
  183. var operatorMap = {};
  184. (function () {
  185. operatorMap[TOK.T_VBAR] = BitOr;
  186. operatorMap[TOK.T_CIRCUMFLEX] = BitXor;
  187. operatorMap[TOK.T_AMPER] = BitAnd;
  188. operatorMap[TOK.T_LEFTSHIFT] = LShift;
  189. operatorMap[TOK.T_RIGHTSHIFT] = RShift;
  190. operatorMap[TOK.T_PLUS] = Add;
  191. operatorMap[TOK.T_MINUS] = Sub;
  192. operatorMap[TOK.T_STAR] = Mult;
  193. operatorMap[TOK.T_SLASH] = Div;
  194. operatorMap[TOK.T_DOUBLESLASH] = FloorDiv;
  195. operatorMap[TOK.T_PERCENT] = Mod;
  196. }());
  197. function getOperator (n) {
  198. goog.asserts.assert(operatorMap[n.type] !== undefined);
  199. return operatorMap[n.type];
  200. }
  201. function astForCompOp (c, n) {
  202. /* comp_op: '<'|'>'|'=='|'>='|'<='|'<>'|'!='|'in'|'not' 'in'|'is'
  203. |'is' 'not'
  204. */
  205. REQ(n, SYM.comp_op);
  206. if (NCH(n) === 1) {
  207. n = CHILD(n, 0);
  208. switch (n.type) {
  209. case TOK.T_LESS:
  210. return Lt;
  211. case TOK.T_GREATER:
  212. return Gt;
  213. case TOK.T_EQEQUAL:
  214. return Eq;
  215. case TOK.T_LESSEQUAL:
  216. return LtE;
  217. case TOK.T_GREATEREQUAL:
  218. return GtE;
  219. case TOK.T_NOTEQUAL:
  220. return NotEq;
  221. case TOK.T_NAME:
  222. if (n.value === "in") {
  223. return In_;
  224. }
  225. if (n.value === "is") {
  226. return Is;
  227. }
  228. }
  229. }
  230. else if (NCH(n) === 2) {
  231. if (CHILD(n, 0).type === TOK.T_NAME) {
  232. if (CHILD(n, 1).value === "in") {
  233. return NotIn;
  234. }
  235. if (CHILD(n, 0).value === "is") {
  236. return IsNot;
  237. }
  238. }
  239. }
  240. goog.asserts.fail("invalid comp_op");
  241. }
  242. function seqForTestlist (c, n) {
  243. /* testlist: test (',' test)* [','] */
  244. var i;
  245. var seq = [];
  246. goog.asserts.assert(n.type === SYM.testlist ||
  247. n.type === SYM.listmaker ||
  248. n.type === SYM.testlist_comp ||
  249. n.type === SYM.testlist_safe ||
  250. n.type === SYM.testlist1);
  251. for (i = 0; i < NCH(n); i += 2) {
  252. goog.asserts.assert(CHILD(n, i).type === SYM.test || CHILD(n, i).type === SYM.old_test);
  253. seq[i / 2] = astForExpr(c, CHILD(n, i));
  254. }
  255. return seq;
  256. }
  257. function astForSuite (c, n) {
  258. /* suite: simple_stmt | NEWLINE INDENT stmt+ DEDENT */
  259. var j;
  260. var num;
  261. var i;
  262. var end;
  263. var ch;
  264. var pos;
  265. var seq;
  266. REQ(n, SYM.suite);
  267. seq = [];
  268. pos = 0;
  269. if (CHILD(n, 0).type === SYM.simple_stmt) {
  270. n = CHILD(n, 0);
  271. /* simple_stmt always ends with an NEWLINE and may have a trailing
  272. * SEMI. */
  273. end = NCH(n) - 1;
  274. if (CHILD(n, end - 1).type === TOK.T_SEMI) {
  275. end -= 1;
  276. }
  277. for (i = 0; i < end; i += 2) // by 2 to skip ;
  278. {
  279. seq[pos++] = astForStmt(c, CHILD(n, i));
  280. }
  281. }
  282. else {
  283. for (i = 2; i < NCH(n) - 1; ++i) {
  284. ch = CHILD(n, i);
  285. REQ(ch, SYM.stmt);
  286. num = numStmts(ch);
  287. if (num === 1) {
  288. // small_stmt or compound_stmt w/ only 1 child
  289. seq[pos++] = astForStmt(c, ch);
  290. }
  291. else {
  292. ch = CHILD(ch, 0);
  293. REQ(ch, SYM.simple_stmt);
  294. for (j = 0; j < NCH(ch); j += 2) {
  295. if (NCH(CHILD(ch, j)) === 0) {
  296. goog.asserts.assert(j + 1 === NCH(ch));
  297. break;
  298. }
  299. seq[pos++] = astForStmt(c, CHILD(ch, j));
  300. }
  301. }
  302. }
  303. }
  304. goog.asserts.assert(pos === numStmts(n));
  305. return seq;
  306. }
  307. function astForExceptClause (c, exc, body) {
  308. /* except_clause: 'except' [test [(',' | 'as') test]] */
  309. var e;
  310. REQ(exc, SYM.except_clause);
  311. REQ(body, SYM.suite);
  312. if (NCH(exc) === 1) {
  313. return new ExceptHandler(null, null, astForSuite(c, body), exc.lineno, exc.col_offset, exc.endlineno, exc.col_endoffset);
  314. }
  315. else if (NCH(exc) === 2) {
  316. return new ExceptHandler(astForExpr(c, CHILD(exc, 1)), null, astForSuite(c, body), exc.lineno, exc.col_offset, exc.endlineno, exc.col_endoffset);
  317. }
  318. else if (NCH(exc) === 4) {
  319. e = astForExpr(c, CHILD(exc, 3));
  320. setContext(c, e, Store, CHILD(exc, 3));
  321. return new ExceptHandler(astForExpr(c, CHILD(exc, 1)), e, astForSuite(c, body), exc.lineno, exc.col_offset, exc.endlineno, exc.col_endoffset);
  322. }
  323. goog.asserts.fail("wrong number of children for except clause");
  324. }
  325. function astForTryStmt (c, n) {
  326. var exceptSt;
  327. var i;
  328. var handlers;
  329. var nc = NCH(n);
  330. var nexcept = (nc - 3) / 3;
  331. var body, orelse = [],
  332. finally_ = null;
  333. REQ(n, SYM.try_stmt);
  334. body = astForSuite(c, CHILD(n, 2));
  335. if (CHILD(n, nc - 3).type === TOK.T_NAME) {
  336. if (CHILD(n, nc - 3).value === "finally") {
  337. if (nc >= 9 && CHILD(n, nc - 6).type === TOK.T_NAME) {
  338. /* we can assume it's an "else",
  339. because nc >= 9 for try-else-finally and
  340. it would otherwise have a type of except_clause */
  341. orelse = astForSuite(c, CHILD(n, nc - 4));
  342. nexcept--;
  343. }
  344. finally_ = astForSuite(c, CHILD(n, nc - 1));
  345. nexcept--;
  346. }
  347. else {
  348. /* we can assume it's an "else",
  349. otherwise it would have a type of except_clause */
  350. orelse = astForSuite(c, CHILD(n, nc - 1));
  351. nexcept--;
  352. }
  353. }
  354. else if (CHILD(n, nc - 3).type !== SYM.except_clause) {
  355. throw new Sk.builtin.SyntaxError("malformed 'try' statement", c.c_filename, n.lineno);
  356. }
  357. if (nexcept > 0) {
  358. handlers = [];
  359. for (i = 0; i < nexcept; ++i) {
  360. handlers[i] = astForExceptClause(c, CHILD(n, 3 + i * 3), CHILD(n, 5 + i * 3));
  361. }
  362. exceptSt = new TryExcept(body, handlers, orelse, n.lineno, n.col_offset, n.endlineno, n.col_endoffset);
  363. if (!finally_) {
  364. return exceptSt;
  365. }
  366. /* if a 'finally' is present too, we nest the TryExcept within a
  367. TryFinally to emulate try ... except ... finally */
  368. body = [exceptSt];
  369. }
  370. goog.asserts.assert(finally_ !== null);
  371. return new TryFinally(body, finally_, n.lineno, n.col_offset, n.endlineno, n.col_endoffset);
  372. }
  373. function astForDottedName (c, n) {
  374. var i;
  375. var e;
  376. var id;
  377. var col_offset;
  378. var lineno;
  379. REQ(n, SYM.dotted_name);
  380. lineno = n.lineno;
  381. col_offset = n.col_offset;
  382. id = strobj(CHILD(n, 0).value);
  383. e = new Name(id, Load, lineno, col_offset, n.endlineno, n.col_endoffset);
  384. for (i = 2; i < NCH(n); i += 2) {
  385. id = strobj(CHILD(n, i).value);
  386. e = new Attribute(e, id, Load, lineno, col_offset, n.endlineno, n.col_endoffset);
  387. }
  388. return e;
  389. }
  390. function astForDecorator (c, n) {
  391. /* decorator: '@' dotted_name [ '(' [arglist] ')' ] NEWLINE */
  392. var nameExpr;
  393. REQ(n, SYM.decorator);
  394. REQ(CHILD(n, 0), TOK.T_AT);
  395. REQ(CHILD(n, NCH(n) - 1), TOK.T_NEWLINE);
  396. nameExpr = astForDottedName(c, CHILD(n, 1));
  397. if (NCH(n) === 3) // no args
  398. {
  399. return nameExpr;
  400. }
  401. else if (NCH(n) === 5) // call with no args
  402. {
  403. return new Call(nameExpr, [], [], null, null, n.lineno, n.col_offset, n.endlineno, n.col_endoffset);
  404. }
  405. else {
  406. return astForCall(c, CHILD(n, 3), nameExpr);
  407. }
  408. }
  409. function astForDecorators (c, n) {
  410. var i;
  411. var decoratorSeq;
  412. REQ(n, SYM.decorators);
  413. decoratorSeq = [];
  414. for (i = 0; i < NCH(n); ++i) {
  415. decoratorSeq[i] = astForDecorator(c, CHILD(n, i));
  416. }
  417. return decoratorSeq;
  418. }
  419. function astForDecorated (c, n) {
  420. var thing;
  421. var decoratorSeq;
  422. REQ(n, SYM.decorated);
  423. decoratorSeq = astForDecorators(c, CHILD(n, 0));
  424. goog.asserts.assert(CHILD(n, 1).type === SYM.funcdef || CHILD(n, 1).type === SYM.classdef);
  425. thing = null;
  426. if (CHILD(n, 1).type === SYM.funcdef) {
  427. thing = astForFuncdef(c, CHILD(n, 1), decoratorSeq);
  428. }
  429. else if (CHILD(n, 1) === SYM.classdef) {
  430. thing = astForClassdef(c, CHILD(n, 1), decoratorSeq);
  431. }
  432. if (thing) {
  433. thing.lineno = n.lineno;
  434. thing.col_offset = n.col_offset;
  435. thing.endlineno = n.endlineno;
  436. thing.col_endoffset = n.col_endoffset
  437. }
  438. return thing;
  439. }
  440. /* with_item: test ['as' expr] */
  441. function astForWithItem (c, n, content) {
  442. var expr_ty, context_expr, optional_vars;
  443. REQ(n, SYM.with_item);
  444. context_expr = astForExpr(c, CHILD(n, 0));
  445. if (NCH(n) == 3) {
  446. optional_vars = astForExpr(c, CHILD(n, 2));
  447. setContext(c, optional_vars, Store, n);
  448. }
  449. return new With_(context_expr, optional_vars, content, n.lineno, n.col_offset, n.endlineno, n.col_endoffset);
  450. }
  451. function astForWithStmt (c, n) {
  452. /* with_stmt: 'with' with_item (',' with_item)* ':' suite */
  453. var i;
  454. var ret
  455. var inner;
  456. REQ(n, SYM.with_stmt)
  457. /* process the with items inside-out */
  458. i = NCH(n) -1
  459. /* the suite of the innermost with item is the suite of the with stmt */
  460. inner = astForSuite(c, CHILD(n,i));
  461. while (true) {
  462. i-=2;
  463. ret = astForWithItem(c, CHILD(n, i), inner)
  464. /* was this the last item? */
  465. if (i == 1) {
  466. break;
  467. }
  468. inner = [ret];
  469. }
  470. return ret
  471. }
  472. function astForExecStmt (c, n) {
  473. var expr1, globals = null, locals = null;
  474. var nchildren = NCH(n);
  475. goog.asserts.assert(nchildren === 2 || nchildren === 4 || nchildren === 6);
  476. /* exec_stmt: 'exec' expr ['in' test [',' test]] */
  477. REQ(n, SYM.exec_stmt);
  478. expr1 = astForExpr(c, CHILD(n, 1));
  479. if (nchildren >= 4) {
  480. globals = astForExpr(c, CHILD(n, 3));
  481. }
  482. if (nchildren === 6) {
  483. locals = astForExpr(c, CHILD(n, 5));
  484. }
  485. return new Exec(expr1, globals, locals, n.lineno, n.col_offset, n.endlineno, n.col_endoffset);
  486. }
  487. function astForIfStmt (c, n) {
  488. /* if_stmt: 'if' test ':' suite ('elif' test ':' suite)*
  489. ['else' ':' suite]
  490. */
  491. var off;
  492. var i;
  493. var orelse;
  494. var hasElse;
  495. var nElif;
  496. var decider;
  497. var s;
  498. REQ(n, SYM.if_stmt);
  499. if (NCH(n) === 4) {
  500. return new If_(
  501. astForExpr(c, CHILD(n, 1)),
  502. astForSuite(c, CHILD(n, 3)),
  503. [], n.lineno, n.col_offset, n.endlineno, n.col_endoffset);
  504. }
  505. s = CHILD(n, 4).value;
  506. decider = s.charAt(2); // elSe or elIf
  507. if (decider === "s") {
  508. return new If_(
  509. astForExpr(c, CHILD(n, 1)),
  510. astForSuite(c, CHILD(n, 3)),
  511. astForSuite(c, CHILD(n, 6)),
  512. n.lineno, n.col_offset, n.endlineno, n.col_endoffset);
  513. }
  514. else if (decider === "i") {
  515. nElif = NCH(n) - 4;
  516. hasElse = false;
  517. orelse = [];
  518. /* must reference the child nElif+1 since 'else' token is third, not
  519. * fourth child from the end. */
  520. if (CHILD(n, nElif + 1).type === TOK.T_NAME &&
  521. CHILD(n, nElif + 1).value.charAt(2) === "s") {
  522. hasElse = true;
  523. nElif -= 3;
  524. }
  525. nElif /= 4;
  526. if (hasElse) {
  527. orelse = [
  528. new If_(
  529. astForExpr(c, CHILD(n, NCH(n) - 6)),
  530. astForSuite(c, CHILD(n, NCH(n) - 4)),
  531. astForSuite(c, CHILD(n, NCH(n) - 1)),
  532. CHILD(n, NCH(n) - 6).lineno,
  533. CHILD(n, NCH(n) - 6).col_offset,
  534. CHILD(n, NCH(n) - 6).endlineno,
  535. CHILD(n, NCH(n) - 6).col_endoffset)];
  536. nElif--;
  537. }
  538. for (i = 0; i < nElif; ++i) {
  539. off = 5 + (nElif - i - 1) * 4;
  540. orelse = [
  541. new If_(
  542. astForExpr(c, CHILD(n, off)),
  543. astForSuite(c, CHILD(n, off + 2)),
  544. orelse,
  545. CHILD(n, off).lineno,
  546. CHILD(n, off).col_offset,
  547. CHILD(n, NCH(n) - 6).endlineno,
  548. CHILD(n, NCH(n) - 6).col_endoffset)];
  549. }
  550. return new If_(
  551. astForExpr(c, CHILD(n, 1)),
  552. astForSuite(c, CHILD(n, 3)),
  553. orelse, n.lineno, n.col_offset, n.endlineno, n.col_endoffset);
  554. }
  555. goog.asserts.fail("unexpected token in 'if' statement");
  556. }
  557. function astForExprlist (c, n, context) {
  558. var e;
  559. var i;
  560. var seq;
  561. REQ(n, SYM.exprlist);
  562. seq = [];
  563. for (i = 0; i < NCH(n); i += 2) {
  564. e = astForExpr(c, CHILD(n, i));
  565. seq[i / 2] = e;
  566. if (context) {
  567. setContext(c, e, context, CHILD(n, i));
  568. }
  569. }
  570. return seq;
  571. }
  572. function astForDelStmt (c, n) {
  573. /* del_stmt: 'del' exprlist */
  574. REQ(n, SYM.del_stmt);
  575. return new Delete_(astForExprlist(c, CHILD(n, 1), Del), n.lineno, n.col_offset, n.endlineno, n.col_endoffset);
  576. }
  577. function astForGlobalStmt (c, n) {
  578. /* global_stmt: 'global' NAME (',' NAME)* */
  579. var i;
  580. var s = [];
  581. REQ(n, SYM.global_stmt);
  582. for (i = 1; i < NCH(n); i += 2) {
  583. s[(i - 1) / 2] = strobj(CHILD(n, i).value);
  584. }
  585. return new Global(s, n.lineno, n.col_offset, n.endlineno, n.col_endoffset);
  586. }
  587. function astForAssertStmt (c, n) {
  588. /* assert_stmt: 'assert' test [',' test] */
  589. REQ(n, SYM.assert_stmt);
  590. if (NCH(n) === 2) {
  591. return new Assert(astForExpr(c, CHILD(n, 1)), null, n.lineno, n.col_offset, n.endlineno, n.col_endoffset);
  592. }
  593. else if (NCH(n) === 4) {
  594. return new Assert(astForExpr(c, CHILD(n, 1)), astForExpr(c, CHILD(n, 3)), n.lineno, n.col_offset, n.endlineno, n.col_endoffset);
  595. }
  596. goog.asserts.fail("improper number of parts to assert stmt");
  597. }
  598. function aliasForImportName (c, n) {
  599. /*
  600. import_as_name: NAME ['as' NAME]
  601. dotted_as_name: dotted_name ['as' NAME]
  602. dotted_name: NAME ('.' NAME)*
  603. */
  604. var i;
  605. var a;
  606. var name;
  607. var str;
  608. loop: while (true) {
  609. switch (n.type) {
  610. case SYM.import_as_name:
  611. str = null;
  612. name = strobj(CHILD(n, 0).value);
  613. if (NCH(n) === 3) {
  614. str = CHILD(n, 2).value;
  615. }
  616. return new alias(name, str == null ? null : strobj(str));
  617. case SYM.dotted_as_name:
  618. if (NCH(n) === 1) {
  619. n = CHILD(n, 0);
  620. continue loop;
  621. }
  622. else {
  623. a = aliasForImportName(c, CHILD(n, 0));
  624. goog.asserts.assert(!a.asname);
  625. a.asname = strobj(CHILD(n, 2).value);
  626. return a;
  627. }
  628. break;
  629. case SYM.dotted_name:
  630. if (NCH(n) === 1) {
  631. return new alias(strobj(CHILD(n, 0).value), null);
  632. }
  633. else {
  634. // create a string of the form a.b.c
  635. str = "";
  636. for (i = 0; i < NCH(n); i += 2) {
  637. str += CHILD(n, i).value + ".";
  638. }
  639. return new alias(strobj(str.substr(0, str.length - 1)), null);
  640. }
  641. break;
  642. case TOK.T_STAR:
  643. return new alias(strobj("*"), null);
  644. default:
  645. throw new Sk.builtin.SyntaxError("unexpected import name", c.c_filename, n.lineno);
  646. }
  647. break;
  648. }
  649. }
  650. function astForImportStmt (c, n) {
  651. /*
  652. import_stmt: import_name | import_from
  653. import_name: 'import' dotted_as_names
  654. import_from: 'from' ('.'* dotted_name | '.') 'import'
  655. ('*' | '(' import_as_names ')' | import_as_names)
  656. */
  657. var modname;
  658. var idx;
  659. var nchildren;
  660. var ndots;
  661. var mod;
  662. var i;
  663. var aliases;
  664. var col_offset;
  665. var lineno;
  666. REQ(n, SYM.import_stmt);
  667. lineno = n.lineno;
  668. col_offset = n.col_offset;
  669. var endlineno = n.endlineno;
  670. var col_endoffset = n.col_endoffset;
  671. n = CHILD(n, 0);
  672. if (n.type === SYM.import_name) {
  673. n = CHILD(n, 1);
  674. REQ(n, SYM.dotted_as_names);
  675. aliases = [];
  676. for (i = 0; i < NCH(n); i += 2) {
  677. aliases[i / 2] = aliasForImportName(c, CHILD(n, i));
  678. }
  679. return new Import_(aliases, lineno, col_offset, endlineno, col_endoffset);
  680. }
  681. else if (n.type === SYM.import_from) {
  682. mod = null;
  683. ndots = 0;
  684. for (idx = 1; idx < NCH(n); ++idx) {
  685. if (CHILD(n, idx).type === SYM.dotted_name) {
  686. mod = aliasForImportName(c, CHILD(n, idx));
  687. idx++;
  688. break;
  689. }
  690. else if (CHILD(n, idx).type !== TOK.T_DOT) {
  691. break;
  692. }
  693. ndots++;
  694. }
  695. ++idx; // skip the import keyword
  696. switch (CHILD(n, idx).type) {
  697. case TOK.T_STAR:
  698. // from ... import
  699. n = CHILD(n, idx);
  700. nchildren = 1;
  701. break;
  702. case TOK.T_LPAR:
  703. // from ... import (x, y, z)
  704. n = CHILD(n, idx + 1);
  705. nchildren = NCH(n);
  706. break;
  707. case SYM.import_as_names:
  708. // from ... import x, y, z
  709. n = CHILD(n, idx);
  710. nchildren = NCH(n);
  711. if (nchildren % 2 === 0) {
  712. throw new Sk.builtin.SyntaxError("trailing comma not allowed without surrounding parentheses", c.c_filename, n.lineno);
  713. }
  714. break;
  715. default:
  716. throw new Sk.builtin.SyntaxError("Unexpected node-type in from-import", c.c_filename, n.lineno);
  717. }
  718. aliases = [];
  719. if (n.type === TOK.T_STAR) {
  720. aliases[0] = aliasForImportName(c, n);
  721. }
  722. else {
  723. for (i = 0; i < NCH(n); i += 2) {
  724. aliases[i / 2] = aliasForImportName(c, CHILD(n, i));
  725. }
  726. }
  727. modname = mod ? mod.name.v : "";
  728. return new ImportFrom(strobj(modname), aliases, ndots, lineno, col_offset, endlineno, col_endoffset);
  729. }
  730. throw new Sk.builtin.SyntaxError("unknown import statement", c.c_filename, n.lineno);
  731. }
  732. function astForTestlistComp(c, n) {
  733. /* testlist_comp: test ( comp_for | (',' test)* [','] ) */
  734. /* argument: test [comp_for] */
  735. goog.asserts.assert(n.type === SYM.testlist_comp || n.type === SYM.argument);
  736. if (NCH(n) > 1 && CHILD(n, 1).type === SYM.comp_for) {
  737. return astForGenExpr(c, n);
  738. }
  739. return astForTestlist(c, n);
  740. }
  741. function astForListcomp (c, n) {
  742. /* listmaker: test ( list_for | (',' test)* [','] )
  743. list_for: 'for' exprlist 'in' testlist_safe [list_iter]
  744. list_iter: list_for | list_if
  745. list_if: 'if' test [list_iter]
  746. testlist_safe: test [(',' test)+ [',']]
  747. */
  748. function countListFors (c, n) {
  749. var nfors = 0;
  750. var ch = CHILD(n, 1);
  751. count_list_for: while (true) {
  752. nfors++;
  753. REQ(ch, SYM.list_for);
  754. if (NCH(ch) === 5) {
  755. ch = CHILD(ch, 4);
  756. }
  757. else {
  758. return nfors;
  759. }
  760. count_list_iter: while (true) {
  761. REQ(ch, SYM.list_iter);
  762. ch = CHILD(ch, 0);
  763. if (ch.type === SYM.list_for) {
  764. continue count_list_for;
  765. }
  766. else if (ch.type === SYM.list_if) {
  767. if (NCH(ch) === 3) {
  768. ch = CHILD(ch, 2);
  769. continue count_list_iter;
  770. }
  771. else {
  772. return nfors;
  773. }
  774. }
  775. break;
  776. }
  777. break;
  778. }
  779. }
  780. function countListIfs (c, n) {
  781. var nifs = 0;
  782. while (true) {
  783. REQ(n, SYM.list_iter);
  784. if (CHILD(n, 0).type === SYM.list_for) {
  785. return nifs;
  786. }
  787. n = CHILD(n, 0);
  788. REQ(n, SYM.list_if);
  789. nifs++;
  790. if (NCH(n) == 2) {
  791. return nifs;
  792. }
  793. n = CHILD(n, 2);
  794. }
  795. }
  796. var j;
  797. var ifs;
  798. var nifs;
  799. var lc;
  800. var expression;
  801. var t;
  802. var forch;
  803. var i;
  804. var ch;
  805. var listcomps;
  806. var nfors;
  807. var elt;
  808. REQ(n, SYM.listmaker);
  809. goog.asserts.assert(NCH(n) > 1);
  810. elt = astForExpr(c, CHILD(n, 0));
  811. nfors = countListFors(c, n);
  812. listcomps = [];
  813. ch = CHILD(n, 1);
  814. for (i = 0; i < nfors; ++i) {
  815. REQ(ch, SYM.list_for);
  816. forch = CHILD(ch, 1);
  817. t = astForExprlist(c, forch, Store);
  818. expression = astForTestlist(c, CHILD(ch, 3));
  819. if (NCH(forch) === 1) {
  820. lc = new comprehension(t[0], expression, []);
  821. }
  822. else {
  823. lc = new comprehension(new Tuple(t, Store, ch.lineno, ch.col_offset, ch.endlineno, ch.col_endoffset), expression, []);
  824. }
  825. if (NCH(ch) === 5) {
  826. ch = CHILD(ch, 4);
  827. nifs = countListIfs(c, ch);
  828. ifs = [];
  829. for (j = 0; j < nifs; ++j) {
  830. REQ(ch, SYM.list_iter);
  831. ch = CHILD(ch, 0);
  832. REQ(ch, SYM.list_if);
  833. ifs[j] = astForExpr(c, CHILD(ch, 1));
  834. if (NCH(ch) === 3) {
  835. ch = CHILD(ch, 2);
  836. }
  837. }
  838. if (ch.type === SYM.list_iter) {
  839. ch = CHILD(ch, 0);
  840. }
  841. lc.ifs = ifs;
  842. }
  843. listcomps[i] = lc;
  844. }
  845. return new ListComp(elt, listcomps, n.lineno, n.col_offset, n.endlineno, n.col_endoffset);
  846. }
  847. function astForFactor (c, n) {
  848. /* some random peephole thing that cpy does */
  849. var expression;
  850. var pnum;
  851. var patom;
  852. var ppower;
  853. var pfactor;
  854. if (CHILD(n, 0).type === TOK.T_MINUS && NCH(n) === 2) {
  855. pfactor = CHILD(n, 1);
  856. if (pfactor.type === SYM.factor && NCH(pfactor) === 1) {
  857. ppower = CHILD(pfactor, 0);
  858. if (ppower.type === SYM.power && NCH(ppower) === 1) {
  859. patom = CHILD(ppower, 0);
  860. if (patom.type === SYM.atom) {
  861. pnum = CHILD(patom, 0);
  862. if (pnum.type === TOK.T_NUMBER) {
  863. pnum.value = "-" + pnum.value;
  864. return astForAtom(c, patom);
  865. }
  866. }
  867. }
  868. }
  869. }
  870. expression = astForExpr(c, CHILD(n, 1));
  871. switch (CHILD(n, 0).type) {
  872. case TOK.T_PLUS:
  873. return new UnaryOp(UAdd, expression, n.lineno, n.col_offset, n.endlineno, n.col_endoffset);
  874. case TOK.T_MINUS:
  875. return new UnaryOp(USub, expression, n.lineno, n.col_offset, n.endlineno, n.col_endoffset);
  876. case TOK.T_TILDE:
  877. return new UnaryOp(Invert, expression, n.lineno, n.col_offset, n.endlineno, n.col_endoffset);
  878. }
  879. goog.asserts.fail("unhandled factor");
  880. }
  881. function astForForStmt (c, n) {
  882. /* for_stmt: 'for' exprlist 'in' testlist ':' suite ['else' ':' suite] */
  883. var target;
  884. var _target;
  885. var nodeTarget;
  886. var seq = [];
  887. REQ(n, SYM.for_stmt);
  888. if (NCH(n) === 9) {
  889. seq = astForSuite(c, CHILD(n, 8));
  890. }
  891. nodeTarget = CHILD(n, 1);
  892. _target = astForExprlist(c, nodeTarget, Store);
  893. if (NCH(nodeTarget) === 1) {
  894. target = _target[0];
  895. }
  896. else {
  897. target = new Tuple(_target, Store, n.lineno, n.col_offset, n.endlineno, n.col_endoffset);
  898. }
  899. return new For_(target,
  900. astForTestlist(c, CHILD(n, 3)),
  901. astForSuite(c, CHILD(n, 5)),
  902. seq, n.lineno, n.col_offset, n.endlineno, n.col_endoffset);
  903. }
  904. function astForCall (c, n, func) {
  905. /*
  906. arglist: (argument ',')* (argument [',']| '*' test [',' '**' test]
  907. | '**' test)
  908. argument: test [comp_for] | test '=' test # Really [keyword '='] test
  909. */
  910. var tmp;
  911. var k;
  912. var key;
  913. var e;
  914. var kwarg;
  915. var vararg;
  916. var keywords;
  917. var args;
  918. var ch;
  919. var i;
  920. var ngens;
  921. var nkeywords;
  922. var nargs;
  923. REQ(n, SYM.arglist);
  924. nargs = 0;
  925. nkeywords = 0;
  926. ngens = 0;
  927. for (i = 0; i < NCH(n); i++) {
  928. ch = CHILD(n, i);
  929. if (ch.type === SYM.argument) {
  930. if (NCH(ch) === 1) {
  931. nargs++;
  932. }
  933. else if (CHILD(ch, 1).type === SYM.comp_for) {
  934. ngens++;
  935. }
  936. else {
  937. nkeywords++;
  938. }
  939. }
  940. }
  941. if (ngens > 1 || (ngens && (nargs || nkeywords))) {
  942. throw new Sk.builtin.SyntaxError("Generator expression must be parenthesized if not sole argument", c.c_filename, n.lineno);
  943. }
  944. if (nargs + nkeywords + ngens > 255) {
  945. throw new Sk.builtin.SyntaxError("more than 255 arguments", c.c_filename, n.lineno);
  946. }
  947. args = [];
  948. keywords = [];
  949. nargs = 0;
  950. nkeywords = 0;
  951. vararg = null;
  952. kwarg = null;
  953. for (i = 0; i < NCH(n); i++) {
  954. ch = CHILD(n, i);
  955. if (ch.type === SYM.argument) {
  956. if (NCH(ch) === 1) {
  957. if (nkeywords) {
  958. throw new Sk.builtin.SyntaxError("non-keyword arg after keyword arg", c.c_filename, n.lineno);
  959. }
  960. if (vararg) {
  961. throw new Sk.builtin.SyntaxError("only named arguments may follow *expression", c.c_filename, n.lineno);
  962. }
  963. args[nargs++] = astForExpr(c, CHILD(ch, 0));
  964. }
  965. else if (CHILD(ch, 1).type === SYM.comp_for) {
  966. args[nargs++] = astForGenExpr(c, ch);
  967. }
  968. else {
  969. e = astForExpr(c, CHILD(ch, 0));
  970. if (e.constructor === Lambda) {
  971. throw new Sk.builtin.SyntaxError("lambda cannot contain assignment", c.c_filename, n.lineno);
  972. }
  973. else if (e.constructor !== Name) {
  974. throw new Sk.builtin.SyntaxError("keyword can't be an expression", c.c_filename, n.lineno);
  975. }
  976. key = e.id;
  977. forbiddenCheck(c, CHILD(ch, 0), key, n.lineno);
  978. for (k = 0; k < nkeywords; ++k) {
  979. tmp = keywords[k].arg;
  980. if (tmp === key) {
  981. throw new Sk.builtin.SyntaxError("keyword argument repeated", c.c_filename, n.lineno);
  982. }
  983. }
  984. keywords[nkeywords++] = new keyword(key, astForExpr(c, CHILD(ch, 2)));
  985. }
  986. }
  987. else if (ch.type === TOK.T_STAR) {
  988. vararg = astForExpr(c, CHILD(n, ++i));
  989. }
  990. else if (ch.type === TOK.T_DOUBLESTAR) {
  991. kwarg = astForExpr(c, CHILD(n, ++i));
  992. }
  993. }
  994. return new Call(func, args, keywords, vararg, kwarg, func.lineno, func.col_offset, func.endlineno, func.col_endoffset);
  995. }
  996. function astForTrailer (c, n, leftExpr) {
  997. /* trailer: '(' [arglist] ')' | '[' subscriptlist ']' | '.' NAME
  998. subscriptlist: subscript (',' subscript)* [',']
  999. subscript: '.' '.' '.' | test | [test] ':' [test] [sliceop]
  1000. */
  1001. var e;
  1002. var elts;
  1003. var slc;
  1004. var j;
  1005. var slices;
  1006. var simple;
  1007. REQ(n, SYM.trailer);
  1008. if (CHILD(n, 0).type === TOK.T_LPAR) {
  1009. if (NCH(n) === 2) {
  1010. return new Call(leftExpr, [], [], null, null, n.lineno, n.col_offset, n.endlineno, n.col_endoffset);
  1011. }
  1012. else {
  1013. return astForCall(c, CHILD(n, 1), leftExpr);
  1014. }
  1015. }
  1016. else if (CHILD(n, 0).type === TOK.T_DOT) {
  1017. return new Attribute(leftExpr, strobj(CHILD(n, 1).value), Load, n.lineno, n.col_offset, n.endlineno, n.col_endoffset);
  1018. }
  1019. else {
  1020. REQ(CHILD(n, 0), TOK.T_LSQB);
  1021. REQ(CHILD(n, 2), TOK.T_RSQB);
  1022. n = CHILD(n, 1);
  1023. if (NCH(n) === 1) {
  1024. return new Subscript(leftExpr, astForSlice(c, CHILD(n, 0)), Load, n.lineno, n.col_offset, n.endlineno, n.col_endoffset);
  1025. }
  1026. else {
  1027. /* The grammar is ambiguous here. The ambiguity is resolved
  1028. by treating the sequence as a tuple literal if there are
  1029. no slice features.
  1030. */
  1031. simple = true;
  1032. slices = [];
  1033. for (j = 0; j < NCH(n); j += 2) {
  1034. slc = astForSlice(c, CHILD(n, j));
  1035. if (slc.constructor !== Index) {
  1036. simple = false;
  1037. }
  1038. slices[j / 2] = slc;
  1039. }
  1040. if (!simple) {
  1041. return new Subscript(leftExpr, new ExtSlice(slices), Load, n.lineno, n.col_offset, n.endlineno, n.col_endoffset);
  1042. }
  1043. elts = [];
  1044. for (j = 0; j < slices.length; ++j) {
  1045. slc = slices[j];
  1046. goog.asserts.assert(slc.constructor === Index && slc.value !== null && slc.value !== undefined);
  1047. elts[j] = slc.value;
  1048. }
  1049. e = new Tuple(elts, Load, n.lineno, n.col_offset, n.endlineno, n.col_endoffset);
  1050. return new Subscript(leftExpr, new Index(e), Load, n.lineno, n.col_offset, n.endlineno, n.col_endoffset);
  1051. }
  1052. }
  1053. }
  1054. function astForFlowStmt (c, n) {
  1055. /*
  1056. flow_stmt: break_stmt | continue_stmt | return_stmt | raise_stmt
  1057. | yield_stmt
  1058. break_stmt: 'break'
  1059. continue_stmt: 'continue'
  1060. return_stmt: 'return' [testlist]
  1061. yield_stmt: yield_expr
  1062. yield_expr: 'yield' testlist
  1063. raise_stmt: 'raise' [test [',' test [',' test]]]
  1064. */
  1065. var ch;
  1066. REQ(n, SYM.flow_stmt);
  1067. ch = CHILD(n, 0);
  1068. switch (ch.type) {
  1069. case SYM.break_stmt:
  1070. return new Break_(n.lineno, n.col_offset, n.endlineno, n.col_endoffset);
  1071. case SYM.continue_stmt:
  1072. return new Continue_(n.lineno, n.col_offset, n.endlineno, n.col_endoffset);
  1073. case SYM.yield_stmt:
  1074. return new Expr(astForExpr(c, CHILD(ch, 0)), n.lineno, n.col_offset, n.endlineno, n.col_endoffset);
  1075. case SYM.return_stmt:
  1076. if (NCH(ch) === 1) {
  1077. return new Return_(null, n.lineno, n.col_offset, n.endlineno, n.col_endoffset);
  1078. }
  1079. else {
  1080. return new Return_(astForTestlist(c, CHILD(ch, 1)), n.lineno, n.col_offset, n.endlineno, n.col_endoffset);
  1081. }
  1082. break;
  1083. case SYM.raise_stmt:
  1084. if (NCH(ch) === 1) {
  1085. return new Raise(null, null, null, n.lineno, n.col_offset, n.endlineno, n.col_endoffset);
  1086. }
  1087. else if (NCH(ch) === 2) {
  1088. return new Raise(astForExpr(c, CHILD(ch, 1)), null, null, n.lineno, n.col_offset, n.endlineno, n.col_endoffset);
  1089. }
  1090. else if (NCH(ch) === 4) {
  1091. return new Raise(
  1092. astForExpr(c, CHILD(ch, 1)),
  1093. astForExpr(c, CHILD(ch, 3)),
  1094. null, n.lineno, n.col_offset, n.endlineno, n.col_endoffset);
  1095. }
  1096. else if (NCH(ch) === 6) {
  1097. return new Raise(
  1098. astForExpr(c, CHILD(ch, 1)),
  1099. astForExpr(c, CHILD(ch, 3)),
  1100. astForExpr(c, CHILD(ch, 5)),
  1101. n.lineno, n.col_offset, n.endlineno, n.col_endoffset);
  1102. }
  1103. break;
  1104. default:
  1105. goog.asserts.fail("unexpected flow_stmt");
  1106. }
  1107. goog.asserts.fail("unhandled flow statement");
  1108. }
  1109. function astForArguments (c, n) {
  1110. /* parameters: '(' [varargslist] ')'
  1111. varargslist: (fpdef ['=' test] ',')* ('*' NAME [',' '**' NAME]
  1112. | '**' NAME) | fpdef ['=' test] (',' fpdef ['=' test])* [',']
  1113. */
  1114. var parenthesized;
  1115. var id;
  1116. var complexArgs;
  1117. var k;
  1118. var j;
  1119. var i;
  1120. var foundDefault;
  1121. var defaults;
  1122. var args;
  1123. var ch;
  1124. var vararg = null;
  1125. var kwarg = null;
  1126. if (n.type === SYM.parameters) {
  1127. if (NCH(n) === 2) // () as arglist
  1128. {
  1129. return new arguments_([], null, null, []);
  1130. }
  1131. n = CHILD(n, 1);
  1132. }
  1133. REQ(n, SYM.varargslist);
  1134. args = [];
  1135. defaults = [];
  1136. /* fpdef: NAME | '(' fplist ')'
  1137. fplist: fpdef (',' fpdef)* [',']
  1138. */
  1139. foundDefault = false;
  1140. i = 0;
  1141. j = 0; // index for defaults
  1142. k = 0; // index for args
  1143. while (i < NCH(n)) {
  1144. ch = CHILD(n, i);
  1145. switch (ch.type) {
  1146. case SYM.fpdef:
  1147. complexArgs = 0;
  1148. parenthesized = 0;
  1149. handle_fpdef: while (true) {
  1150. if (i + 1 < NCH(n) && CHILD(n, i + 1).type === TOK.T_EQUAL) {
  1151. defaults[j++] = astForExpr(c, CHILD(n, i + 2));
  1152. i += 2;
  1153. foundDefault = true;
  1154. }
  1155. else if (foundDefault) {
  1156. /* def f((x)=4): pass should raise an error.
  1157. def f((x, (y))): pass will just incur the tuple unpacking warning. */
  1158. if (parenthesized && !complexArgs) {
  1159. throw new Sk.builtin.SyntaxError("parenthesized arg with default", c.c_filename, n.lineno);
  1160. }
  1161. throw new Sk.builtin.SyntaxError("non-default argument follows default argument", c.c_filename, n.lineno);
  1162. }
  1163. if (NCH(ch) === 3) {
  1164. ch = CHILD(ch, 1);
  1165. // def foo((x)): is not complex, special case.
  1166. if (NCH(ch) !== 1) {
  1167. throw new Sk.builtin.SyntaxError("tuple parameter unpacking has been removed", c.c_filename, n.lineno);
  1168. }
  1169. else {
  1170. /* def foo((x)): setup for checking NAME below. */
  1171. /* Loop because there can be many parens and tuple
  1172. unpacking mixed in. */
  1173. parenthesized = true;
  1174. ch = CHILD(ch, 0);
  1175. goog.asserts.assert(ch.type === SYM.fpdef);
  1176. continue handle_fpdef;
  1177. }
  1178. }
  1179. if (CHILD(ch, 0).type === TOK.T_NAME) {
  1180. forbiddenCheck(c, n, CHILD(ch, 0).value, n.lineno);
  1181. id = strobj(CHILD(ch, 0).value);
  1182. args[k++] = new Name(id, Param, ch.lineno, ch.col_offset, n.endlineno, n.col_endoffset);
  1183. }
  1184. i += 2;
  1185. if (parenthesized) {
  1186. throw new Sk.builtin.SyntaxError("parenthesized argument names are invalid", c.c_filename, n.lineno);
  1187. }
  1188. break;
  1189. }
  1190. break;
  1191. case TOK.T_STAR:
  1192. forbiddenCheck(c, CHILD(n, i + 1), CHILD(n, i + 1).value, n.lineno);
  1193. vararg = strobj(CHILD(n, i + 1).value);
  1194. i += 3;
  1195. break;
  1196. case TOK.T_DOUBLESTAR:
  1197. forbiddenCheck(c, CHILD(n, i + 1), CHILD(n, i + 1).value, n.lineno);
  1198. kwarg = strobj(CHILD(n, i + 1).value);
  1199. i += 3;
  1200. break;
  1201. default:
  1202. goog.asserts.fail("unexpected node in varargslist");
  1203. }
  1204. }
  1205. return new arguments_(args, vararg, kwarg, defaults);
  1206. }
  1207. function astForFuncdef (c, n, decoratorSeq) {
  1208. /* funcdef: 'def' NAME parameters ':' suite */
  1209. var body;
  1210. var args;
  1211. var name;
  1212. REQ(n, SYM.funcdef);
  1213. name = strobj(CHILD(n, 1).value);
  1214. forbiddenCheck(c, CHILD(n, 1), CHILD(n, 1).value, n.lineno);
  1215. args = astForArguments(c, CHILD(n, 2));
  1216. body = astForSuite(c, CHILD(n, 4));
  1217. return new FunctionDef(name, args, body, decoratorSeq, n.lineno, n.col_offset, n.endlineno, n.col_endoffset);
  1218. }
  1219. function astForClassBases (c, n) {
  1220. /* testlist: test (',' test)* [','] */
  1221. goog.asserts.assert(NCH(n) > 0);
  1222. REQ(n, SYM.testlist);
  1223. if (NCH(n) === 1) {
  1224. return [ astForExpr(c, CHILD(n, 0)) ];
  1225. }
  1226. return seqForTestlist(c, n);
  1227. }
  1228. function astForClassdef (c, n, decoratorSeq) {
  1229. /* classdef: 'class' NAME ['(' testlist ')'] ':' suite */
  1230. var s;
  1231. var bases;
  1232. var classname;
  1233. REQ(n, SYM.classdef);
  1234. forbiddenCheck(c, n, CHILD(n, 1).value, n.lineno);
  1235. classname = strobj(CHILD(n, 1).value);
  1236. if (NCH(n) === 4) {
  1237. return new ClassDef(classname, [], astForSuite(c, CHILD(n, 3)), decoratorSeq, n.lineno, n.col_offset, n.endlineno, n.col_endoffset);
  1238. }
  1239. if (CHILD(n, 3).type === TOK.T_RPAR) {
  1240. return new ClassDef(classname, [], astForSuite(c, CHILD(n, 5)), decoratorSeq, n.lineno, n.col_offset, n.endlineno, n.col_endoffset);
  1241. }
  1242. bases = astForClassBases(c, CHILD(n, 3));
  1243. s = astForSuite(c, CHILD(n, 6));
  1244. return new ClassDef(classname, bases, s, decoratorSeq, n.lineno, n.col_offset, n.endlineno, n.col_endoffset);
  1245. }
  1246. function astForLambdef (c, n) {
  1247. /* lambdef: 'lambda' [varargslist] ':' test */
  1248. var args;
  1249. var expression;
  1250. if (NCH(n) === 3) {
  1251. args = new arguments_([], null, null, []);
  1252. expression = astForExpr(c, CHILD(n, 2));
  1253. }
  1254. else {
  1255. args = astForArguments(c, CHILD(n, 1));
  1256. expression = astForExpr(c, CHILD(n, 3));
  1257. }
  1258. return new Lambda(args, expression, n.lineno, n.col_offset, n.endlineno, n.col_endoffset);
  1259. }
  1260. function astForComprehension(c, n) {
  1261. /* testlist_comp: test ( comp_for | (',' test)* [','] )
  1262. argument: test [comp_for] | test '=' test # Really [keyword '='] test */
  1263. var j;
  1264. var ifs;
  1265. var nifs;
  1266. var ge;
  1267. var expression;
  1268. var t;
  1269. var forch;
  1270. var i;
  1271. var ch;
  1272. var genexps;
  1273. var nfors;
  1274. var elt;
  1275. var comps;
  1276. var comp;
  1277. function countCompFors(c, n) {
  1278. var nfors = 0;
  1279. count_comp_for: while (true) {
  1280. nfors++;
  1281. REQ(n, SYM.comp_for);
  1282. if (NCH(n) === 5) {
  1283. n = CHILD(n, 4);
  1284. } else {
  1285. return nfors;
  1286. }
  1287. count_comp_iter: while (true) {
  1288. REQ(n, SYM.comp_iter);
  1289. n = CHILD(n, 0);
  1290. if (n.type === SYM.comp_for) {
  1291. continue count_comp_for;
  1292. } else if (n.type === SYM.comp_if) {
  1293. if (NCH(n) === 3) {
  1294. n = CHILD(n, 2);
  1295. continue count_comp_iter;
  1296. } else {
  1297. return nfors;
  1298. }
  1299. }
  1300. break;
  1301. }
  1302. break;
  1303. }
  1304. goog.asserts.fail("logic error in countCompFors");
  1305. }
  1306. function countCompIfs(c, n) {
  1307. var nifs = 0;
  1308. while (true) {
  1309. REQ(n, SYM.comp_iter);
  1310. if (CHILD(n, 0).type === SYM.comp_for) {
  1311. return nifs;
  1312. }
  1313. n = CHILD(n, 0);
  1314. REQ(n, SYM.comp_if);
  1315. nifs++;
  1316. if (NCH(n) == 2) {
  1317. return nifs;
  1318. }
  1319. n = CHILD(n, 2);
  1320. }
  1321. }
  1322. nfors = countCompFors(c, n);
  1323. comps = [];
  1324. for (i = 0; i < nfors; ++i) {
  1325. REQ(n, SYM.comp_for);
  1326. forch = CHILD(n, 1);
  1327. t = astForExprlist(c, forch, Store);
  1328. expression = astForExpr(c, CHILD(n, 3));
  1329. if (NCH(forch) === 1) {
  1330. comp = new comprehension(t[0], expression, []);
  1331. } else {
  1332. comp = new comprehension(new Tuple(t, Store, n.lineno, n.col_offset, n.endlineno, n.col_endoffset), expression, []);
  1333. }
  1334. if (NCH(n) === 5) {
  1335. n = CHILD(n, 4);
  1336. nifs = countCompIfs(c, n);
  1337. ifs = [];
  1338. for (j = 0; j < nifs; ++j) {
  1339. REQ(n, SYM.comp_iter);
  1340. n = CHILD(n, 0);
  1341. REQ(n, SYM.comp_if);
  1342. expression = astForExpr(c, CHILD(n, 1));
  1343. ifs[j] = expression;
  1344. if (NCH(n) === 3) {
  1345. n = CHILD(n, 2);
  1346. }
  1347. }
  1348. if (n.type === SYM.comp_iter) {
  1349. n = CHILD(n, 0);
  1350. }
  1351. comp.ifs = ifs;
  1352. }
  1353. comps[i] = comp;
  1354. }
  1355. return comps;
  1356. }
  1357. function astForIterComp(c, n, type) {
  1358. var elt, comps;
  1359. goog.asserts.assert(NCH(n) > 1);
  1360. elt = astForExpr(c, CHILD(n, 0));
  1361. comps = astForComprehension(c, CHILD(n, 1));
  1362. if (type === COMP_GENEXP) {
  1363. return new GeneratorExp(elt, comps, n.lineno, n.col_offset, n.endlineno, n.col_endoffset);
  1364. } else if (type === COMP_SETCOMP) {
  1365. return new SetComp(elt, comps, n.lineno, n.col_offset, n.endlineno, n.col_endoffset);
  1366. }
  1367. }
  1368. function astForDictComp(c, n) {
  1369. var key, value;
  1370. var comps = [];
  1371. goog.asserts.assert(NCH(n) > 3);
  1372. REQ(CHILD(n, 1), TOK.T_COLON);
  1373. key = astForExpr(c, CHILD(n, 0));
  1374. value = astForExpr(c, CHILD(n, 2));
  1375. comps = astForComprehension(c, CHILD(n, 3));
  1376. return new DictComp(key, value, comps, n.lineno, n.col_offset, n.endlineno, n.col_endoffset);
  1377. }
  1378. function astForGenExpr(c, n) {
  1379. goog.asserts.assert(n.type === SYM.testlist_comp || n.type === SYM.argument);
  1380. return astForIterComp(c, n, COMP_GENEXP);
  1381. }
  1382. function astForSetComp(c, n) {
  1383. goog.asserts.assert(n.type === SYM.dictorsetmaker);
  1384. return astForIterComp(c, n, COMP_SETCOMP);
  1385. }
  1386. function astForWhileStmt (c, n) {
  1387. /* while_stmt: 'while' test ':' suite ['else' ':' suite] */
  1388. REQ(n, SYM.while_stmt);
  1389. if (NCH(n) === 4) {
  1390. return new While_(astForExpr(c, CHILD(n, 1)), astForSuite(c, CHILD(n, 3)), [], n.lineno, n.col_offset, n.endlineno, n.col_endoffset);
  1391. }
  1392. else if (NCH(n) === 7) {
  1393. return new While_(astForExpr(c, CHILD(n, 1)), astForSuite(c, CHILD(n, 3)), astForSuite(c, CHILD(n, 6)), n.lineno, n.col_offset, n.endlineno, n.col_endoffset);
  1394. }
  1395. goog.asserts.fail("wrong number of tokens for 'while' stmt");
  1396. }
  1397. function astForAugassign (c, n) {
  1398. REQ(n, SYM.augassign);
  1399. n = CHILD(n, 0);
  1400. switch (n.value.charAt(0)) {
  1401. case "+":
  1402. return Add;
  1403. case "-":
  1404. return Sub;
  1405. case "/":
  1406. if (n.value.charAt(1) === "/") {
  1407. return FloorDiv;
  1408. }
  1409. return Div;
  1410. case "%":
  1411. return Mod;
  1412. case "<":
  1413. return LShift;
  1414. case ">":
  1415. return RShift;
  1416. case "&":
  1417. return BitAnd;
  1418. case "^":
  1419. return BitXor;
  1420. case "|":
  1421. return BitOr;
  1422. case "*":
  1423. if (n.value.charAt(1) === "*") {
  1424. return Pow;
  1425. }
  1426. return Mult;
  1427. default:
  1428. goog.asserts.fail("invalid augassign");
  1429. }
  1430. }
  1431. function astForBinop (c, n) {
  1432. /* Must account for a sequence of expressions.
  1433. How should A op B op C by represented?
  1434. BinOp(BinOp(A, op, B), op, C).
  1435. */
  1436. var tmp;
  1437. var newoperator;
  1438. var nextOper;
  1439. var i;
  1440. var result = new BinOp(
  1441. astForExpr(c, CHILD(n, 0)),
  1442. getOperator(CHILD(n, 1)),
  1443. astForExpr(c, CHILD(n, 2)),
  1444. n.lineno, n.col_offset, n.endlineno, n.col_endoffset);
  1445. var nops = (NCH(n) - 1) / 2;
  1446. for (i = 1; i < nops; ++i) {
  1447. nextOper = CHILD(n, i * 2 + 1);
  1448. newoperator = getOperator(nextOper);
  1449. tmp = astForExpr(c, CHILD(n, i * 2 + 2));
  1450. result = new BinOp(result, newoperator, tmp, nextOper.lineno, nextOper.col_offset, n.endlineno, n.col_endoffset);
  1451. }
  1452. return result;
  1453. }
  1454. function astForTestlist(c, n) {
  1455. /* this doesn't show up in Grammar.txt never did: testlist_gexp: test (',' test)* [','] */
  1456. /* testlist_comp: test (',' test)* [','] */
  1457. /* testlist: test (',' test)* [','] */
  1458. /* testlist_safe: test (',' test)+ [','] */
  1459. /* testlist1: test (',' test)* */
  1460. goog.asserts.assert(NCH(n) > 0);
  1461. if (n.type === SYM.testlist_comp) {
  1462. if (NCH(n) > 1) {
  1463. goog.asserts.assert(CHILD(n, 1).type !== SYM.comp_for);
  1464. }
  1465. }
  1466. else {
  1467. goog.asserts.assert(n.type === SYM.testlist || n.type === SYM.testlist_safe || n.type === SYM.testlist1);
  1468. }
  1469. if (NCH(n) === 1) {
  1470. return astForExpr(c, CHILD(n, 0));
  1471. }
  1472. else {
  1473. return new Tuple(seqForTestlist(c, n), Load, n.lineno, n.col_offset, n.endlineno, n.col_endoffset);
  1474. }
  1475. }
  1476. function astForExprStmt (c, n) {
  1477. var expression;
  1478. var value;
  1479. var e;
  1480. var i;
  1481. var targets;
  1482. var expr2;
  1483. var varName;
  1484. var expr1;
  1485. var ch;
  1486. REQ(n, SYM.expr_stmt);
  1487. /* expr_stmt: testlist (augassign (yield_expr|testlist)
  1488. | ('=' (yield_expr|testlist))*)
  1489. testlist: test (',' test)* [',']
  1490. augassign: '+=' | '-=' | '*=' | '/=' | '%=' | '&=' | '|=' | '^='
  1491. | '<<=' | '>>=' | '**=' | '//='
  1492. test: ... here starts the operator precendence dance
  1493. */
  1494. if (NCH(n) === 1) {
  1495. return new Expr(astForTestlist(c, CHILD(n, 0)), n.lineno, n.col_offset, n.endlineno, n.col_endoffset);
  1496. }
  1497. else if (CHILD(n, 1).type === SYM.augassign) {
  1498. ch = CHILD(n, 0);
  1499. expr1 = astForTestlist(c, ch);
  1500. switch (expr1.constructor) {
  1501. case GeneratorExp:
  1502. throw new Sk.builtin.SyntaxError("augmented assignment to generator expression not possible", c.c_filename, n.lineno);
  1503. case Yield:
  1504. throw new Sk.builtin.SyntaxError("augmented assignment to yield expression not possible", c.c_filename, n.lineno);
  1505. case Name:
  1506. varName = expr1.id;
  1507. forbiddenCheck(c, ch, varName, n.lineno);
  1508. break;
  1509. case Attribute:
  1510. case Subscript:
  1511. break;
  1512. default:
  1513. throw new Sk.builtin.SyntaxError("illegal expression for augmented assignment", c.c_filename, n.lineno);
  1514. }
  1515. setContext(c, expr1, Store, ch);
  1516. ch = CHILD(n, 2);
  1517. if (ch.type === SYM.testlist) {
  1518. expr2 = astForTestlist(c, ch);
  1519. }
  1520. else {
  1521. expr2 = astForExpr(c, ch);
  1522. }
  1523. return new AugAssign(expr1, astForAugassign(c, CHILD(n, 1)), expr2, n.lineno, n.col_offset, n.endlineno, n.col_endoffset);
  1524. }
  1525. else {
  1526. // normal assignment
  1527. REQ(CHILD(n, 1), TOK.T_EQUAL);
  1528. targets = [];
  1529. for (i = 0; i < NCH(n) - 2; i += 2) {
  1530. ch = CHILD(n, i);
  1531. if (ch.type === SYM.yield_expr) {
  1532. throw new Sk.builtin.SyntaxError("assignment to yield expression not possible", c.c_filename, n.lineno);
  1533. }
  1534. e = astForTestlist(c, ch);
  1535. setContext(c, e, Store, CHILD(n, i));
  1536. targets[i / 2] = e;
  1537. }
  1538. value = CHILD(n, NCH(n) - 1);
  1539. if (value.type === SYM.testlist) {
  1540. expression = astForTestlist(c, value);
  1541. }
  1542. else {
  1543. expression = astForExpr(c, value);
  1544. }
  1545. return new Assign(targets, expression, n.lineno, n.col_offset, n.endlineno, n.col_endoffset);
  1546. }
  1547. }
  1548. function astForIfexpr (c, n) {
  1549. /* test: or_test 'if' or_test 'else' test */
  1550. goog.asserts.assert(NCH(n) === 5);
  1551. return new IfExp(
  1552. astForExpr(c, CHILD(n, 2)),
  1553. astForExpr(c, CHILD(n, 0)),
  1554. astForExpr(c, CHILD(n, 4)),
  1555. n.lineno, n.col_offset, n.endlineno, n.col_endoffset);
  1556. }
  1557. /**
  1558. * s is a python-style string literal, including quote characters and u/r/b
  1559. * prefixes. Returns decoded string object.
  1560. */
  1561. function parsestr (c, s) {
  1562. var encodeUtf8 = function (s) {
  1563. return unescape(encodeURIComponent(s));
  1564. };
  1565. var decodeUtf8 = function (s) {
  1566. return decodeURIComponent(escape(s));
  1567. };
  1568. var decodeEscape = function (s, quote) {
  1569. var d3;
  1570. var d2;
  1571. var d1;
  1572. var d0;
  1573. var c;
  1574. var i;
  1575. var len = s.length;
  1576. var ret = "";
  1577. for (i = 0; i < len; ++i) {
  1578. c = s.charAt(i);
  1579. if (c === "\\") {
  1580. ++i;
  1581. c = s.charAt(i);
  1582. if (c === "n") {
  1583. ret += "\n";
  1584. }
  1585. else if (c === "\\") {
  1586. ret += "\\";
  1587. }
  1588. else if (c === "t") {
  1589. ret += "\t";
  1590. }
  1591. else if (c === "r") {
  1592. ret += "\r";
  1593. }
  1594. else if (c === "b") {
  1595. ret += "\b";
  1596. }
  1597. else if (c === "f") {
  1598. ret += "\f";
  1599. }
  1600. else if (c === "v") {
  1601. ret += "\v";
  1602. }
  1603. else if (c === "0") {
  1604. ret += "\0";
  1605. }
  1606. else if (c === '"') {
  1607. ret += '"';
  1608. }
  1609. else if (c === '\'') {
  1610. ret += '\'';
  1611. }
  1612. else if (c === "\n") /* escaped newline, join lines */ {
  1613. }
  1614. else if (c === "x") {
  1615. d0 = s.charAt(++i);
  1616. d1 = s.charAt(++i);
  1617. ret += String.fromCharCode(parseInt(d0 + d1, 16));
  1618. }
  1619. else if (c === "u" || c === "U") {
  1620. d0 = s.charAt(++i);
  1621. d1 = s.charAt(++i);
  1622. d2 = s.charAt(++i);
  1623. d3 = s.charAt(++i);
  1624. ret += String.fromCharCode(parseInt(d0 + d1, 16), parseInt(d2 + d3, 16));
  1625. }
  1626. else {
  1627. // Leave it alone
  1628. ret += "\\" + c;
  1629. // goog.asserts.fail("unhandled escape: '" + c.charCodeAt(0) + "'");
  1630. }
  1631. }
  1632. else {
  1633. ret += c;
  1634. }
  1635. }
  1636. return ret;
  1637. };
  1638. //print("parsestr", s);
  1639. var quote = s.charAt(0);
  1640. var rawmode = false;
  1641. var unicode = false;
  1642. // treats every sequence as unicodes even if they are not treated with uU prefix
  1643. // kinda hacking though working for most purposes
  1644. if((c.c_flags & Parser.CO_FUTURE_UNICODE_LITERALS || Sk.python3 === true)) {
  1645. unicode = true;
  1646. }
  1647. if (quote === "u" || quote === "U") {
  1648. s = s.substr(1);
  1649. quote = s.charAt(0);
  1650. unicode = true;
  1651. }
  1652. else if (quote === "r" || quote === "R") {
  1653. s = s.substr(1);
  1654. quote = s.charAt(0);
  1655. rawmode = true;
  1656. }
  1657. goog.asserts.assert(quote !== "b" && quote !== "B", "todo; haven't done b'' strings yet");
  1658. goog.asserts.assert(quote === "'" || quote === '"' && s.charAt(s.length - 1) === quote);
  1659. s = s.substr(1, s.length - 2);
  1660. if (unicode) {
  1661. s = encodeUtf8(s);
  1662. }
  1663. if (s.length >= 4 && s.charAt(0) === quote && s.charAt(1) === quote) {
  1664. goog.asserts.assert(s.charAt(s.length - 1) === quote && s.charAt(s.length - 2) === quote);
  1665. s = s.substr(2, s.length - 4);
  1666. }
  1667. if (rawmode || s.indexOf("\\") === -1) {
  1668. return strobj(decodeUtf8(s));
  1669. }
  1670. return strobj(decodeEscape(s, quote));
  1671. }
  1672. function parsestrplus (c, n) {
  1673. var i;
  1674. var ret;
  1675. REQ(CHILD(n, 0), TOK.T_STRING);
  1676. ret = new Sk.builtin.str("");
  1677. for (i = 0; i < NCH(n); ++i) {
  1678. try {
  1679. ret = ret.sq$concat(parsestr(c, CHILD(n, i).value));
  1680. } catch (x) {
  1681. throw new Sk.builtin.SyntaxError("invalid string (possibly contains a unicode character)", c.c_filename, CHILD(n, i).lineno);
  1682. }
  1683. }
  1684. return ret;
  1685. }
  1686. function parsenumber (c, s, lineno) {
  1687. var neg;
  1688. var val;
  1689. var tmp;
  1690. var end = s.charAt(s.length - 1);
  1691. // call internal complex type constructor for complex strings
  1692. if (end === "j" || end === "J") {
  1693. return Sk.builtin.complex.complex_subtype_from_string(s);
  1694. }
  1695. // Handle longs
  1696. if (end === "l" || end === "L") {
  1697. return Sk.longFromStr(s.substr(0, s.length - 1), 0);
  1698. }
  1699. // todo; we don't currently distinguish between int and float so
  1700. // str is wrong for these.
  1701. if (s.indexOf(".") !== -1) {
  1702. return new Sk.builtin.float_(parseFloat(s));
  1703. }
  1704. // Handle integers of various bases
  1705. tmp = s;
  1706. neg = false;
  1707. if (s.charAt(0) === "-") {
  1708. tmp = s.substr(1);
  1709. neg = true;
  1710. }
  1711. if (tmp.charAt(0) === "0" && (tmp.charAt(1) === "x" || tmp.charAt(1) === "X")) {
  1712. // Hex
  1713. tmp = tmp.substring(2);
  1714. val = parseInt(tmp, 16);
  1715. } else if ((s.indexOf("e") !== -1) || (s.indexOf("E") !== -1)) {
  1716. // Float with exponent (needed to make sure e/E wasn't hex first)
  1717. return new Sk.builtin.float_(parseFloat(s));
  1718. } else if (tmp.charAt(0) === "0" && (tmp.charAt(1) === "b" || tmp.charAt(1) === "B")) {
  1719. // Binary
  1720. tmp = tmp.substring(2);
  1721. val = parseInt(tmp, 2);
  1722. } else if (tmp.charAt(0) === "0") {
  1723. if (tmp === "0") {
  1724. // Zero
  1725. val = 0;
  1726. } else {
  1727. // Octal
  1728. tmp = tmp.substring(1);
  1729. if ((tmp.charAt(0) === "o") || (tmp.charAt(0) === "O")) {
  1730. tmp = tmp.substring(1);
  1731. }
  1732. val = parseInt(tmp, 8);
  1733. }
  1734. }
  1735. else {
  1736. // Decimal
  1737. val = parseInt(tmp, 10);
  1738. }
  1739. // Convert to long
  1740. if (val > Sk.builtin.int_.threshold$ &&
  1741. Math.floor(val) === val &&
  1742. (s.indexOf("e") === -1 && s.indexOf("E") === -1)) {
  1743. return Sk.longFromStr(s, 0);
  1744. }
  1745. // Small enough, return parsed number
  1746. if (neg) {
  1747. return new Sk.builtin.int_(-val);
  1748. } else {
  1749. return new Sk.builtin.int_(val);
  1750. }
  1751. }
  1752. function astForSlice (c, n) {
  1753. var n2;
  1754. var step;
  1755. var upper;
  1756. var lower;
  1757. var ch;
  1758. REQ(n, SYM.subscript);
  1759. /*
  1760. subscript: '.' '.' '.' | test | [test] ':' [test] [sliceop]
  1761. sliceop: ':' [test]
  1762. */
  1763. ch = CHILD(n, 0);
  1764. lower = null;
  1765. upper = null;
  1766. step = null;
  1767. if (ch.type === TOK.T_DOT) {
  1768. return new Ellipsis();
  1769. }
  1770. if (NCH(n) === 1 && ch.type === SYM.test) {
  1771. return new Index(astForExpr(c, ch));
  1772. }
  1773. if (ch.type === SYM.test) {
  1774. lower = astForExpr(c, ch);
  1775. }
  1776. if (ch.type === TOK.T_COLON) {
  1777. if (NCH(n) > 1) {
  1778. n2 = CHILD(n, 1);
  1779. if (n2.type === SYM.test) {
  1780. upper = astForExpr(c, n2);
  1781. }
  1782. }
  1783. }
  1784. else if (NCH(n) > 2) {
  1785. n2 = CHILD(n, 2);
  1786. if (n2.type === SYM.test) {
  1787. upper = astForExpr(c, n2);
  1788. }
  1789. }
  1790. ch = CHILD(n, NCH(n) - 1);
  1791. if (ch.type === SYM.sliceop) {
  1792. if (NCH(ch) === 1) {
  1793. ch = CHILD(ch, 0);
  1794. step = new Name(strobj("None"), Load, ch.lineno, ch.col_offset, ch.endlineno, ch.col_endoffset);
  1795. }
  1796. else {
  1797. ch = CHILD(ch, 1);
  1798. if (ch.type === SYM.test) {
  1799. step = astForExpr(c, ch);
  1800. }
  1801. }
  1802. }
  1803. return new Slice(lower, upper, step);
  1804. }
  1805. function astForAtom(c, n) {
  1806. /* atom: ('(' [yield_expr|testlist_comp] ')' |
  1807. '[' [listmaker] ']' |
  1808. '{' [dictorsetmaker] '}' |
  1809. '`' testlist1 '`' |
  1810. NAME | NUMBER | STRING+)
  1811. */
  1812. var i;
  1813. var values;
  1814. var keys;
  1815. var size;
  1816. var ch = CHILD(n, 0);
  1817. var elts;
  1818. switch (ch.type) {
  1819. case TOK.T_NAME:
  1820. // All names start in Load context, but may be changed later
  1821. return new Name(strobj(ch.value), Load, n.lineno, n.col_offset, n.endlineno, n.col_endoffset);
  1822. case TOK.T_STRING:
  1823. return new Str(parsestrplus(c, n), n.lineno, n.col_offset, n.endlineno, n.col_endoffset);
  1824. case TOK.T_NUMBER:
  1825. return new Num(parsenumber(c, ch.value, n.lineno), n.lineno, n.col_offset, n.endlineno, n.col_endoffset);
  1826. case TOK.T_LPAR: // various uses for parens
  1827. ch = CHILD(n, 1);
  1828. if (ch.type === TOK.T_RPAR) {
  1829. return new Tuple([], Load, n.lineno, n.col_offset, n.endlineno, n.col_endoffset);
  1830. }
  1831. if (ch.type === SYM.yield_expr) {
  1832. return astForExpr(c, ch);
  1833. }
  1834. // if (NCH(ch) > 1 && CHILD(ch, 1).type === SYM.comp_for) {
  1835. // return astForComprehension(c, ch);
  1836. // }
  1837. return astForTestlistComp(c, ch);
  1838. case TOK.T_LSQB: // list or listcomp
  1839. ch = CHILD(n, 1);
  1840. if (ch.type === TOK.T_RSQB) {
  1841. return new List([], Load, n.lineno, n.col_offset, n.endlineno, n.col_endoffset);
  1842. }
  1843. REQ(ch, SYM.listmaker);
  1844. if (NCH(ch) === 1 || CHILD(ch, 1).type === TOK.T_COMMA) {
  1845. return new List(seqForTestlist(c, ch), Load, n.lineno, n.col_offset, n.endlineno, n.col_endoffset);
  1846. }
  1847. return astForListcomp(c, ch);
  1848. case TOK.T_LBRACE:
  1849. /* dictorsetmaker:
  1850. * (test ':' test (comp_for : (',' test ':' test)* [','])) |
  1851. * (test (comp_for | (',' test)* [',']))
  1852. */
  1853. keys = [];
  1854. values = [];
  1855. ch = CHILD(n, 1);
  1856. if (n.type === TOK.T_RBRACE) {
  1857. //it's an empty dict
  1858. return new Dict([], null, n.lineno, n.col_offset, n.endlineno, n.col_endoffset);
  1859. }
  1860. else if (NCH(ch) === 1 || (NCH(ch) !== 0 && CHILD(ch, 1).type === TOK.T_COMMA)) {
  1861. //it's a simple set
  1862. elts = [];
  1863. size = Math.floor((NCH(ch) + 1) / 2);
  1864. for (i = 0; i < NCH(ch); i += 2) {
  1865. var expression = astForExpr(c, CHILD(ch, i));
  1866. elts[i / 2] = expression;
  1867. }
  1868. return new Set(elts, n.lineno, n.col_offset, n.endlineno, n.col_endoffset);
  1869. }
  1870. else if (NCH(ch) !== 0 && CHILD(ch, 1).type == SYM.comp_for) {
  1871. //it's a set comprehension
  1872. return astForSetComp(c, ch);
  1873. }
  1874. else if (NCH(ch) > 3 && CHILD(ch, 3).type === SYM.comp_for) {
  1875. //it's a dict compr. I think.
  1876. return astForDictComp(c, ch);
  1877. }
  1878. else {
  1879. size = Math.floor((NCH(ch) + 1) / 4); // + 1 for no trailing comma case
  1880. for (i = 0; i < NCH(ch); i += 4) {
  1881. keys[i / 4] = astForExpr(c, CHILD(ch, i));
  1882. values[i / 4] = astForExpr(c, CHILD(ch, i + 2));
  1883. }
  1884. return new Dict(keys, values, n.lineno, n.col_offset, n.endlineno, n.col_endoffset);
  1885. }
  1886. case TOK.T_BACKQUOTE:
  1887. //throw new Sk.builtin.SyntaxError("backquote not supported, use repr()", c.c_filename, n.lineno);
  1888. return new Repr(astForTestlist(c, CHILD(n, 1)), n.lineno, n.col_offset, n.endlineno, n.col_endoffset);
  1889. default:
  1890. goog.asserts.fail("unhandled atom", ch.type);
  1891. }
  1892. }
  1893. function astForPower (c, n) {
  1894. /* power: atom trailer* ('**' factor)*
  1895. */
  1896. var f;
  1897. var tmp;
  1898. var ch;
  1899. var i;
  1900. var e;
  1901. REQ(n, SYM.power);
  1902. e = astForAtom(c, CHILD(n, 0));
  1903. if (NCH(n) === 1) {
  1904. return e;
  1905. }
  1906. for (i = 1; i < NCH(n); ++i) {
  1907. ch = CHILD(n, i);
  1908. if (ch.type !== SYM.trailer) {
  1909. break;
  1910. }
  1911. tmp = astForTrailer(c, ch, e);
  1912. tmp.lineno = e.lineno;
  1913. tmp.col_offset = e.col_offset;
  1914. tmp.endlineno = e.endlineno;
  1915. tmp.col_endoffset = e.col_endoffset;
  1916. e = tmp;
  1917. }
  1918. if (CHILD(n, NCH(n) - 1).type === SYM.factor) {
  1919. f = astForExpr(c, CHILD(n, NCH(n) - 1));
  1920. e = new BinOp(e, Pow, f, n.lineno, n.col_offset, n.endlineno, n.col_endoffset);
  1921. }
  1922. return e;
  1923. }
  1924. function astForExpr (c, n) {
  1925. /* handle the full range of simple expressions
  1926. test: or_test ['if' or_test 'else' test] | lambdef
  1927. or_test: and_test ('or' and_test)*
  1928. and_test: not_test ('and' not_test)*
  1929. not_test: 'not' not_test | comparison
  1930. comparison: expr (comp_op expr)*
  1931. expr: xor_expr ('|' xor_expr)*
  1932. xor_expr: and_expr ('^' and_expr)*
  1933. and_expr: shift_expr ('&' shift_expr)*
  1934. shift_expr: arith_expr (('<<'|'>>') arith_expr)*
  1935. arith_expr: term (('+'|'-') term)*
  1936. term: factor (('*'|'/'|'%'|'//') factor)*
  1937. factor: ('+'|'-'|'~') factor | power
  1938. power: atom trailer* ('**' factor)*
  1939. As well as modified versions that exist for backward compatibility,
  1940. to explicitly allow:
  1941. [ x for x in lambda: 0, lambda: 1 ]
  1942. (which would be ambiguous without these extra rules)
  1943. old_test: or_test | old_lambdef
  1944. old_lambdef: 'lambda' [vararglist] ':' old_test
  1945. */
  1946. var exp;
  1947. var cmps;
  1948. var ops;
  1949. var i;
  1950. var seq;
  1951. LOOP: while (true) {
  1952. switch (n.type) {
  1953. case SYM.test:
  1954. case SYM.old_test:
  1955. if (CHILD(n, 0).type === SYM.lambdef || CHILD(n, 0).type === SYM.old_lambdef) {
  1956. return astForLambdef(c, CHILD(n, 0));
  1957. }
  1958. else if (NCH(n) > 1) {
  1959. return astForIfexpr(c, n);
  1960. }
  1961. // fallthrough
  1962. case SYM.or_test:
  1963. case SYM.and_test:
  1964. if (NCH(n) === 1) {
  1965. n = CHILD(n, 0);
  1966. continue LOOP;
  1967. }
  1968. seq = [];
  1969. for (i = 0; i < NCH(n); i += 2) {
  1970. seq[i / 2] = astForExpr(c, CHILD(n, i));
  1971. }
  1972. if (CHILD(n, 1).value === "and") {
  1973. return new BoolOp(And, seq, n.lineno, n.col_offset, n.endlineno, n.col_endoffset);
  1974. }
  1975. goog.asserts.assert(CHILD(n, 1).value === "or");
  1976. return new BoolOp(Or, seq, n.lineno, n.col_offset, n.endlineno, n.col_endoffset);
  1977. case SYM.not_test:
  1978. if (NCH(n) === 1) {
  1979. n = CHILD(n, 0);
  1980. continue LOOP;
  1981. }
  1982. else {
  1983. return new UnaryOp(Not, astForExpr(c, CHILD(n, 1)), n.lineno, n.col_offset, n.endlineno, n.col_endoffset);
  1984. }
  1985. break;
  1986. case SYM.comparison:
  1987. if (NCH(n) === 1) {
  1988. n = CHILD(n, 0);
  1989. continue LOOP;
  1990. }
  1991. else {
  1992. ops = [];
  1993. cmps = [];
  1994. for (i = 1; i < NCH(n); i += 2) {
  1995. ops[(i - 1) / 2] = astForCompOp(c, CHILD(n, i));
  1996. cmps[(i - 1) / 2] = astForExpr(c, CHILD(n, i + 1));
  1997. }
  1998. return new Compare(astForExpr(c, CHILD(n, 0)), ops, cmps, n.lineno, n.col_offset, n.endlineno, n.col_endoffset);
  1999. }
  2000. break;
  2001. case SYM.expr:
  2002. case SYM.xor_expr:
  2003. case SYM.and_expr:
  2004. case SYM.shift_expr:
  2005. case SYM.arith_expr:
  2006. case SYM.term:
  2007. if (NCH(n) === 1) {
  2008. n = CHILD(n, 0);
  2009. continue LOOP;
  2010. }
  2011. return astForBinop(c, n);
  2012. case SYM.yield_expr:
  2013. exp = null;
  2014. if (NCH(n) === 2) {
  2015. exp = astForTestlist(c, CHILD(n, 1));
  2016. }
  2017. return new Yield(exp, n.lineno, n.col_offset, n.endlineno, n.col_endoffset);
  2018. case SYM.factor:
  2019. if (NCH(n) === 1) {
  2020. n = CHILD(n, 0);
  2021. continue LOOP;
  2022. }
  2023. return astForFactor(c, n);
  2024. case SYM.power:
  2025. return astForPower(c, n);
  2026. default:
  2027. goog.asserts.fail("unhandled expr", "n.type: %d", n.type);
  2028. }
  2029. break;
  2030. }
  2031. }
  2032. function astForPrintStmt (c, n) {
  2033. /* print_stmt: 'print' ( [ test (',' test)* [','] ]
  2034. | '>>' test [ (',' test)+ [','] ] )
  2035. */
  2036. var nl;
  2037. var i, j;
  2038. var seq;
  2039. var start = 1;
  2040. var dest = null;
  2041. REQ(n, SYM.print_stmt);
  2042. if (NCH(n) >= 2 && CHILD(n, 1).type === TOK.T_RIGHTSHIFT) {
  2043. dest = astForExpr(c, CHILD(n, 2));
  2044. start = 4;
  2045. }
  2046. seq = [];
  2047. for (i = start, j = 0; i < NCH(n); i += 2, ++j) {
  2048. seq[j] = astForExpr(c, CHILD(n, i));
  2049. }
  2050. nl = (CHILD(n, NCH(n) - 1)).type === TOK.T_COMMA ? false : true;
  2051. return new Print(dest, seq, nl, n.lineno, n.col_offset, n.endlineno, n.col_endoffset);
  2052. }
  2053. function astForStmt(c, n) {
  2054. var ch;
  2055. if (n.type === SYM.stmt) {
  2056. goog.asserts.assert(NCH(n) === 1);
  2057. n = CHILD(n, 0);
  2058. }
  2059. if (n.type === SYM.simple_stmt) {
  2060. goog.asserts.assert(numStmts(n) === 1);
  2061. n = CHILD(n, 0);
  2062. }
  2063. if (n.type === SYM.small_stmt) {
  2064. REQ(n, SYM.small_stmt);
  2065. n = CHILD(n, 0);
  2066. /* small_stmt: expr_stmt | print_stmt | del_stmt | pass_stmt
  2067. | flow_stmt | import_stmt | global_stmt | exec_stmt
  2068. | assert_stmt
  2069. */
  2070. switch (n.type) {
  2071. case SYM.expr_stmt:
  2072. return astForExprStmt(c, n);
  2073. case SYM.print_stmt:
  2074. return astForPrintStmt(c, n);
  2075. case SYM.del_stmt:
  2076. return astForDelStmt(c, n);
  2077. case SYM.pass_stmt:
  2078. return new Pass(n.lineno, n.col_offset, n.endlineno, n.col_endoffset);
  2079. case SYM.flow_stmt:
  2080. return astForFlowStmt(c, n);
  2081. case SYM.import_stmt:
  2082. return astForImportStmt(c, n);
  2083. case SYM.global_stmt:
  2084. return astForGlobalStmt(c, n);
  2085. case SYM.exec_stmt:
  2086. return astForExecStmt(c, n);
  2087. case SYM.assert_stmt:
  2088. return astForAssertStmt(c, n);
  2089. case SYM.debugger_stmt:
  2090. return new Debugger_(n.lineno, n.col_offset, n.endlineno, n.col_endoffset);
  2091. default:
  2092. goog.asserts.fail("unhandled small_stmt");
  2093. }
  2094. }
  2095. else {
  2096. /* compound_stmt: if_stmt | while_stmt | for_stmt | try_stmt
  2097. | funcdef | classdef | decorated
  2098. */
  2099. ch = CHILD(n, 0);
  2100. REQ(n, SYM.compound_stmt);
  2101. switch (ch.type) {
  2102. case SYM.if_stmt:
  2103. return astForIfStmt(c, ch);
  2104. case SYM.while_stmt:
  2105. return astForWhileStmt(c, ch);
  2106. case SYM.for_stmt:
  2107. return astForForStmt(c, ch);
  2108. case SYM.try_stmt:
  2109. return astForTryStmt(c, ch);
  2110. case SYM.with_stmt:
  2111. return astForWithStmt(c, ch);
  2112. case SYM.funcdef:
  2113. return astForFuncdef(c, ch, []);
  2114. case SYM.classdef:
  2115. return astForClassdef(c, ch, []);
  2116. case SYM.decorated:
  2117. return astForDecorated(c, ch);
  2118. default:
  2119. goog.asserts.assert("unhandled compound_stmt");
  2120. }
  2121. }
  2122. }
  2123. Sk.astFromParse = function (n, filename, c_flags) {
  2124. var j;
  2125. var num;
  2126. var ch;
  2127. var i;
  2128. var c = new Compiling("utf-8", filename, c_flags);
  2129. var stmts = [];
  2130. var k = 0;
  2131. switch (n.type) {
  2132. case SYM.file_input:
  2133. for (i = 0; i < NCH(n) - 1; ++i) {
  2134. ch = CHILD(n, i);
  2135. if (n.type === TOK.T_NEWLINE) {
  2136. continue;
  2137. }
  2138. REQ(ch, SYM.stmt);
  2139. num = numStmts(ch);
  2140. if (num === 1) {
  2141. stmts[k++] = astForStmt(c, ch);
  2142. }
  2143. else {
  2144. ch = CHILD(ch, 0);
  2145. REQ(ch, SYM.simple_stmt);
  2146. for (j = 0; j < num; ++j) {
  2147. stmts[k++] = astForStmt(c, CHILD(ch, j * 2));
  2148. }
  2149. }
  2150. }
  2151. return new Module(stmts);
  2152. case SYM.eval_input:
  2153. goog.asserts.fail("todo;");
  2154. case SYM.single_input:
  2155. goog.asserts.fail("todo;");
  2156. default:
  2157. goog.asserts.fail("todo;");
  2158. }
  2159. };
  2160. Sk.astDump = function (node) {
  2161. var spaces = function (n) // todo; blurgh
  2162. {
  2163. var i;
  2164. var ret = "";
  2165. for (i = 0; i < n; ++i) {
  2166. ret += " ";
  2167. }
  2168. return ret;
  2169. };
  2170. var _format = function (node, indent) {
  2171. var ret;
  2172. var elemsstr;
  2173. var x;
  2174. var elems;
  2175. var fieldstr;
  2176. var field;
  2177. var attrs;
  2178. var fieldlen;
  2179. var b;
  2180. var a;
  2181. var i;
  2182. var fields;
  2183. var namelen;
  2184. if (node === null) {
  2185. return indent + "None";
  2186. }
  2187. else if (node.prototype && node.prototype._astname !== undefined && node.prototype._isenum) {
  2188. return indent + node.prototype._astname + "()";
  2189. }
  2190. else if (node._astname !== undefined) {
  2191. namelen = spaces(node._astname.length + 1);
  2192. fields = [];
  2193. for (i = 0; i < node._fields.length; i += 2) // iter_fields
  2194. {
  2195. a = node._fields[i]; // field name
  2196. b = node._fields[i + 1](node); // field getter func
  2197. fieldlen = spaces(a.length + 1);
  2198. fields.push([a, _format(b, indent + namelen + fieldlen)]);
  2199. }
  2200. attrs = [];
  2201. for (i = 0; i < fields.length; ++i) {
  2202. field = fields[i];
  2203. attrs.push(field[0] + "=" + field[1].replace(/^\s+/, ""));
  2204. }
  2205. fieldstr = attrs.join(",\n" + indent + namelen);
  2206. return indent + node._astname + "(" + fieldstr + ")";
  2207. }
  2208. else if (goog.isArrayLike(node)) {
  2209. //Sk.debugout("arr", node.length);
  2210. elems = [];
  2211. for (i = 0; i < node.length; ++i) {
  2212. x = node[i];
  2213. elems.push(_format(x, indent + " "));
  2214. }
  2215. elemsstr = elems.join(",\n");
  2216. return indent + "[" + elemsstr.replace(/^\s+/, "") + "]";
  2217. }
  2218. else {
  2219. if (node === true) {
  2220. ret = "True";
  2221. }
  2222. else if (node === false) {
  2223. ret = "False";
  2224. }
  2225. else if (node instanceof Sk.builtin.lng) {
  2226. ret = node.tp$str().v;
  2227. }
  2228. else if (node instanceof Sk.builtin.str) {
  2229. ret = node["$r"]().v;
  2230. }
  2231. else {
  2232. ret = "" + node;
  2233. }
  2234. return indent + ret;
  2235. }
  2236. };
  2237. return _format(node, "");
  2238. };
  2239. goog.exportSymbol("Sk.astFromParse", Sk.astFromParse);
  2240. goog.exportSymbol("Sk.astDump", Sk.astDump);