expression.go 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994
  1. package parser
  2. import (
  3. "regexp"
  4. "github.com/robertkrimen/otto/ast"
  5. "github.com/robertkrimen/otto/file"
  6. "github.com/robertkrimen/otto/token"
  7. )
  8. func (p *parser) parseIdentifier() *ast.Identifier {
  9. literal := p.literal
  10. idx := p.idx
  11. if p.mode&StoreComments != 0 {
  12. p.comments.MarkComments(ast.LEADING)
  13. }
  14. p.next()
  15. exp := &ast.Identifier{
  16. Name: literal,
  17. Idx: idx,
  18. }
  19. if p.mode&StoreComments != 0 {
  20. p.comments.SetExpression(exp)
  21. }
  22. return exp
  23. }
  24. func (p *parser) parsePrimaryExpression() ast.Expression {
  25. literal := p.literal
  26. idx := p.idx
  27. switch p.token {
  28. case token.IDENTIFIER:
  29. p.next()
  30. if len(literal) > 1 {
  31. tkn, strict := token.IsKeyword(literal)
  32. if tkn == token.KEYWORD {
  33. if !strict {
  34. p.error(idx, "Unexpected reserved word")
  35. }
  36. }
  37. }
  38. return &ast.Identifier{
  39. Name: literal,
  40. Idx: idx,
  41. }
  42. case token.NULL:
  43. p.next()
  44. return &ast.NullLiteral{
  45. Idx: idx,
  46. Literal: literal,
  47. }
  48. case token.BOOLEAN:
  49. p.next()
  50. value := false
  51. switch literal {
  52. case "true":
  53. value = true
  54. case "false":
  55. value = false
  56. default:
  57. p.error(idx, "Illegal boolean literal")
  58. }
  59. return &ast.BooleanLiteral{
  60. Idx: idx,
  61. Literal: literal,
  62. Value: value,
  63. }
  64. case token.STRING:
  65. p.next()
  66. value, err := parseStringLiteral(literal[1 : len(literal)-1])
  67. if err != nil {
  68. p.error(idx, err.Error())
  69. }
  70. return &ast.StringLiteral{
  71. Idx: idx,
  72. Literal: literal,
  73. Value: value,
  74. }
  75. case token.NUMBER:
  76. p.next()
  77. value, err := parseNumberLiteral(literal)
  78. if err != nil {
  79. p.error(idx, err.Error())
  80. value = 0
  81. }
  82. return &ast.NumberLiteral{
  83. Idx: idx,
  84. Literal: literal,
  85. Value: value,
  86. }
  87. case token.SLASH, token.QUOTIENT_ASSIGN:
  88. return p.parseRegExpLiteral()
  89. case token.LEFT_BRACE:
  90. return p.parseObjectLiteral()
  91. case token.LEFT_BRACKET:
  92. return p.parseArrayLiteral()
  93. case token.LEFT_PARENTHESIS:
  94. p.expect(token.LEFT_PARENTHESIS)
  95. expression := p.parseExpression()
  96. if p.mode&StoreComments != 0 {
  97. p.comments.Unset()
  98. }
  99. p.expect(token.RIGHT_PARENTHESIS)
  100. return expression
  101. case token.THIS:
  102. p.next()
  103. return &ast.ThisExpression{
  104. Idx: idx,
  105. }
  106. case token.FUNCTION:
  107. return p.parseFunction(false)
  108. }
  109. p.errorUnexpectedToken(p.token)
  110. p.nextStatement()
  111. return &ast.BadExpression{From: idx, To: p.idx}
  112. }
  113. func (p *parser) parseRegExpLiteral() *ast.RegExpLiteral {
  114. offset := p.chrOffset - 1 // Opening slash already gotten
  115. if p.token == token.QUOTIENT_ASSIGN {
  116. offset-- // =
  117. }
  118. idx := p.idxOf(offset)
  119. pattern, err := p.scanString(offset)
  120. endOffset := p.chrOffset
  121. p.next()
  122. if err == nil {
  123. pattern = pattern[1 : len(pattern)-1]
  124. }
  125. flags := ""
  126. if p.token == token.IDENTIFIER { // gim
  127. flags = p.literal
  128. p.next()
  129. endOffset = p.chrOffset - 1
  130. }
  131. var value string
  132. // TODO 15.10
  133. // Test during parsing that this is a valid regular expression
  134. // Sorry, (?=) and (?!) are invalid (for now)
  135. pat, err := TransformRegExp(pattern)
  136. if err != nil {
  137. if pat == "" || p.mode&IgnoreRegExpErrors == 0 {
  138. p.error(idx, "Invalid regular expression: %s", err.Error())
  139. }
  140. } else {
  141. _, err = regexp.Compile(pat)
  142. if err != nil {
  143. // We should not get here, ParseRegExp should catch any errors
  144. p.error(idx, "Invalid regular expression: %s", err.Error()[22:]) // Skip redundant "parse regexp error"
  145. } else {
  146. value = pat
  147. }
  148. }
  149. literal := p.str[offset:endOffset]
  150. return &ast.RegExpLiteral{
  151. Idx: idx,
  152. Literal: literal,
  153. Pattern: pattern,
  154. Flags: flags,
  155. Value: value,
  156. }
  157. }
  158. func (p *parser) parseVariableDeclaration(declarationList *[]*ast.VariableExpression) ast.Expression {
  159. if p.token != token.IDENTIFIER {
  160. idx := p.expect(token.IDENTIFIER)
  161. p.nextStatement()
  162. return &ast.BadExpression{From: idx, To: p.idx}
  163. }
  164. literal := p.literal
  165. idx := p.idx
  166. p.next()
  167. node := &ast.VariableExpression{
  168. Name: literal,
  169. Idx: idx,
  170. }
  171. if p.mode&StoreComments != 0 {
  172. p.comments.SetExpression(node)
  173. }
  174. if declarationList != nil {
  175. *declarationList = append(*declarationList, node)
  176. }
  177. if p.token == token.ASSIGN {
  178. if p.mode&StoreComments != 0 {
  179. p.comments.Unset()
  180. }
  181. p.next()
  182. node.Initializer = p.parseAssignmentExpression()
  183. }
  184. return node
  185. }
  186. func (p *parser) parseVariableDeclarationList(idx file.Idx) []ast.Expression {
  187. var declarationList []*ast.VariableExpression // Avoid bad expressions
  188. var list []ast.Expression
  189. for {
  190. if p.mode&StoreComments != 0 {
  191. p.comments.MarkComments(ast.LEADING)
  192. }
  193. decl := p.parseVariableDeclaration(&declarationList)
  194. list = append(list, decl)
  195. if p.token != token.COMMA {
  196. break
  197. }
  198. if p.mode&StoreComments != 0 {
  199. p.comments.Unset()
  200. }
  201. p.next()
  202. }
  203. p.scope.declare(&ast.VariableDeclaration{
  204. Var: idx,
  205. List: declarationList,
  206. })
  207. return list
  208. }
  209. func (p *parser) parseObjectPropertyKey() (string, string) {
  210. idx, tkn, literal := p.idx, p.token, p.literal
  211. value := ""
  212. if p.mode&StoreComments != 0 {
  213. p.comments.MarkComments(ast.KEY)
  214. }
  215. p.next()
  216. switch tkn {
  217. case token.IDENTIFIER:
  218. value = literal
  219. case token.NUMBER:
  220. var err error
  221. _, err = parseNumberLiteral(literal)
  222. if err != nil {
  223. p.error(idx, err.Error())
  224. } else {
  225. value = literal
  226. }
  227. case token.STRING:
  228. var err error
  229. value, err = parseStringLiteral(literal[1 : len(literal)-1])
  230. if err != nil {
  231. p.error(idx, err.Error())
  232. }
  233. default:
  234. // null, false, class, etc.
  235. if matchIdentifier.MatchString(literal) {
  236. value = literal
  237. }
  238. }
  239. return literal, value
  240. }
  241. func (p *parser) parseObjectProperty() ast.Property {
  242. literal, value := p.parseObjectPropertyKey()
  243. if literal == "get" && p.token != token.COLON {
  244. idx := p.idx
  245. _, value := p.parseObjectPropertyKey()
  246. parameterList := p.parseFunctionParameterList()
  247. node := &ast.FunctionLiteral{
  248. Function: idx,
  249. ParameterList: parameterList,
  250. }
  251. p.parseFunctionBlock(node)
  252. return ast.Property{
  253. Key: value,
  254. Kind: "get",
  255. Value: node,
  256. }
  257. } else if literal == "set" && p.token != token.COLON {
  258. idx := p.idx
  259. _, value := p.parseObjectPropertyKey()
  260. parameterList := p.parseFunctionParameterList()
  261. node := &ast.FunctionLiteral{
  262. Function: idx,
  263. ParameterList: parameterList,
  264. }
  265. p.parseFunctionBlock(node)
  266. return ast.Property{
  267. Key: value,
  268. Kind: "set",
  269. Value: node,
  270. }
  271. }
  272. if p.mode&StoreComments != 0 {
  273. p.comments.MarkComments(ast.COLON)
  274. }
  275. p.expect(token.COLON)
  276. exp := ast.Property{
  277. Key: value,
  278. Kind: "value",
  279. Value: p.parseAssignmentExpression(),
  280. }
  281. if p.mode&StoreComments != 0 {
  282. p.comments.SetExpression(exp.Value)
  283. }
  284. return exp
  285. }
  286. func (p *parser) parseObjectLiteral() ast.Expression {
  287. var value []ast.Property
  288. idx0 := p.expect(token.LEFT_BRACE)
  289. for p.token != token.RIGHT_BRACE && p.token != token.EOF {
  290. value = append(value, p.parseObjectProperty())
  291. if p.token == token.COMMA {
  292. if p.mode&StoreComments != 0 {
  293. p.comments.Unset()
  294. }
  295. p.next()
  296. continue
  297. }
  298. }
  299. if p.mode&StoreComments != 0 {
  300. p.comments.MarkComments(ast.FINAL)
  301. }
  302. idx1 := p.expect(token.RIGHT_BRACE)
  303. return &ast.ObjectLiteral{
  304. LeftBrace: idx0,
  305. RightBrace: idx1,
  306. Value: value,
  307. }
  308. }
  309. func (p *parser) parseArrayLiteral() ast.Expression {
  310. idx0 := p.expect(token.LEFT_BRACKET)
  311. var value []ast.Expression
  312. for p.token != token.RIGHT_BRACKET && p.token != token.EOF {
  313. if p.token == token.COMMA {
  314. // This kind of comment requires a special empty expression node.
  315. empty := &ast.EmptyExpression{Begin: p.idx, End: p.idx}
  316. if p.mode&StoreComments != 0 {
  317. p.comments.SetExpression(empty)
  318. p.comments.Unset()
  319. }
  320. value = append(value, empty)
  321. p.next()
  322. continue
  323. }
  324. exp := p.parseAssignmentExpression()
  325. value = append(value, exp)
  326. if p.token != token.RIGHT_BRACKET {
  327. if p.mode&StoreComments != 0 {
  328. p.comments.Unset()
  329. }
  330. p.expect(token.COMMA)
  331. }
  332. }
  333. if p.mode&StoreComments != 0 {
  334. p.comments.MarkComments(ast.FINAL)
  335. }
  336. idx1 := p.expect(token.RIGHT_BRACKET)
  337. return &ast.ArrayLiteral{
  338. LeftBracket: idx0,
  339. RightBracket: idx1,
  340. Value: value,
  341. }
  342. }
  343. func (p *parser) parseArgumentList() (argumentList []ast.Expression, idx0, idx1 file.Idx) { //nolint: nonamedreturns
  344. if p.mode&StoreComments != 0 {
  345. p.comments.Unset()
  346. }
  347. idx0 = p.expect(token.LEFT_PARENTHESIS)
  348. if p.token != token.RIGHT_PARENTHESIS {
  349. for {
  350. exp := p.parseAssignmentExpression()
  351. if p.mode&StoreComments != 0 {
  352. p.comments.SetExpression(exp)
  353. }
  354. argumentList = append(argumentList, exp)
  355. if p.token != token.COMMA {
  356. break
  357. }
  358. if p.mode&StoreComments != 0 {
  359. p.comments.Unset()
  360. }
  361. p.next()
  362. }
  363. }
  364. if p.mode&StoreComments != 0 {
  365. p.comments.Unset()
  366. }
  367. idx1 = p.expect(token.RIGHT_PARENTHESIS)
  368. return
  369. }
  370. func (p *parser) parseCallExpression(left ast.Expression) ast.Expression {
  371. argumentList, idx0, idx1 := p.parseArgumentList()
  372. exp := &ast.CallExpression{
  373. Callee: left,
  374. LeftParenthesis: idx0,
  375. ArgumentList: argumentList,
  376. RightParenthesis: idx1,
  377. }
  378. if p.mode&StoreComments != 0 {
  379. p.comments.SetExpression(exp)
  380. }
  381. return exp
  382. }
  383. func (p *parser) parseDotMember(left ast.Expression) ast.Expression {
  384. period := p.expect(token.PERIOD)
  385. literal := p.literal
  386. idx := p.idx
  387. if !matchIdentifier.MatchString(literal) {
  388. p.expect(token.IDENTIFIER)
  389. p.nextStatement()
  390. return &ast.BadExpression{From: period, To: p.idx}
  391. }
  392. p.next()
  393. return &ast.DotExpression{
  394. Left: left,
  395. Identifier: &ast.Identifier{
  396. Idx: idx,
  397. Name: literal,
  398. },
  399. }
  400. }
  401. func (p *parser) parseBracketMember(left ast.Expression) ast.Expression {
  402. idx0 := p.expect(token.LEFT_BRACKET)
  403. member := p.parseExpression()
  404. idx1 := p.expect(token.RIGHT_BRACKET)
  405. return &ast.BracketExpression{
  406. LeftBracket: idx0,
  407. Left: left,
  408. Member: member,
  409. RightBracket: idx1,
  410. }
  411. }
  412. func (p *parser) parseNewExpression() ast.Expression {
  413. idx := p.expect(token.NEW)
  414. callee := p.parseLeftHandSideExpression()
  415. node := &ast.NewExpression{
  416. New: idx,
  417. Callee: callee,
  418. }
  419. if p.token == token.LEFT_PARENTHESIS {
  420. argumentList, idx0, idx1 := p.parseArgumentList()
  421. node.ArgumentList = argumentList
  422. node.LeftParenthesis = idx0
  423. node.RightParenthesis = idx1
  424. }
  425. if p.mode&StoreComments != 0 {
  426. p.comments.SetExpression(node)
  427. }
  428. return node
  429. }
  430. func (p *parser) parseLeftHandSideExpression() ast.Expression {
  431. var left ast.Expression
  432. if p.token == token.NEW {
  433. left = p.parseNewExpression()
  434. } else {
  435. if p.mode&StoreComments != 0 {
  436. p.comments.MarkComments(ast.LEADING)
  437. p.comments.MarkPrimary()
  438. }
  439. left = p.parsePrimaryExpression()
  440. }
  441. if p.mode&StoreComments != 0 {
  442. p.comments.SetExpression(left)
  443. }
  444. for {
  445. switch p.token {
  446. case token.PERIOD:
  447. left = p.parseDotMember(left)
  448. case token.LEFT_BRACKET:
  449. left = p.parseBracketMember(left)
  450. default:
  451. return left
  452. }
  453. }
  454. }
  455. func (p *parser) parseLeftHandSideExpressionAllowCall() ast.Expression {
  456. allowIn := p.scope.allowIn
  457. p.scope.allowIn = true
  458. defer func() {
  459. p.scope.allowIn = allowIn
  460. }()
  461. var left ast.Expression
  462. if p.token == token.NEW {
  463. var newComments []*ast.Comment
  464. if p.mode&StoreComments != 0 {
  465. newComments = p.comments.FetchAll()
  466. p.comments.MarkComments(ast.LEADING)
  467. p.comments.MarkPrimary()
  468. }
  469. left = p.parseNewExpression()
  470. if p.mode&StoreComments != 0 {
  471. p.comments.CommentMap.AddComments(left, newComments, ast.LEADING)
  472. }
  473. } else {
  474. if p.mode&StoreComments != 0 {
  475. p.comments.MarkComments(ast.LEADING)
  476. p.comments.MarkPrimary()
  477. }
  478. left = p.parsePrimaryExpression()
  479. }
  480. if p.mode&StoreComments != 0 {
  481. p.comments.SetExpression(left)
  482. }
  483. for {
  484. switch p.token {
  485. case token.PERIOD:
  486. left = p.parseDotMember(left)
  487. case token.LEFT_BRACKET:
  488. left = p.parseBracketMember(left)
  489. case token.LEFT_PARENTHESIS:
  490. left = p.parseCallExpression(left)
  491. default:
  492. return left
  493. }
  494. }
  495. }
  496. func (p *parser) parsePostfixExpression() ast.Expression {
  497. operand := p.parseLeftHandSideExpressionAllowCall()
  498. switch p.token {
  499. case token.INCREMENT, token.DECREMENT:
  500. // Make sure there is no line terminator here
  501. if p.implicitSemicolon {
  502. break
  503. }
  504. tkn := p.token
  505. idx := p.idx
  506. if p.mode&StoreComments != 0 {
  507. p.comments.Unset()
  508. }
  509. p.next()
  510. switch operand.(type) {
  511. case *ast.Identifier, *ast.DotExpression, *ast.BracketExpression:
  512. default:
  513. p.error(idx, "invalid left-hand side in assignment")
  514. p.nextStatement()
  515. return &ast.BadExpression{From: idx, To: p.idx}
  516. }
  517. exp := &ast.UnaryExpression{
  518. Operator: tkn,
  519. Idx: idx,
  520. Operand: operand,
  521. Postfix: true,
  522. }
  523. if p.mode&StoreComments != 0 {
  524. p.comments.SetExpression(exp)
  525. }
  526. return exp
  527. }
  528. return operand
  529. }
  530. func (p *parser) parseUnaryExpression() ast.Expression {
  531. switch p.token {
  532. case token.PLUS, token.MINUS, token.NOT, token.BITWISE_NOT:
  533. fallthrough
  534. case token.DELETE, token.VOID, token.TYPEOF:
  535. tkn := p.token
  536. idx := p.idx
  537. if p.mode&StoreComments != 0 {
  538. p.comments.Unset()
  539. }
  540. p.next()
  541. return &ast.UnaryExpression{
  542. Operator: tkn,
  543. Idx: idx,
  544. Operand: p.parseUnaryExpression(),
  545. }
  546. case token.INCREMENT, token.DECREMENT:
  547. tkn := p.token
  548. idx := p.idx
  549. if p.mode&StoreComments != 0 {
  550. p.comments.Unset()
  551. }
  552. p.next()
  553. operand := p.parseUnaryExpression()
  554. switch operand.(type) {
  555. case *ast.Identifier, *ast.DotExpression, *ast.BracketExpression:
  556. default:
  557. p.error(idx, "invalid left-hand side in assignment")
  558. p.nextStatement()
  559. return &ast.BadExpression{From: idx, To: p.idx}
  560. }
  561. return &ast.UnaryExpression{
  562. Operator: tkn,
  563. Idx: idx,
  564. Operand: operand,
  565. }
  566. }
  567. return p.parsePostfixExpression()
  568. }
  569. func (p *parser) parseMultiplicativeExpression() ast.Expression {
  570. next := p.parseUnaryExpression
  571. left := next()
  572. for p.token == token.MULTIPLY || p.token == token.SLASH ||
  573. p.token == token.REMAINDER {
  574. tkn := p.token
  575. if p.mode&StoreComments != 0 {
  576. p.comments.Unset()
  577. }
  578. p.next()
  579. left = &ast.BinaryExpression{
  580. Operator: tkn,
  581. Left: left,
  582. Right: next(),
  583. }
  584. }
  585. return left
  586. }
  587. func (p *parser) parseAdditiveExpression() ast.Expression {
  588. next := p.parseMultiplicativeExpression
  589. left := next()
  590. for p.token == token.PLUS || p.token == token.MINUS {
  591. tkn := p.token
  592. if p.mode&StoreComments != 0 {
  593. p.comments.Unset()
  594. }
  595. p.next()
  596. left = &ast.BinaryExpression{
  597. Operator: tkn,
  598. Left: left,
  599. Right: next(),
  600. }
  601. }
  602. return left
  603. }
  604. func (p *parser) parseShiftExpression() ast.Expression {
  605. next := p.parseAdditiveExpression
  606. left := next()
  607. for p.token == token.SHIFT_LEFT || p.token == token.SHIFT_RIGHT ||
  608. p.token == token.UNSIGNED_SHIFT_RIGHT {
  609. tkn := p.token
  610. if p.mode&StoreComments != 0 {
  611. p.comments.Unset()
  612. }
  613. p.next()
  614. left = &ast.BinaryExpression{
  615. Operator: tkn,
  616. Left: left,
  617. Right: next(),
  618. }
  619. }
  620. return left
  621. }
  622. func (p *parser) parseRelationalExpression() ast.Expression {
  623. next := p.parseShiftExpression
  624. left := next()
  625. allowIn := p.scope.allowIn
  626. p.scope.allowIn = true
  627. defer func() {
  628. p.scope.allowIn = allowIn
  629. }()
  630. switch p.token {
  631. case token.LESS, token.LESS_OR_EQUAL, token.GREATER, token.GREATER_OR_EQUAL:
  632. tkn := p.token
  633. if p.mode&StoreComments != 0 {
  634. p.comments.Unset()
  635. }
  636. p.next()
  637. exp := &ast.BinaryExpression{
  638. Operator: tkn,
  639. Left: left,
  640. Right: p.parseRelationalExpression(),
  641. Comparison: true,
  642. }
  643. return exp
  644. case token.INSTANCEOF:
  645. tkn := p.token
  646. if p.mode&StoreComments != 0 {
  647. p.comments.Unset()
  648. }
  649. p.next()
  650. exp := &ast.BinaryExpression{
  651. Operator: tkn,
  652. Left: left,
  653. Right: p.parseRelationalExpression(),
  654. }
  655. return exp
  656. case token.IN:
  657. if !allowIn {
  658. return left
  659. }
  660. tkn := p.token
  661. if p.mode&StoreComments != 0 {
  662. p.comments.Unset()
  663. }
  664. p.next()
  665. exp := &ast.BinaryExpression{
  666. Operator: tkn,
  667. Left: left,
  668. Right: p.parseRelationalExpression(),
  669. }
  670. return exp
  671. }
  672. return left
  673. }
  674. func (p *parser) parseEqualityExpression() ast.Expression {
  675. next := p.parseRelationalExpression
  676. left := next()
  677. for p.token == token.EQUAL || p.token == token.NOT_EQUAL ||
  678. p.token == token.STRICT_EQUAL || p.token == token.STRICT_NOT_EQUAL {
  679. tkn := p.token
  680. if p.mode&StoreComments != 0 {
  681. p.comments.Unset()
  682. }
  683. p.next()
  684. left = &ast.BinaryExpression{
  685. Operator: tkn,
  686. Left: left,
  687. Right: next(),
  688. Comparison: true,
  689. }
  690. }
  691. return left
  692. }
  693. func (p *parser) parseBitwiseAndExpression() ast.Expression {
  694. next := p.parseEqualityExpression
  695. left := next()
  696. for p.token == token.AND {
  697. if p.mode&StoreComments != 0 {
  698. p.comments.Unset()
  699. }
  700. tkn := p.token
  701. p.next()
  702. left = &ast.BinaryExpression{
  703. Operator: tkn,
  704. Left: left,
  705. Right: next(),
  706. }
  707. }
  708. return left
  709. }
  710. func (p *parser) parseBitwiseExclusiveOrExpression() ast.Expression {
  711. next := p.parseBitwiseAndExpression
  712. left := next()
  713. for p.token == token.EXCLUSIVE_OR {
  714. if p.mode&StoreComments != 0 {
  715. p.comments.Unset()
  716. }
  717. tkn := p.token
  718. p.next()
  719. left = &ast.BinaryExpression{
  720. Operator: tkn,
  721. Left: left,
  722. Right: next(),
  723. }
  724. }
  725. return left
  726. }
  727. func (p *parser) parseBitwiseOrExpression() ast.Expression {
  728. next := p.parseBitwiseExclusiveOrExpression
  729. left := next()
  730. for p.token == token.OR {
  731. if p.mode&StoreComments != 0 {
  732. p.comments.Unset()
  733. }
  734. tkn := p.token
  735. p.next()
  736. left = &ast.BinaryExpression{
  737. Operator: tkn,
  738. Left: left,
  739. Right: next(),
  740. }
  741. }
  742. return left
  743. }
  744. func (p *parser) parseLogicalAndExpression() ast.Expression {
  745. next := p.parseBitwiseOrExpression
  746. left := next()
  747. for p.token == token.LOGICAL_AND {
  748. if p.mode&StoreComments != 0 {
  749. p.comments.Unset()
  750. }
  751. tkn := p.token
  752. p.next()
  753. left = &ast.BinaryExpression{
  754. Operator: tkn,
  755. Left: left,
  756. Right: next(),
  757. }
  758. }
  759. return left
  760. }
  761. func (p *parser) parseLogicalOrExpression() ast.Expression {
  762. next := p.parseLogicalAndExpression
  763. left := next()
  764. for p.token == token.LOGICAL_OR {
  765. if p.mode&StoreComments != 0 {
  766. p.comments.Unset()
  767. }
  768. tkn := p.token
  769. p.next()
  770. left = &ast.BinaryExpression{
  771. Operator: tkn,
  772. Left: left,
  773. Right: next(),
  774. }
  775. }
  776. return left
  777. }
  778. func (p *parser) parseConditionalExpression() ast.Expression {
  779. left := p.parseLogicalOrExpression()
  780. if p.token == token.QUESTION_MARK {
  781. if p.mode&StoreComments != 0 {
  782. p.comments.Unset()
  783. }
  784. p.next()
  785. consequent := p.parseAssignmentExpression()
  786. if p.mode&StoreComments != 0 {
  787. p.comments.Unset()
  788. }
  789. p.expect(token.COLON)
  790. exp := &ast.ConditionalExpression{
  791. Test: left,
  792. Consequent: consequent,
  793. Alternate: p.parseAssignmentExpression(),
  794. }
  795. return exp
  796. }
  797. return left
  798. }
  799. func (p *parser) parseAssignmentExpression() ast.Expression {
  800. left := p.parseConditionalExpression()
  801. var operator token.Token
  802. switch p.token {
  803. case token.ASSIGN:
  804. operator = p.token
  805. case token.ADD_ASSIGN:
  806. operator = token.PLUS
  807. case token.SUBTRACT_ASSIGN:
  808. operator = token.MINUS
  809. case token.MULTIPLY_ASSIGN:
  810. operator = token.MULTIPLY
  811. case token.QUOTIENT_ASSIGN:
  812. operator = token.SLASH
  813. case token.REMAINDER_ASSIGN:
  814. operator = token.REMAINDER
  815. case token.AND_ASSIGN:
  816. operator = token.AND
  817. case token.AND_NOT_ASSIGN:
  818. operator = token.AND_NOT
  819. case token.OR_ASSIGN:
  820. operator = token.OR
  821. case token.EXCLUSIVE_OR_ASSIGN:
  822. operator = token.EXCLUSIVE_OR
  823. case token.SHIFT_LEFT_ASSIGN:
  824. operator = token.SHIFT_LEFT
  825. case token.SHIFT_RIGHT_ASSIGN:
  826. operator = token.SHIFT_RIGHT
  827. case token.UNSIGNED_SHIFT_RIGHT_ASSIGN:
  828. operator = token.UNSIGNED_SHIFT_RIGHT
  829. }
  830. if operator != 0 {
  831. idx := p.idx
  832. if p.mode&StoreComments != 0 {
  833. p.comments.Unset()
  834. }
  835. p.next()
  836. switch left.(type) {
  837. case *ast.Identifier, *ast.DotExpression, *ast.BracketExpression:
  838. default:
  839. p.error(left.Idx0(), "invalid left-hand side in assignment")
  840. p.nextStatement()
  841. return &ast.BadExpression{From: idx, To: p.idx}
  842. }
  843. exp := &ast.AssignExpression{
  844. Left: left,
  845. Operator: operator,
  846. Right: p.parseAssignmentExpression(),
  847. }
  848. if p.mode&StoreComments != 0 {
  849. p.comments.SetExpression(exp)
  850. }
  851. return exp
  852. }
  853. return left
  854. }
  855. func (p *parser) parseExpression() ast.Expression {
  856. next := p.parseAssignmentExpression
  857. left := next()
  858. if p.token == token.COMMA {
  859. sequence := []ast.Expression{left}
  860. for {
  861. if p.token != token.COMMA {
  862. break
  863. }
  864. p.next()
  865. sequence = append(sequence, next())
  866. }
  867. return &ast.SequenceExpression{
  868. Sequence: sequence,
  869. }
  870. }
  871. return left
  872. }