cmpl_parse.go 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657
  1. package otto
  2. import (
  3. "fmt"
  4. "regexp"
  5. "github.com/robertkrimen/otto/ast"
  6. "github.com/robertkrimen/otto/file"
  7. "github.com/robertkrimen/otto/token"
  8. )
  9. var trueLiteral = &_nodeLiteral{value: toValue_bool(true)}
  10. var falseLiteral = &_nodeLiteral{value: toValue_bool(false)}
  11. var nullLiteral = &_nodeLiteral{value: nullValue}
  12. var emptyStatement = &_nodeEmptyStatement{}
  13. func (cmpl *_compiler) parseExpression(in ast.Expression) _nodeExpression {
  14. if in == nil {
  15. return nil
  16. }
  17. switch in := in.(type) {
  18. case *ast.ArrayLiteral:
  19. out := &_nodeArrayLiteral{
  20. value: make([]_nodeExpression, len(in.Value)),
  21. }
  22. for i, value := range in.Value {
  23. out.value[i] = cmpl.parseExpression(value)
  24. }
  25. return out
  26. case *ast.AssignExpression:
  27. return &_nodeAssignExpression{
  28. operator: in.Operator,
  29. left: cmpl.parseExpression(in.Left),
  30. right: cmpl.parseExpression(in.Right),
  31. }
  32. case *ast.BinaryExpression:
  33. return &_nodeBinaryExpression{
  34. operator: in.Operator,
  35. left: cmpl.parseExpression(in.Left),
  36. right: cmpl.parseExpression(in.Right),
  37. comparison: in.Comparison,
  38. }
  39. case *ast.BooleanLiteral:
  40. if in.Value {
  41. return trueLiteral
  42. }
  43. return falseLiteral
  44. case *ast.BracketExpression:
  45. return &_nodeBracketExpression{
  46. idx: in.Left.Idx0(),
  47. left: cmpl.parseExpression(in.Left),
  48. member: cmpl.parseExpression(in.Member),
  49. }
  50. case *ast.CallExpression:
  51. out := &_nodeCallExpression{
  52. callee: cmpl.parseExpression(in.Callee),
  53. argumentList: make([]_nodeExpression, len(in.ArgumentList)),
  54. }
  55. for i, value := range in.ArgumentList {
  56. out.argumentList[i] = cmpl.parseExpression(value)
  57. }
  58. return out
  59. case *ast.ConditionalExpression:
  60. return &_nodeConditionalExpression{
  61. test: cmpl.parseExpression(in.Test),
  62. consequent: cmpl.parseExpression(in.Consequent),
  63. alternate: cmpl.parseExpression(in.Alternate),
  64. }
  65. case *ast.DotExpression:
  66. return &_nodeDotExpression{
  67. idx: in.Left.Idx0(),
  68. left: cmpl.parseExpression(in.Left),
  69. identifier: in.Identifier.Name,
  70. }
  71. case *ast.EmptyExpression:
  72. return nil
  73. case *ast.FunctionLiteral:
  74. name := ""
  75. if in.Name != nil {
  76. name = in.Name.Name
  77. }
  78. out := &_nodeFunctionLiteral{
  79. name: name,
  80. body: cmpl.parseStatement(in.Body),
  81. source: in.Source,
  82. file: cmpl.file,
  83. }
  84. if in.ParameterList != nil {
  85. list := in.ParameterList.List
  86. out.parameterList = make([]string, len(list))
  87. for i, value := range list {
  88. out.parameterList[i] = value.Name
  89. }
  90. }
  91. for _, value := range in.DeclarationList {
  92. switch value := value.(type) {
  93. case *ast.FunctionDeclaration:
  94. out.functionList = append(out.functionList, cmpl.parseExpression(value.Function).(*_nodeFunctionLiteral))
  95. case *ast.VariableDeclaration:
  96. for _, value := range value.List {
  97. out.varList = append(out.varList, value.Name)
  98. }
  99. default:
  100. panic(fmt.Errorf("Here be dragons: parseProgram.declaration(%T)", value))
  101. }
  102. }
  103. return out
  104. case *ast.Identifier:
  105. return &_nodeIdentifier{
  106. idx: in.Idx,
  107. name: in.Name,
  108. }
  109. case *ast.NewExpression:
  110. out := &_nodeNewExpression{
  111. callee: cmpl.parseExpression(in.Callee),
  112. argumentList: make([]_nodeExpression, len(in.ArgumentList)),
  113. }
  114. for i, value := range in.ArgumentList {
  115. out.argumentList[i] = cmpl.parseExpression(value)
  116. }
  117. return out
  118. case *ast.NullLiteral:
  119. return nullLiteral
  120. case *ast.NumberLiteral:
  121. return &_nodeLiteral{
  122. value: toValue(in.Value),
  123. }
  124. case *ast.ObjectLiteral:
  125. out := &_nodeObjectLiteral{
  126. value: make([]_nodeProperty, len(in.Value)),
  127. }
  128. for i, value := range in.Value {
  129. out.value[i] = _nodeProperty{
  130. key: value.Key,
  131. kind: value.Kind,
  132. value: cmpl.parseExpression(value.Value),
  133. }
  134. }
  135. return out
  136. case *ast.RegExpLiteral:
  137. return &_nodeRegExpLiteral{
  138. flags: in.Flags,
  139. pattern: in.Pattern,
  140. }
  141. case *ast.SequenceExpression:
  142. out := &_nodeSequenceExpression{
  143. sequence: make([]_nodeExpression, len(in.Sequence)),
  144. }
  145. for i, value := range in.Sequence {
  146. out.sequence[i] = cmpl.parseExpression(value)
  147. }
  148. return out
  149. case *ast.StringLiteral:
  150. return &_nodeLiteral{
  151. value: toValue_string(in.Value),
  152. }
  153. case *ast.ThisExpression:
  154. return &_nodeThisExpression{}
  155. case *ast.UnaryExpression:
  156. return &_nodeUnaryExpression{
  157. operator: in.Operator,
  158. operand: cmpl.parseExpression(in.Operand),
  159. postfix: in.Postfix,
  160. }
  161. case *ast.VariableExpression:
  162. return &_nodeVariableExpression{
  163. idx: in.Idx0(),
  164. name: in.Name,
  165. initializer: cmpl.parseExpression(in.Initializer),
  166. }
  167. }
  168. panic(fmt.Errorf("Here be dragons: cmpl.parseExpression(%T)", in))
  169. }
  170. func (cmpl *_compiler) parseStatement(in ast.Statement) _nodeStatement {
  171. if in == nil {
  172. return nil
  173. }
  174. switch in := in.(type) {
  175. case *ast.BlockStatement:
  176. out := &_nodeBlockStatement{
  177. list: make([]_nodeStatement, len(in.List)),
  178. }
  179. for i, value := range in.List {
  180. out.list[i] = cmpl.parseStatement(value)
  181. }
  182. return out
  183. case *ast.BranchStatement:
  184. out := &_nodeBranchStatement{
  185. branch: in.Token,
  186. }
  187. if in.Label != nil {
  188. out.label = in.Label.Name
  189. }
  190. return out
  191. case *ast.DebuggerStatement:
  192. return &_nodeDebuggerStatement{}
  193. case *ast.DoWhileStatement:
  194. out := &_nodeDoWhileStatement{
  195. test: cmpl.parseExpression(in.Test),
  196. }
  197. body := cmpl.parseStatement(in.Body)
  198. if block, ok := body.(*_nodeBlockStatement); ok {
  199. out.body = block.list
  200. } else {
  201. out.body = append(out.body, body)
  202. }
  203. return out
  204. case *ast.EmptyStatement:
  205. return emptyStatement
  206. case *ast.ExpressionStatement:
  207. return &_nodeExpressionStatement{
  208. expression: cmpl.parseExpression(in.Expression),
  209. }
  210. case *ast.ForInStatement:
  211. out := &_nodeForInStatement{
  212. into: cmpl.parseExpression(in.Into),
  213. source: cmpl.parseExpression(in.Source),
  214. }
  215. body := cmpl.parseStatement(in.Body)
  216. if block, ok := body.(*_nodeBlockStatement); ok {
  217. out.body = block.list
  218. } else {
  219. out.body = append(out.body, body)
  220. }
  221. return out
  222. case *ast.ForStatement:
  223. out := &_nodeForStatement{
  224. initializer: cmpl.parseExpression(in.Initializer),
  225. update: cmpl.parseExpression(in.Update),
  226. test: cmpl.parseExpression(in.Test),
  227. }
  228. body := cmpl.parseStatement(in.Body)
  229. if block, ok := body.(*_nodeBlockStatement); ok {
  230. out.body = block.list
  231. } else {
  232. out.body = append(out.body, body)
  233. }
  234. return out
  235. case *ast.FunctionStatement:
  236. return emptyStatement
  237. case *ast.IfStatement:
  238. return &_nodeIfStatement{
  239. test: cmpl.parseExpression(in.Test),
  240. consequent: cmpl.parseStatement(in.Consequent),
  241. alternate: cmpl.parseStatement(in.Alternate),
  242. }
  243. case *ast.LabelledStatement:
  244. return &_nodeLabelledStatement{
  245. label: in.Label.Name,
  246. statement: cmpl.parseStatement(in.Statement),
  247. }
  248. case *ast.ReturnStatement:
  249. return &_nodeReturnStatement{
  250. argument: cmpl.parseExpression(in.Argument),
  251. }
  252. case *ast.SwitchStatement:
  253. out := &_nodeSwitchStatement{
  254. discriminant: cmpl.parseExpression(in.Discriminant),
  255. default_: in.Default,
  256. body: make([]*_nodeCaseStatement, len(in.Body)),
  257. }
  258. for i, clause := range in.Body {
  259. out.body[i] = &_nodeCaseStatement{
  260. test: cmpl.parseExpression(clause.Test),
  261. consequent: make([]_nodeStatement, len(clause.Consequent)),
  262. }
  263. for j, value := range clause.Consequent {
  264. out.body[i].consequent[j] = cmpl.parseStatement(value)
  265. }
  266. }
  267. return out
  268. case *ast.ThrowStatement:
  269. return &_nodeThrowStatement{
  270. argument: cmpl.parseExpression(in.Argument),
  271. }
  272. case *ast.TryStatement:
  273. out := &_nodeTryStatement{
  274. body: cmpl.parseStatement(in.Body),
  275. finally: cmpl.parseStatement(in.Finally),
  276. }
  277. if in.Catch != nil {
  278. out.catch = &_nodeCatchStatement{
  279. parameter: in.Catch.Parameter.Name,
  280. body: cmpl.parseStatement(in.Catch.Body),
  281. }
  282. }
  283. return out
  284. case *ast.VariableStatement:
  285. out := &_nodeVariableStatement{
  286. list: make([]_nodeExpression, len(in.List)),
  287. }
  288. for i, value := range in.List {
  289. out.list[i] = cmpl.parseExpression(value)
  290. }
  291. return out
  292. case *ast.WhileStatement:
  293. out := &_nodeWhileStatement{
  294. test: cmpl.parseExpression(in.Test),
  295. }
  296. body := cmpl.parseStatement(in.Body)
  297. if block, ok := body.(*_nodeBlockStatement); ok {
  298. out.body = block.list
  299. } else {
  300. out.body = append(out.body, body)
  301. }
  302. return out
  303. case *ast.WithStatement:
  304. return &_nodeWithStatement{
  305. object: cmpl.parseExpression(in.Object),
  306. body: cmpl.parseStatement(in.Body),
  307. }
  308. }
  309. panic(fmt.Errorf("Here be dragons: cmpl.parseStatement(%T)", in))
  310. }
  311. func cmpl_parse(in *ast.Program) *_nodeProgram {
  312. cmpl := _compiler{
  313. program: in,
  314. }
  315. return cmpl.parse()
  316. }
  317. func (cmpl *_compiler) _parse(in *ast.Program) *_nodeProgram {
  318. out := &_nodeProgram{
  319. body: make([]_nodeStatement, len(in.Body)),
  320. file: in.File,
  321. }
  322. for i, value := range in.Body {
  323. out.body[i] = cmpl.parseStatement(value)
  324. }
  325. for _, value := range in.DeclarationList {
  326. switch value := value.(type) {
  327. case *ast.FunctionDeclaration:
  328. out.functionList = append(out.functionList, cmpl.parseExpression(value.Function).(*_nodeFunctionLiteral))
  329. case *ast.VariableDeclaration:
  330. for _, value := range value.List {
  331. out.varList = append(out.varList, value.Name)
  332. }
  333. default:
  334. panic(fmt.Errorf("Here be dragons: cmpl.parseProgram.DeclarationList(%T)", value))
  335. }
  336. }
  337. return out
  338. }
  339. type _nodeProgram struct {
  340. body []_nodeStatement
  341. varList []string
  342. functionList []*_nodeFunctionLiteral
  343. variableList []_nodeDeclaration
  344. file *file.File
  345. }
  346. type _nodeDeclaration struct {
  347. name string
  348. definition _node
  349. }
  350. type _node interface {
  351. }
  352. type (
  353. _nodeExpression interface {
  354. _node
  355. _expressionNode()
  356. }
  357. _nodeArrayLiteral struct {
  358. value []_nodeExpression
  359. }
  360. _nodeAssignExpression struct {
  361. operator token.Token
  362. left _nodeExpression
  363. right _nodeExpression
  364. }
  365. _nodeBinaryExpression struct {
  366. operator token.Token
  367. left _nodeExpression
  368. right _nodeExpression
  369. comparison bool
  370. }
  371. _nodeBracketExpression struct {
  372. idx file.Idx
  373. left _nodeExpression
  374. member _nodeExpression
  375. }
  376. _nodeCallExpression struct {
  377. callee _nodeExpression
  378. argumentList []_nodeExpression
  379. }
  380. _nodeConditionalExpression struct {
  381. test _nodeExpression
  382. consequent _nodeExpression
  383. alternate _nodeExpression
  384. }
  385. _nodeDotExpression struct {
  386. idx file.Idx
  387. left _nodeExpression
  388. identifier string
  389. }
  390. _nodeFunctionLiteral struct {
  391. name string
  392. body _nodeStatement
  393. source string
  394. parameterList []string
  395. varList []string
  396. functionList []*_nodeFunctionLiteral
  397. file *file.File
  398. }
  399. _nodeIdentifier struct {
  400. idx file.Idx
  401. name string
  402. }
  403. _nodeLiteral struct {
  404. value Value
  405. }
  406. _nodeNewExpression struct {
  407. callee _nodeExpression
  408. argumentList []_nodeExpression
  409. }
  410. _nodeObjectLiteral struct {
  411. value []_nodeProperty
  412. }
  413. _nodeProperty struct {
  414. key string
  415. kind string
  416. value _nodeExpression
  417. }
  418. _nodeRegExpLiteral struct {
  419. flags string
  420. pattern string // Value?
  421. regexp *regexp.Regexp
  422. }
  423. _nodeSequenceExpression struct {
  424. sequence []_nodeExpression
  425. }
  426. _nodeThisExpression struct {
  427. }
  428. _nodeUnaryExpression struct {
  429. operator token.Token
  430. operand _nodeExpression
  431. postfix bool
  432. }
  433. _nodeVariableExpression struct {
  434. idx file.Idx
  435. name string
  436. initializer _nodeExpression
  437. }
  438. )
  439. type (
  440. _nodeStatement interface {
  441. _node
  442. _statementNode()
  443. }
  444. _nodeBlockStatement struct {
  445. list []_nodeStatement
  446. }
  447. _nodeBranchStatement struct {
  448. branch token.Token
  449. label string
  450. }
  451. _nodeCaseStatement struct {
  452. test _nodeExpression
  453. consequent []_nodeStatement
  454. }
  455. _nodeCatchStatement struct {
  456. parameter string
  457. body _nodeStatement
  458. }
  459. _nodeDebuggerStatement struct {
  460. }
  461. _nodeDoWhileStatement struct {
  462. test _nodeExpression
  463. body []_nodeStatement
  464. }
  465. _nodeEmptyStatement struct {
  466. }
  467. _nodeExpressionStatement struct {
  468. expression _nodeExpression
  469. }
  470. _nodeForInStatement struct {
  471. into _nodeExpression
  472. source _nodeExpression
  473. body []_nodeStatement
  474. }
  475. _nodeForStatement struct {
  476. initializer _nodeExpression
  477. update _nodeExpression
  478. test _nodeExpression
  479. body []_nodeStatement
  480. }
  481. _nodeIfStatement struct {
  482. test _nodeExpression
  483. consequent _nodeStatement
  484. alternate _nodeStatement
  485. }
  486. _nodeLabelledStatement struct {
  487. label string
  488. statement _nodeStatement
  489. }
  490. _nodeReturnStatement struct {
  491. argument _nodeExpression
  492. }
  493. _nodeSwitchStatement struct {
  494. discriminant _nodeExpression
  495. default_ int
  496. body []*_nodeCaseStatement
  497. }
  498. _nodeThrowStatement struct {
  499. argument _nodeExpression
  500. }
  501. _nodeTryStatement struct {
  502. body _nodeStatement
  503. catch *_nodeCatchStatement
  504. finally _nodeStatement
  505. }
  506. _nodeVariableStatement struct {
  507. list []_nodeExpression
  508. }
  509. _nodeWhileStatement struct {
  510. test _nodeExpression
  511. body []_nodeStatement
  512. }
  513. _nodeWithStatement struct {
  514. object _nodeExpression
  515. body _nodeStatement
  516. }
  517. )
  518. // _expressionNode
  519. func (*_nodeArrayLiteral) _expressionNode() {}
  520. func (*_nodeAssignExpression) _expressionNode() {}
  521. func (*_nodeBinaryExpression) _expressionNode() {}
  522. func (*_nodeBracketExpression) _expressionNode() {}
  523. func (*_nodeCallExpression) _expressionNode() {}
  524. func (*_nodeConditionalExpression) _expressionNode() {}
  525. func (*_nodeDotExpression) _expressionNode() {}
  526. func (*_nodeFunctionLiteral) _expressionNode() {}
  527. func (*_nodeIdentifier) _expressionNode() {}
  528. func (*_nodeLiteral) _expressionNode() {}
  529. func (*_nodeNewExpression) _expressionNode() {}
  530. func (*_nodeObjectLiteral) _expressionNode() {}
  531. func (*_nodeRegExpLiteral) _expressionNode() {}
  532. func (*_nodeSequenceExpression) _expressionNode() {}
  533. func (*_nodeThisExpression) _expressionNode() {}
  534. func (*_nodeUnaryExpression) _expressionNode() {}
  535. func (*_nodeVariableExpression) _expressionNode() {}
  536. // _statementNode
  537. func (*_nodeBlockStatement) _statementNode() {}
  538. func (*_nodeBranchStatement) _statementNode() {}
  539. func (*_nodeCaseStatement) _statementNode() {}
  540. func (*_nodeCatchStatement) _statementNode() {}
  541. func (*_nodeDebuggerStatement) _statementNode() {}
  542. func (*_nodeDoWhileStatement) _statementNode() {}
  543. func (*_nodeEmptyStatement) _statementNode() {}
  544. func (*_nodeExpressionStatement) _statementNode() {}
  545. func (*_nodeForInStatement) _statementNode() {}
  546. func (*_nodeForStatement) _statementNode() {}
  547. func (*_nodeIfStatement) _statementNode() {}
  548. func (*_nodeLabelledStatement) _statementNode() {}
  549. func (*_nodeReturnStatement) _statementNode() {}
  550. func (*_nodeSwitchStatement) _statementNode() {}
  551. func (*_nodeThrowStatement) _statementNode() {}
  552. func (*_nodeTryStatement) _statementNode() {}
  553. func (*_nodeVariableStatement) _statementNode() {}
  554. func (*_nodeWhileStatement) _statementNode() {}
  555. func (*_nodeWithStatement) _statementNode() {}