expression.go 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992
  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. endOffset = p.chrOffset
  129. p.next()
  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. for p.token != token.RIGHT_PARENTHESIS {
  349. exp := p.parseAssignmentExpression()
  350. if p.mode&StoreComments != 0 {
  351. p.comments.SetExpression(exp)
  352. }
  353. argumentList = append(argumentList, exp)
  354. if p.token != token.COMMA {
  355. break
  356. }
  357. if p.mode&StoreComments != 0 {
  358. p.comments.Unset()
  359. }
  360. p.next()
  361. }
  362. if p.mode&StoreComments != 0 {
  363. p.comments.Unset()
  364. }
  365. idx1 = p.expect(token.RIGHT_PARENTHESIS)
  366. return
  367. }
  368. func (p *parser) parseCallExpression(left ast.Expression) ast.Expression {
  369. argumentList, idx0, idx1 := p.parseArgumentList()
  370. exp := &ast.CallExpression{
  371. Callee: left,
  372. LeftParenthesis: idx0,
  373. ArgumentList: argumentList,
  374. RightParenthesis: idx1,
  375. }
  376. if p.mode&StoreComments != 0 {
  377. p.comments.SetExpression(exp)
  378. }
  379. return exp
  380. }
  381. func (p *parser) parseDotMember(left ast.Expression) ast.Expression {
  382. period := p.expect(token.PERIOD)
  383. literal := p.literal
  384. idx := p.idx
  385. if !matchIdentifier.MatchString(literal) {
  386. p.expect(token.IDENTIFIER)
  387. p.nextStatement()
  388. return &ast.BadExpression{From: period, To: p.idx}
  389. }
  390. p.next()
  391. return &ast.DotExpression{
  392. Left: left,
  393. Identifier: &ast.Identifier{
  394. Idx: idx,
  395. Name: literal,
  396. },
  397. }
  398. }
  399. func (p *parser) parseBracketMember(left ast.Expression) ast.Expression {
  400. idx0 := p.expect(token.LEFT_BRACKET)
  401. member := p.parseExpression()
  402. idx1 := p.expect(token.RIGHT_BRACKET)
  403. return &ast.BracketExpression{
  404. LeftBracket: idx0,
  405. Left: left,
  406. Member: member,
  407. RightBracket: idx1,
  408. }
  409. }
  410. func (p *parser) parseNewExpression() ast.Expression {
  411. idx := p.expect(token.NEW)
  412. callee := p.parseLeftHandSideExpression()
  413. node := &ast.NewExpression{
  414. New: idx,
  415. Callee: callee,
  416. }
  417. if p.token == token.LEFT_PARENTHESIS {
  418. argumentList, idx0, idx1 := p.parseArgumentList()
  419. node.ArgumentList = argumentList
  420. node.LeftParenthesis = idx0
  421. node.RightParenthesis = idx1
  422. }
  423. if p.mode&StoreComments != 0 {
  424. p.comments.SetExpression(node)
  425. }
  426. return node
  427. }
  428. func (p *parser) parseLeftHandSideExpression() ast.Expression {
  429. var left ast.Expression
  430. if p.token == token.NEW {
  431. left = p.parseNewExpression()
  432. } else {
  433. if p.mode&StoreComments != 0 {
  434. p.comments.MarkComments(ast.LEADING)
  435. p.comments.MarkPrimary()
  436. }
  437. left = p.parsePrimaryExpression()
  438. }
  439. if p.mode&StoreComments != 0 {
  440. p.comments.SetExpression(left)
  441. }
  442. for {
  443. switch p.token {
  444. case token.PERIOD:
  445. left = p.parseDotMember(left)
  446. case token.LEFT_BRACKET:
  447. left = p.parseBracketMember(left)
  448. default:
  449. return left
  450. }
  451. }
  452. }
  453. func (p *parser) parseLeftHandSideExpressionAllowCall() ast.Expression {
  454. allowIn := p.scope.allowIn
  455. p.scope.allowIn = true
  456. defer func() {
  457. p.scope.allowIn = allowIn
  458. }()
  459. var left ast.Expression
  460. if p.token == token.NEW {
  461. var newComments []*ast.Comment
  462. if p.mode&StoreComments != 0 {
  463. newComments = p.comments.FetchAll()
  464. p.comments.MarkComments(ast.LEADING)
  465. p.comments.MarkPrimary()
  466. }
  467. left = p.parseNewExpression()
  468. if p.mode&StoreComments != 0 {
  469. p.comments.CommentMap.AddComments(left, newComments, ast.LEADING)
  470. }
  471. } else {
  472. if p.mode&StoreComments != 0 {
  473. p.comments.MarkComments(ast.LEADING)
  474. p.comments.MarkPrimary()
  475. }
  476. left = p.parsePrimaryExpression()
  477. }
  478. if p.mode&StoreComments != 0 {
  479. p.comments.SetExpression(left)
  480. }
  481. for {
  482. switch p.token {
  483. case token.PERIOD:
  484. left = p.parseDotMember(left)
  485. case token.LEFT_BRACKET:
  486. left = p.parseBracketMember(left)
  487. case token.LEFT_PARENTHESIS:
  488. left = p.parseCallExpression(left)
  489. default:
  490. return left
  491. }
  492. }
  493. }
  494. func (p *parser) parsePostfixExpression() ast.Expression {
  495. operand := p.parseLeftHandSideExpressionAllowCall()
  496. switch p.token {
  497. case token.INCREMENT, token.DECREMENT:
  498. // Make sure there is no line terminator here
  499. if p.implicitSemicolon {
  500. break
  501. }
  502. tkn := p.token
  503. idx := p.idx
  504. if p.mode&StoreComments != 0 {
  505. p.comments.Unset()
  506. }
  507. p.next()
  508. switch operand.(type) {
  509. case *ast.Identifier, *ast.DotExpression, *ast.BracketExpression:
  510. default:
  511. p.error(idx, "invalid left-hand side in assignment")
  512. p.nextStatement()
  513. return &ast.BadExpression{From: idx, To: p.idx}
  514. }
  515. exp := &ast.UnaryExpression{
  516. Operator: tkn,
  517. Idx: idx,
  518. Operand: operand,
  519. Postfix: true,
  520. }
  521. if p.mode&StoreComments != 0 {
  522. p.comments.SetExpression(exp)
  523. }
  524. return exp
  525. }
  526. return operand
  527. }
  528. func (p *parser) parseUnaryExpression() ast.Expression {
  529. switch p.token {
  530. case token.PLUS, token.MINUS, token.NOT, token.BITWISE_NOT:
  531. fallthrough
  532. case token.DELETE, token.VOID, token.TYPEOF:
  533. tkn := p.token
  534. idx := p.idx
  535. if p.mode&StoreComments != 0 {
  536. p.comments.Unset()
  537. }
  538. p.next()
  539. return &ast.UnaryExpression{
  540. Operator: tkn,
  541. Idx: idx,
  542. Operand: p.parseUnaryExpression(),
  543. }
  544. case token.INCREMENT, token.DECREMENT:
  545. tkn := p.token
  546. idx := p.idx
  547. if p.mode&StoreComments != 0 {
  548. p.comments.Unset()
  549. }
  550. p.next()
  551. operand := p.parseUnaryExpression()
  552. switch operand.(type) {
  553. case *ast.Identifier, *ast.DotExpression, *ast.BracketExpression:
  554. default:
  555. p.error(idx, "invalid left-hand side in assignment")
  556. p.nextStatement()
  557. return &ast.BadExpression{From: idx, To: p.idx}
  558. }
  559. return &ast.UnaryExpression{
  560. Operator: tkn,
  561. Idx: idx,
  562. Operand: operand,
  563. }
  564. }
  565. return p.parsePostfixExpression()
  566. }
  567. func (p *parser) parseMultiplicativeExpression() ast.Expression {
  568. next := p.parseUnaryExpression
  569. left := next()
  570. for p.token == token.MULTIPLY || p.token == token.SLASH ||
  571. p.token == token.REMAINDER {
  572. tkn := p.token
  573. if p.mode&StoreComments != 0 {
  574. p.comments.Unset()
  575. }
  576. p.next()
  577. left = &ast.BinaryExpression{
  578. Operator: tkn,
  579. Left: left,
  580. Right: next(),
  581. }
  582. }
  583. return left
  584. }
  585. func (p *parser) parseAdditiveExpression() ast.Expression {
  586. next := p.parseMultiplicativeExpression
  587. left := next()
  588. for p.token == token.PLUS || p.token == token.MINUS {
  589. tkn := p.token
  590. if p.mode&StoreComments != 0 {
  591. p.comments.Unset()
  592. }
  593. p.next()
  594. left = &ast.BinaryExpression{
  595. Operator: tkn,
  596. Left: left,
  597. Right: next(),
  598. }
  599. }
  600. return left
  601. }
  602. func (p *parser) parseShiftExpression() ast.Expression {
  603. next := p.parseAdditiveExpression
  604. left := next()
  605. for p.token == token.SHIFT_LEFT || p.token == token.SHIFT_RIGHT ||
  606. p.token == token.UNSIGNED_SHIFT_RIGHT {
  607. tkn := p.token
  608. if p.mode&StoreComments != 0 {
  609. p.comments.Unset()
  610. }
  611. p.next()
  612. left = &ast.BinaryExpression{
  613. Operator: tkn,
  614. Left: left,
  615. Right: next(),
  616. }
  617. }
  618. return left
  619. }
  620. func (p *parser) parseRelationalExpression() ast.Expression {
  621. next := p.parseShiftExpression
  622. left := next()
  623. allowIn := p.scope.allowIn
  624. p.scope.allowIn = true
  625. defer func() {
  626. p.scope.allowIn = allowIn
  627. }()
  628. switch p.token {
  629. case token.LESS, token.LESS_OR_EQUAL, token.GREATER, token.GREATER_OR_EQUAL:
  630. tkn := p.token
  631. if p.mode&StoreComments != 0 {
  632. p.comments.Unset()
  633. }
  634. p.next()
  635. exp := &ast.BinaryExpression{
  636. Operator: tkn,
  637. Left: left,
  638. Right: p.parseRelationalExpression(),
  639. Comparison: true,
  640. }
  641. return exp
  642. case token.INSTANCEOF:
  643. tkn := p.token
  644. if p.mode&StoreComments != 0 {
  645. p.comments.Unset()
  646. }
  647. p.next()
  648. exp := &ast.BinaryExpression{
  649. Operator: tkn,
  650. Left: left,
  651. Right: p.parseRelationalExpression(),
  652. }
  653. return exp
  654. case token.IN:
  655. if !allowIn {
  656. return left
  657. }
  658. tkn := p.token
  659. if p.mode&StoreComments != 0 {
  660. p.comments.Unset()
  661. }
  662. p.next()
  663. exp := &ast.BinaryExpression{
  664. Operator: tkn,
  665. Left: left,
  666. Right: p.parseRelationalExpression(),
  667. }
  668. return exp
  669. }
  670. return left
  671. }
  672. func (p *parser) parseEqualityExpression() ast.Expression {
  673. next := p.parseRelationalExpression
  674. left := next()
  675. for p.token == token.EQUAL || p.token == token.NOT_EQUAL ||
  676. p.token == token.STRICT_EQUAL || p.token == token.STRICT_NOT_EQUAL {
  677. tkn := p.token
  678. if p.mode&StoreComments != 0 {
  679. p.comments.Unset()
  680. }
  681. p.next()
  682. left = &ast.BinaryExpression{
  683. Operator: tkn,
  684. Left: left,
  685. Right: next(),
  686. Comparison: true,
  687. }
  688. }
  689. return left
  690. }
  691. func (p *parser) parseBitwiseAndExpression() ast.Expression {
  692. next := p.parseEqualityExpression
  693. left := next()
  694. for p.token == token.AND {
  695. if p.mode&StoreComments != 0 {
  696. p.comments.Unset()
  697. }
  698. tkn := p.token
  699. p.next()
  700. left = &ast.BinaryExpression{
  701. Operator: tkn,
  702. Left: left,
  703. Right: next(),
  704. }
  705. }
  706. return left
  707. }
  708. func (p *parser) parseBitwiseExclusiveOrExpression() ast.Expression {
  709. next := p.parseBitwiseAndExpression
  710. left := next()
  711. for p.token == token.EXCLUSIVE_OR {
  712. if p.mode&StoreComments != 0 {
  713. p.comments.Unset()
  714. }
  715. tkn := p.token
  716. p.next()
  717. left = &ast.BinaryExpression{
  718. Operator: tkn,
  719. Left: left,
  720. Right: next(),
  721. }
  722. }
  723. return left
  724. }
  725. func (p *parser) parseBitwiseOrExpression() ast.Expression {
  726. next := p.parseBitwiseExclusiveOrExpression
  727. left := next()
  728. for p.token == token.OR {
  729. if p.mode&StoreComments != 0 {
  730. p.comments.Unset()
  731. }
  732. tkn := p.token
  733. p.next()
  734. left = &ast.BinaryExpression{
  735. Operator: tkn,
  736. Left: left,
  737. Right: next(),
  738. }
  739. }
  740. return left
  741. }
  742. func (p *parser) parseLogicalAndExpression() ast.Expression {
  743. next := p.parseBitwiseOrExpression
  744. left := next()
  745. for p.token == token.LOGICAL_AND {
  746. if p.mode&StoreComments != 0 {
  747. p.comments.Unset()
  748. }
  749. tkn := p.token
  750. p.next()
  751. left = &ast.BinaryExpression{
  752. Operator: tkn,
  753. Left: left,
  754. Right: next(),
  755. }
  756. }
  757. return left
  758. }
  759. func (p *parser) parseLogicalOrExpression() ast.Expression {
  760. next := p.parseLogicalAndExpression
  761. left := next()
  762. for p.token == token.LOGICAL_OR {
  763. if p.mode&StoreComments != 0 {
  764. p.comments.Unset()
  765. }
  766. tkn := p.token
  767. p.next()
  768. left = &ast.BinaryExpression{
  769. Operator: tkn,
  770. Left: left,
  771. Right: next(),
  772. }
  773. }
  774. return left
  775. }
  776. func (p *parser) parseConditionalExpression() ast.Expression {
  777. left := p.parseLogicalOrExpression()
  778. if p.token == token.QUESTION_MARK {
  779. if p.mode&StoreComments != 0 {
  780. p.comments.Unset()
  781. }
  782. p.next()
  783. consequent := p.parseAssignmentExpression()
  784. if p.mode&StoreComments != 0 {
  785. p.comments.Unset()
  786. }
  787. p.expect(token.COLON)
  788. exp := &ast.ConditionalExpression{
  789. Test: left,
  790. Consequent: consequent,
  791. Alternate: p.parseAssignmentExpression(),
  792. }
  793. return exp
  794. }
  795. return left
  796. }
  797. func (p *parser) parseAssignmentExpression() ast.Expression {
  798. left := p.parseConditionalExpression()
  799. var operator token.Token
  800. switch p.token {
  801. case token.ASSIGN:
  802. operator = p.token
  803. case token.ADD_ASSIGN:
  804. operator = token.PLUS
  805. case token.SUBTRACT_ASSIGN:
  806. operator = token.MINUS
  807. case token.MULTIPLY_ASSIGN:
  808. operator = token.MULTIPLY
  809. case token.QUOTIENT_ASSIGN:
  810. operator = token.SLASH
  811. case token.REMAINDER_ASSIGN:
  812. operator = token.REMAINDER
  813. case token.AND_ASSIGN:
  814. operator = token.AND
  815. case token.AND_NOT_ASSIGN:
  816. operator = token.AND_NOT
  817. case token.OR_ASSIGN:
  818. operator = token.OR
  819. case token.EXCLUSIVE_OR_ASSIGN:
  820. operator = token.EXCLUSIVE_OR
  821. case token.SHIFT_LEFT_ASSIGN:
  822. operator = token.SHIFT_LEFT
  823. case token.SHIFT_RIGHT_ASSIGN:
  824. operator = token.SHIFT_RIGHT
  825. case token.UNSIGNED_SHIFT_RIGHT_ASSIGN:
  826. operator = token.UNSIGNED_SHIFT_RIGHT
  827. }
  828. if operator != 0 {
  829. idx := p.idx
  830. if p.mode&StoreComments != 0 {
  831. p.comments.Unset()
  832. }
  833. p.next()
  834. switch left.(type) {
  835. case *ast.Identifier, *ast.DotExpression, *ast.BracketExpression:
  836. default:
  837. p.error(left.Idx0(), "invalid left-hand side in assignment")
  838. p.nextStatement()
  839. return &ast.BadExpression{From: idx, To: p.idx}
  840. }
  841. exp := &ast.AssignExpression{
  842. Left: left,
  843. Operator: operator,
  844. Right: p.parseAssignmentExpression(),
  845. }
  846. if p.mode&StoreComments != 0 {
  847. p.comments.SetExpression(exp)
  848. }
  849. return exp
  850. }
  851. return left
  852. }
  853. func (p *parser) parseExpression() ast.Expression {
  854. next := p.parseAssignmentExpression
  855. left := next()
  856. if p.token == token.COMMA {
  857. sequence := []ast.Expression{left}
  858. for {
  859. if p.token != token.COMMA {
  860. break
  861. }
  862. p.next()
  863. sequence = append(sequence, next())
  864. }
  865. return &ast.SequenceExpression{
  866. Sequence: sequence,
  867. }
  868. }
  869. return left
  870. }