statement.go 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938
  1. package parser
  2. import (
  3. "github.com/robertkrimen/otto/ast"
  4. "github.com/robertkrimen/otto/token"
  5. )
  6. func (self *_parser) parseBlockStatement() *ast.BlockStatement {
  7. node := &ast.BlockStatement{}
  8. // Find comments before the leading brace
  9. if self.mode&StoreComments != 0 {
  10. self.comments.CommentMap.AddComments(node, self.comments.FetchAll(), ast.LEADING)
  11. self.comments.Unset()
  12. }
  13. node.LeftBrace = self.expect(token.LEFT_BRACE)
  14. node.List = self.parseStatementList()
  15. if self.mode&StoreComments != 0 {
  16. self.comments.Unset()
  17. self.comments.CommentMap.AddComments(node, self.comments.FetchAll(), ast.FINAL)
  18. self.comments.AfterBlock()
  19. }
  20. node.RightBrace = self.expect(token.RIGHT_BRACE)
  21. // Find comments after the trailing brace
  22. if self.mode&StoreComments != 0 {
  23. self.comments.ResetLineBreak()
  24. self.comments.CommentMap.AddComments(node, self.comments.Fetch(), ast.TRAILING)
  25. }
  26. return node
  27. }
  28. func (self *_parser) parseEmptyStatement() ast.Statement {
  29. idx := self.expect(token.SEMICOLON)
  30. return &ast.EmptyStatement{Semicolon: idx}
  31. }
  32. func (self *_parser) parseStatementList() (list []ast.Statement) {
  33. for self.token != token.RIGHT_BRACE && self.token != token.EOF {
  34. statement := self.parseStatement()
  35. list = append(list, statement)
  36. }
  37. return
  38. }
  39. func (self *_parser) parseStatement() ast.Statement {
  40. if self.token == token.EOF {
  41. self.errorUnexpectedToken(self.token)
  42. return &ast.BadStatement{From: self.idx, To: self.idx + 1}
  43. }
  44. if self.mode&StoreComments != 0 {
  45. self.comments.ResetLineBreak()
  46. }
  47. switch self.token {
  48. case token.SEMICOLON:
  49. return self.parseEmptyStatement()
  50. case token.LEFT_BRACE:
  51. return self.parseBlockStatement()
  52. case token.IF:
  53. return self.parseIfStatement()
  54. case token.DO:
  55. statement := self.parseDoWhileStatement()
  56. self.comments.PostProcessNode(statement)
  57. return statement
  58. case token.WHILE:
  59. return self.parseWhileStatement()
  60. case token.FOR:
  61. return self.parseForOrForInStatement()
  62. case token.BREAK:
  63. return self.parseBreakStatement()
  64. case token.CONTINUE:
  65. return self.parseContinueStatement()
  66. case token.DEBUGGER:
  67. return self.parseDebuggerStatement()
  68. case token.WITH:
  69. return self.parseWithStatement()
  70. case token.VAR:
  71. return self.parseVariableStatement()
  72. case token.FUNCTION:
  73. return self.parseFunctionStatement()
  74. case token.SWITCH:
  75. return self.parseSwitchStatement()
  76. case token.RETURN:
  77. return self.parseReturnStatement()
  78. case token.THROW:
  79. return self.parseThrowStatement()
  80. case token.TRY:
  81. return self.parseTryStatement()
  82. }
  83. var comments []*ast.Comment
  84. if self.mode&StoreComments != 0 {
  85. comments = self.comments.FetchAll()
  86. }
  87. expression := self.parseExpression()
  88. if identifier, isIdentifier := expression.(*ast.Identifier); isIdentifier && self.token == token.COLON {
  89. // LabelledStatement
  90. colon := self.idx
  91. if self.mode&StoreComments != 0 {
  92. self.comments.Unset()
  93. }
  94. self.next() // :
  95. label := identifier.Name
  96. for _, value := range self.scope.labels {
  97. if label == value {
  98. self.error(identifier.Idx0(), "Label '%s' already exists", label)
  99. }
  100. }
  101. var labelComments []*ast.Comment
  102. if self.mode&StoreComments != 0 {
  103. labelComments = self.comments.FetchAll()
  104. }
  105. self.scope.labels = append(self.scope.labels, label) // Push the label
  106. statement := self.parseStatement()
  107. self.scope.labels = self.scope.labels[:len(self.scope.labels)-1] // Pop the label
  108. exp := &ast.LabelledStatement{
  109. Label: identifier,
  110. Colon: colon,
  111. Statement: statement,
  112. }
  113. if self.mode&StoreComments != 0 {
  114. self.comments.CommentMap.AddComments(exp, labelComments, ast.LEADING)
  115. }
  116. return exp
  117. }
  118. self.optionalSemicolon()
  119. statement := &ast.ExpressionStatement{
  120. Expression: expression,
  121. }
  122. if self.mode&StoreComments != 0 {
  123. self.comments.CommentMap.AddComments(statement, comments, ast.LEADING)
  124. }
  125. return statement
  126. }
  127. func (self *_parser) parseTryStatement() ast.Statement {
  128. var tryComments []*ast.Comment
  129. if self.mode&StoreComments != 0 {
  130. tryComments = self.comments.FetchAll()
  131. }
  132. node := &ast.TryStatement{
  133. Try: self.expect(token.TRY),
  134. Body: self.parseBlockStatement(),
  135. }
  136. if self.mode&StoreComments != 0 {
  137. self.comments.CommentMap.AddComments(node, tryComments, ast.LEADING)
  138. self.comments.CommentMap.AddComments(node.Body, self.comments.FetchAll(), ast.TRAILING)
  139. }
  140. if self.token == token.CATCH {
  141. catch := self.idx
  142. if self.mode&StoreComments != 0 {
  143. self.comments.Unset()
  144. }
  145. self.next()
  146. self.expect(token.LEFT_PARENTHESIS)
  147. if self.token != token.IDENTIFIER {
  148. self.expect(token.IDENTIFIER)
  149. self.nextStatement()
  150. return &ast.BadStatement{From: catch, To: self.idx}
  151. } else {
  152. identifier := self.parseIdentifier()
  153. self.expect(token.RIGHT_PARENTHESIS)
  154. node.Catch = &ast.CatchStatement{
  155. Catch: catch,
  156. Parameter: identifier,
  157. Body: self.parseBlockStatement(),
  158. }
  159. if self.mode&StoreComments != 0 {
  160. self.comments.CommentMap.AddComments(node.Catch.Body, self.comments.FetchAll(), ast.TRAILING)
  161. }
  162. }
  163. }
  164. if self.token == token.FINALLY {
  165. if self.mode&StoreComments != 0 {
  166. self.comments.Unset()
  167. }
  168. self.next()
  169. if self.mode&StoreComments != 0 {
  170. tryComments = self.comments.FetchAll()
  171. }
  172. node.Finally = self.parseBlockStatement()
  173. if self.mode&StoreComments != 0 {
  174. self.comments.CommentMap.AddComments(node.Finally, tryComments, ast.LEADING)
  175. }
  176. }
  177. if node.Catch == nil && node.Finally == nil {
  178. self.error(node.Try, "Missing catch or finally after try")
  179. return &ast.BadStatement{From: node.Try, To: node.Body.Idx1()}
  180. }
  181. return node
  182. }
  183. func (self *_parser) parseFunctionParameterList() *ast.ParameterList {
  184. opening := self.expect(token.LEFT_PARENTHESIS)
  185. if self.mode&StoreComments != 0 {
  186. self.comments.Unset()
  187. }
  188. var list []*ast.Identifier
  189. for self.token != token.RIGHT_PARENTHESIS && self.token != token.EOF {
  190. if self.token != token.IDENTIFIER {
  191. self.expect(token.IDENTIFIER)
  192. } else {
  193. identifier := self.parseIdentifier()
  194. list = append(list, identifier)
  195. }
  196. if self.token != token.RIGHT_PARENTHESIS {
  197. if self.mode&StoreComments != 0 {
  198. self.comments.Unset()
  199. }
  200. self.expect(token.COMMA)
  201. }
  202. }
  203. closing := self.expect(token.RIGHT_PARENTHESIS)
  204. return &ast.ParameterList{
  205. Opening: opening,
  206. List: list,
  207. Closing: closing,
  208. }
  209. }
  210. func (self *_parser) parseParameterList() (list []string) {
  211. for self.token != token.EOF {
  212. if self.token != token.IDENTIFIER {
  213. self.expect(token.IDENTIFIER)
  214. }
  215. list = append(list, self.literal)
  216. self.next()
  217. if self.token != token.EOF {
  218. self.expect(token.COMMA)
  219. }
  220. }
  221. return
  222. }
  223. func (self *_parser) parseFunctionStatement() *ast.FunctionStatement {
  224. var comments []*ast.Comment
  225. if self.mode&StoreComments != 0 {
  226. comments = self.comments.FetchAll()
  227. }
  228. function := &ast.FunctionStatement{
  229. Function: self.parseFunction(true),
  230. }
  231. if self.mode&StoreComments != 0 {
  232. self.comments.CommentMap.AddComments(function, comments, ast.LEADING)
  233. }
  234. return function
  235. }
  236. func (self *_parser) parseFunction(declaration bool) *ast.FunctionLiteral {
  237. node := &ast.FunctionLiteral{
  238. Function: self.expect(token.FUNCTION),
  239. }
  240. var name *ast.Identifier
  241. if self.token == token.IDENTIFIER {
  242. name = self.parseIdentifier()
  243. if declaration {
  244. self.scope.declare(&ast.FunctionDeclaration{
  245. Function: node,
  246. })
  247. }
  248. } else if declaration {
  249. // Use expect error handling
  250. self.expect(token.IDENTIFIER)
  251. }
  252. if self.mode&StoreComments != 0 {
  253. self.comments.Unset()
  254. }
  255. node.Name = name
  256. node.ParameterList = self.parseFunctionParameterList()
  257. self.parseFunctionBlock(node)
  258. node.Source = self.slice(node.Idx0(), node.Idx1())
  259. return node
  260. }
  261. func (self *_parser) parseFunctionBlock(node *ast.FunctionLiteral) {
  262. {
  263. self.openScope()
  264. inFunction := self.scope.inFunction
  265. self.scope.inFunction = true
  266. defer func() {
  267. self.scope.inFunction = inFunction
  268. self.closeScope()
  269. }()
  270. node.Body = self.parseBlockStatement()
  271. node.DeclarationList = self.scope.declarationList
  272. }
  273. }
  274. func (self *_parser) parseDebuggerStatement() ast.Statement {
  275. idx := self.expect(token.DEBUGGER)
  276. node := &ast.DebuggerStatement{
  277. Debugger: idx,
  278. }
  279. if self.mode&StoreComments != 0 {
  280. self.comments.CommentMap.AddComments(node, self.comments.FetchAll(), ast.TRAILING)
  281. }
  282. self.semicolon()
  283. return node
  284. }
  285. func (self *_parser) parseReturnStatement() ast.Statement {
  286. idx := self.expect(token.RETURN)
  287. var comments []*ast.Comment
  288. if self.mode&StoreComments != 0 {
  289. comments = self.comments.FetchAll()
  290. }
  291. if !self.scope.inFunction {
  292. self.error(idx, "Illegal return statement")
  293. self.nextStatement()
  294. return &ast.BadStatement{From: idx, To: self.idx}
  295. }
  296. node := &ast.ReturnStatement{
  297. Return: idx,
  298. }
  299. if !self.implicitSemicolon && self.token != token.SEMICOLON && self.token != token.RIGHT_BRACE && self.token != token.EOF {
  300. node.Argument = self.parseExpression()
  301. }
  302. if self.mode&StoreComments != 0 {
  303. self.comments.CommentMap.AddComments(node, comments, ast.LEADING)
  304. }
  305. self.semicolon()
  306. return node
  307. }
  308. func (self *_parser) parseThrowStatement() ast.Statement {
  309. var comments []*ast.Comment
  310. if self.mode&StoreComments != 0 {
  311. comments = self.comments.FetchAll()
  312. }
  313. idx := self.expect(token.THROW)
  314. if self.implicitSemicolon {
  315. if self.chr == -1 { // Hackish
  316. self.error(idx, "Unexpected end of input")
  317. } else {
  318. self.error(idx, "Illegal newline after throw")
  319. }
  320. self.nextStatement()
  321. return &ast.BadStatement{From: idx, To: self.idx}
  322. }
  323. node := &ast.ThrowStatement{
  324. Throw: self.idx,
  325. Argument: self.parseExpression(),
  326. }
  327. if self.mode&StoreComments != 0 {
  328. self.comments.CommentMap.AddComments(node, comments, ast.LEADING)
  329. }
  330. self.semicolon()
  331. return node
  332. }
  333. func (self *_parser) parseSwitchStatement() ast.Statement {
  334. var comments []*ast.Comment
  335. if self.mode&StoreComments != 0 {
  336. comments = self.comments.FetchAll()
  337. }
  338. self.expect(token.SWITCH)
  339. if self.mode&StoreComments != 0 {
  340. comments = append(comments, self.comments.FetchAll()...)
  341. }
  342. self.expect(token.LEFT_PARENTHESIS)
  343. node := &ast.SwitchStatement{
  344. Discriminant: self.parseExpression(),
  345. Default: -1,
  346. }
  347. self.expect(token.RIGHT_PARENTHESIS)
  348. if self.mode&StoreComments != 0 {
  349. comments = append(comments, self.comments.FetchAll()...)
  350. }
  351. self.expect(token.LEFT_BRACE)
  352. inSwitch := self.scope.inSwitch
  353. self.scope.inSwitch = true
  354. defer func() {
  355. self.scope.inSwitch = inSwitch
  356. }()
  357. for index := 0; self.token != token.EOF; index++ {
  358. if self.token == token.RIGHT_BRACE {
  359. self.next()
  360. break
  361. }
  362. clause := self.parseCaseStatement()
  363. if clause.Test == nil {
  364. if node.Default != -1 {
  365. self.error(clause.Case, "Already saw a default in switch")
  366. }
  367. node.Default = index
  368. }
  369. node.Body = append(node.Body, clause)
  370. }
  371. if self.mode&StoreComments != 0 {
  372. self.comments.CommentMap.AddComments(node, comments, ast.LEADING)
  373. }
  374. return node
  375. }
  376. func (self *_parser) parseWithStatement() ast.Statement {
  377. var comments []*ast.Comment
  378. if self.mode&StoreComments != 0 {
  379. comments = self.comments.FetchAll()
  380. }
  381. self.expect(token.WITH)
  382. var withComments []*ast.Comment
  383. if self.mode&StoreComments != 0 {
  384. withComments = self.comments.FetchAll()
  385. }
  386. self.expect(token.LEFT_PARENTHESIS)
  387. node := &ast.WithStatement{
  388. Object: self.parseExpression(),
  389. }
  390. self.expect(token.RIGHT_PARENTHESIS)
  391. if self.mode&StoreComments != 0 {
  392. self.comments.CommentMap.AddComments(node, comments, ast.LEADING)
  393. self.comments.CommentMap.AddComments(node, withComments, ast.WITH)
  394. }
  395. node.Body = self.parseStatement()
  396. return node
  397. }
  398. func (self *_parser) parseCaseStatement() *ast.CaseStatement {
  399. node := &ast.CaseStatement{
  400. Case: self.idx,
  401. }
  402. var comments []*ast.Comment
  403. if self.mode&StoreComments != 0 {
  404. comments = self.comments.FetchAll()
  405. self.comments.Unset()
  406. }
  407. if self.token == token.DEFAULT {
  408. self.next()
  409. } else {
  410. self.expect(token.CASE)
  411. node.Test = self.parseExpression()
  412. }
  413. if self.mode&StoreComments != 0 {
  414. self.comments.Unset()
  415. }
  416. self.expect(token.COLON)
  417. for {
  418. if self.token == token.EOF ||
  419. self.token == token.RIGHT_BRACE ||
  420. self.token == token.CASE ||
  421. self.token == token.DEFAULT {
  422. break
  423. }
  424. consequent := self.parseStatement()
  425. node.Consequent = append(node.Consequent, consequent)
  426. }
  427. // Link the comments to the case statement
  428. if self.mode&StoreComments != 0 {
  429. self.comments.CommentMap.AddComments(node, comments, ast.LEADING)
  430. }
  431. return node
  432. }
  433. func (self *_parser) parseIterationStatement() ast.Statement {
  434. inIteration := self.scope.inIteration
  435. self.scope.inIteration = true
  436. defer func() {
  437. self.scope.inIteration = inIteration
  438. }()
  439. return self.parseStatement()
  440. }
  441. func (self *_parser) parseForIn(into ast.Expression) *ast.ForInStatement {
  442. // Already have consumed "<into> in"
  443. source := self.parseExpression()
  444. self.expect(token.RIGHT_PARENTHESIS)
  445. body := self.parseIterationStatement()
  446. forin := &ast.ForInStatement{
  447. Into: into,
  448. Source: source,
  449. Body: body,
  450. }
  451. return forin
  452. }
  453. func (self *_parser) parseFor(initializer ast.Expression) *ast.ForStatement {
  454. // Already have consumed "<initializer> ;"
  455. var test, update ast.Expression
  456. if self.token != token.SEMICOLON {
  457. test = self.parseExpression()
  458. }
  459. if self.mode&StoreComments != 0 {
  460. self.comments.Unset()
  461. }
  462. self.expect(token.SEMICOLON)
  463. if self.token != token.RIGHT_PARENTHESIS {
  464. update = self.parseExpression()
  465. }
  466. self.expect(token.RIGHT_PARENTHESIS)
  467. body := self.parseIterationStatement()
  468. forstatement := &ast.ForStatement{
  469. Initializer: initializer,
  470. Test: test,
  471. Update: update,
  472. Body: body,
  473. }
  474. return forstatement
  475. }
  476. func (self *_parser) parseForOrForInStatement() ast.Statement {
  477. var comments []*ast.Comment
  478. if self.mode&StoreComments != 0 {
  479. comments = self.comments.FetchAll()
  480. }
  481. idx := self.expect(token.FOR)
  482. var forComments []*ast.Comment
  483. if self.mode&StoreComments != 0 {
  484. forComments = self.comments.FetchAll()
  485. }
  486. self.expect(token.LEFT_PARENTHESIS)
  487. var left []ast.Expression
  488. forIn := false
  489. if self.token != token.SEMICOLON {
  490. allowIn := self.scope.allowIn
  491. self.scope.allowIn = false
  492. if self.token == token.VAR {
  493. var_ := self.idx
  494. var varComments []*ast.Comment
  495. if self.mode&StoreComments != 0 {
  496. varComments = self.comments.FetchAll()
  497. self.comments.Unset()
  498. }
  499. self.next()
  500. list := self.parseVariableDeclarationList(var_)
  501. if len(list) == 1 && self.token == token.IN {
  502. if self.mode&StoreComments != 0 {
  503. self.comments.Unset()
  504. }
  505. self.next() // in
  506. forIn = true
  507. left = []ast.Expression{list[0]} // There is only one declaration
  508. } else {
  509. left = list
  510. }
  511. if self.mode&StoreComments != 0 {
  512. self.comments.CommentMap.AddComments(left[0], varComments, ast.LEADING)
  513. }
  514. } else {
  515. left = append(left, self.parseExpression())
  516. if self.token == token.IN {
  517. self.next()
  518. forIn = true
  519. }
  520. }
  521. self.scope.allowIn = allowIn
  522. }
  523. if forIn {
  524. switch left[0].(type) {
  525. case *ast.Identifier, *ast.DotExpression, *ast.BracketExpression, *ast.VariableExpression:
  526. // These are all acceptable
  527. default:
  528. self.error(idx, "Invalid left-hand side in for-in")
  529. self.nextStatement()
  530. return &ast.BadStatement{From: idx, To: self.idx}
  531. }
  532. forin := self.parseForIn(left[0])
  533. if self.mode&StoreComments != 0 {
  534. self.comments.CommentMap.AddComments(forin, comments, ast.LEADING)
  535. self.comments.CommentMap.AddComments(forin, forComments, ast.FOR)
  536. }
  537. return forin
  538. }
  539. if self.mode&StoreComments != 0 {
  540. self.comments.Unset()
  541. }
  542. self.expect(token.SEMICOLON)
  543. initializer := &ast.SequenceExpression{Sequence: left}
  544. forstatement := self.parseFor(initializer)
  545. if self.mode&StoreComments != 0 {
  546. self.comments.CommentMap.AddComments(forstatement, comments, ast.LEADING)
  547. self.comments.CommentMap.AddComments(forstatement, forComments, ast.FOR)
  548. }
  549. return forstatement
  550. }
  551. func (self *_parser) parseVariableStatement() *ast.VariableStatement {
  552. var comments []*ast.Comment
  553. if self.mode&StoreComments != 0 {
  554. comments = self.comments.FetchAll()
  555. }
  556. idx := self.expect(token.VAR)
  557. list := self.parseVariableDeclarationList(idx)
  558. statement := &ast.VariableStatement{
  559. Var: idx,
  560. List: list,
  561. }
  562. if self.mode&StoreComments != 0 {
  563. self.comments.CommentMap.AddComments(statement, comments, ast.LEADING)
  564. self.comments.Unset()
  565. }
  566. self.semicolon()
  567. return statement
  568. }
  569. func (self *_parser) parseDoWhileStatement() ast.Statement {
  570. inIteration := self.scope.inIteration
  571. self.scope.inIteration = true
  572. defer func() {
  573. self.scope.inIteration = inIteration
  574. }()
  575. var comments []*ast.Comment
  576. if self.mode&StoreComments != 0 {
  577. comments = self.comments.FetchAll()
  578. }
  579. self.expect(token.DO)
  580. var doComments []*ast.Comment
  581. if self.mode&StoreComments != 0 {
  582. doComments = self.comments.FetchAll()
  583. }
  584. node := &ast.DoWhileStatement{}
  585. if self.token == token.LEFT_BRACE {
  586. node.Body = self.parseBlockStatement()
  587. } else {
  588. node.Body = self.parseStatement()
  589. }
  590. self.expect(token.WHILE)
  591. var whileComments []*ast.Comment
  592. if self.mode&StoreComments != 0 {
  593. whileComments = self.comments.FetchAll()
  594. }
  595. self.expect(token.LEFT_PARENTHESIS)
  596. node.Test = self.parseExpression()
  597. self.expect(token.RIGHT_PARENTHESIS)
  598. if self.mode&StoreComments != 0 {
  599. self.comments.CommentMap.AddComments(node, comments, ast.LEADING)
  600. self.comments.CommentMap.AddComments(node, doComments, ast.DO)
  601. self.comments.CommentMap.AddComments(node, whileComments, ast.WHILE)
  602. }
  603. return node
  604. }
  605. func (self *_parser) parseWhileStatement() ast.Statement {
  606. var comments []*ast.Comment
  607. if self.mode&StoreComments != 0 {
  608. comments = self.comments.FetchAll()
  609. }
  610. self.expect(token.WHILE)
  611. var whileComments []*ast.Comment
  612. if self.mode&StoreComments != 0 {
  613. whileComments = self.comments.FetchAll()
  614. }
  615. self.expect(token.LEFT_PARENTHESIS)
  616. node := &ast.WhileStatement{
  617. Test: self.parseExpression(),
  618. }
  619. self.expect(token.RIGHT_PARENTHESIS)
  620. node.Body = self.parseIterationStatement()
  621. if self.mode&StoreComments != 0 {
  622. self.comments.CommentMap.AddComments(node, comments, ast.LEADING)
  623. self.comments.CommentMap.AddComments(node, whileComments, ast.WHILE)
  624. }
  625. return node
  626. }
  627. func (self *_parser) parseIfStatement() ast.Statement {
  628. var comments []*ast.Comment
  629. if self.mode&StoreComments != 0 {
  630. comments = self.comments.FetchAll()
  631. }
  632. self.expect(token.IF)
  633. var ifComments []*ast.Comment
  634. if self.mode&StoreComments != 0 {
  635. ifComments = self.comments.FetchAll()
  636. }
  637. self.expect(token.LEFT_PARENTHESIS)
  638. node := &ast.IfStatement{
  639. If: self.idx,
  640. Test: self.parseExpression(),
  641. }
  642. self.expect(token.RIGHT_PARENTHESIS)
  643. if self.token == token.LEFT_BRACE {
  644. node.Consequent = self.parseBlockStatement()
  645. } else {
  646. node.Consequent = self.parseStatement()
  647. }
  648. if self.token == token.ELSE {
  649. self.next()
  650. node.Alternate = self.parseStatement()
  651. }
  652. if self.mode&StoreComments != 0 {
  653. self.comments.CommentMap.AddComments(node, comments, ast.LEADING)
  654. self.comments.CommentMap.AddComments(node, ifComments, ast.IF)
  655. }
  656. return node
  657. }
  658. func (self *_parser) parseSourceElement() ast.Statement {
  659. statement := self.parseStatement()
  660. return statement
  661. }
  662. func (self *_parser) parseSourceElements() []ast.Statement {
  663. body := []ast.Statement(nil)
  664. for {
  665. if self.token != token.STRING {
  666. break
  667. }
  668. body = append(body, self.parseSourceElement())
  669. }
  670. for self.token != token.EOF {
  671. body = append(body, self.parseSourceElement())
  672. }
  673. return body
  674. }
  675. func (self *_parser) parseProgram() *ast.Program {
  676. self.openScope()
  677. defer self.closeScope()
  678. return &ast.Program{
  679. Body: self.parseSourceElements(),
  680. DeclarationList: self.scope.declarationList,
  681. File: self.file,
  682. }
  683. }
  684. func (self *_parser) parseBreakStatement() ast.Statement {
  685. var comments []*ast.Comment
  686. if self.mode&StoreComments != 0 {
  687. comments = self.comments.FetchAll()
  688. }
  689. idx := self.expect(token.BREAK)
  690. semicolon := self.implicitSemicolon
  691. if self.token == token.SEMICOLON {
  692. semicolon = true
  693. self.next()
  694. }
  695. if semicolon || self.token == token.RIGHT_BRACE {
  696. self.implicitSemicolon = false
  697. if !self.scope.inIteration && !self.scope.inSwitch {
  698. goto illegal
  699. }
  700. breakStatement := &ast.BranchStatement{
  701. Idx: idx,
  702. Token: token.BREAK,
  703. }
  704. if self.mode&StoreComments != 0 {
  705. self.comments.CommentMap.AddComments(breakStatement, comments, ast.LEADING)
  706. self.comments.CommentMap.AddComments(breakStatement, self.comments.FetchAll(), ast.TRAILING)
  707. }
  708. return breakStatement
  709. }
  710. if self.token == token.IDENTIFIER {
  711. identifier := self.parseIdentifier()
  712. if !self.scope.hasLabel(identifier.Name) {
  713. self.error(idx, "Undefined label '%s'", identifier.Name)
  714. return &ast.BadStatement{From: idx, To: identifier.Idx1()}
  715. }
  716. self.semicolon()
  717. breakStatement := &ast.BranchStatement{
  718. Idx: idx,
  719. Token: token.BREAK,
  720. Label: identifier,
  721. }
  722. if self.mode&StoreComments != 0 {
  723. self.comments.CommentMap.AddComments(breakStatement, comments, ast.LEADING)
  724. }
  725. return breakStatement
  726. }
  727. self.expect(token.IDENTIFIER)
  728. illegal:
  729. self.error(idx, "Illegal break statement")
  730. self.nextStatement()
  731. return &ast.BadStatement{From: idx, To: self.idx}
  732. }
  733. func (self *_parser) parseContinueStatement() ast.Statement {
  734. idx := self.expect(token.CONTINUE)
  735. semicolon := self.implicitSemicolon
  736. if self.token == token.SEMICOLON {
  737. semicolon = true
  738. self.next()
  739. }
  740. if semicolon || self.token == token.RIGHT_BRACE {
  741. self.implicitSemicolon = false
  742. if !self.scope.inIteration {
  743. goto illegal
  744. }
  745. return &ast.BranchStatement{
  746. Idx: idx,
  747. Token: token.CONTINUE,
  748. }
  749. }
  750. if self.token == token.IDENTIFIER {
  751. identifier := self.parseIdentifier()
  752. if !self.scope.hasLabel(identifier.Name) {
  753. self.error(idx, "Undefined label '%s'", identifier.Name)
  754. return &ast.BadStatement{From: idx, To: identifier.Idx1()}
  755. }
  756. if !self.scope.inIteration {
  757. goto illegal
  758. }
  759. self.semicolon()
  760. return &ast.BranchStatement{
  761. Idx: idx,
  762. Token: token.CONTINUE,
  763. Label: identifier,
  764. }
  765. }
  766. self.expect(token.IDENTIFIER)
  767. illegal:
  768. self.error(idx, "Illegal continue statement")
  769. self.nextStatement()
  770. return &ast.BadStatement{From: idx, To: self.idx}
  771. }
  772. // Find the next statement after an error (recover)
  773. func (self *_parser) nextStatement() {
  774. for {
  775. switch self.token {
  776. case token.BREAK, token.CONTINUE,
  777. token.FOR, token.IF, token.RETURN, token.SWITCH,
  778. token.VAR, token.DO, token.TRY, token.WITH,
  779. token.WHILE, token.THROW, token.CATCH, token.FINALLY:
  780. // Return only if parser made some progress since last
  781. // sync or if it has not reached 10 next calls without
  782. // progress. Otherwise consume at least one token to
  783. // avoid an endless parser loop
  784. if self.idx == self.recover.idx && self.recover.count < 10 {
  785. self.recover.count++
  786. return
  787. }
  788. if self.idx > self.recover.idx {
  789. self.recover.idx = self.idx
  790. self.recover.count = 0
  791. return
  792. }
  793. // Reaching here indicates a parser bug, likely an
  794. // incorrect token list in this function, but it only
  795. // leads to skipping of possibly correct code if a
  796. // previous error is present, and thus is preferred
  797. // over a non-terminating parse.
  798. case token.EOF:
  799. return
  800. }
  801. self.next()
  802. }
  803. }