AST.cpp 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461
  1. /*
  2. * Copyright (c) 2020, Andreas Kling <kling@serenityos.org>
  3. * All rights reserved.
  4. *
  5. * Redistribution and use in source and binary forms, with or without
  6. * modification, are permitted provided that the following conditions are met:
  7. *
  8. * 1. Redistributions of source code must retain the above copyright notice, this
  9. * list of conditions and the following disclaimer.
  10. *
  11. * 2. Redistributions in binary form must reproduce the above copyright notice,
  12. * this list of conditions and the following disclaimer in the documentation
  13. * and/or other materials provided with the distribution.
  14. *
  15. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  16. * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  17. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  18. * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
  19. * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  20. * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
  21. * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  22. * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
  23. * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  24. * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  25. */
  26. #include <LibJS/AST.h>
  27. #include <LibJS/Function.h>
  28. #include <LibJS/Interpreter.h>
  29. #include <LibJS/Value.h>
  30. #include <stdio.h>
  31. namespace JS {
  32. Value ScopeNode::execute(Interpreter& interpreter) const
  33. {
  34. return interpreter.run(*this);
  35. }
  36. Value FunctionDeclaration::execute(Interpreter& interpreter) const
  37. {
  38. auto* function = interpreter.heap().allocate<Function>(name(), body());
  39. interpreter.global_object().put(m_name, Value(function));
  40. return Value(function);
  41. }
  42. Value CallExpression::execute(Interpreter& interpreter) const
  43. {
  44. if (name() == "$gc") {
  45. interpreter.heap().collect_garbage();
  46. return js_undefined();
  47. }
  48. auto callee = interpreter.global_object().get(name());
  49. ASSERT(callee.is_object());
  50. auto* callee_object = callee.as_object();
  51. ASSERT(callee_object->is_function());
  52. auto& function = static_cast<Function&>(*callee_object);
  53. return interpreter.run(function.body());
  54. }
  55. Value ReturnStatement::execute(Interpreter& interpreter) const
  56. {
  57. auto value = argument().execute(interpreter);
  58. interpreter.do_return();
  59. return value;
  60. }
  61. Value IfStatement::execute(Interpreter& interpreter) const
  62. {
  63. auto predicate_result = m_predicate->execute(interpreter);
  64. if (predicate_result.as_bool())
  65. return interpreter.run(*m_consequent);
  66. else
  67. return interpreter.run(*m_alternate);
  68. }
  69. Value WhileStatement::execute(Interpreter& interpreter) const
  70. {
  71. Value last_value = js_undefined();
  72. while (m_predicate->execute(interpreter).as_bool()) {
  73. last_value = interpreter.run(*m_body);
  74. }
  75. return last_value;
  76. }
  77. Value add(Value lhs, Value rhs)
  78. {
  79. ASSERT(lhs.is_number());
  80. ASSERT(rhs.is_number());
  81. return Value(lhs.as_double() + rhs.as_double());
  82. }
  83. Value sub(Value lhs, Value rhs)
  84. {
  85. ASSERT(lhs.is_number());
  86. ASSERT(rhs.is_number());
  87. return Value(lhs.as_double() - rhs.as_double());
  88. }
  89. const Value typed_eq(const Value lhs, const Value rhs)
  90. {
  91. if (rhs.type() != lhs.type())
  92. return Value(false);
  93. switch (lhs.type()) {
  94. case Value::Type::Undefined:
  95. return Value(true);
  96. case Value::Type::Null:
  97. return Value(true);
  98. case Value::Type::Number:
  99. return Value(lhs.as_double() == rhs.as_double());
  100. case Value::Type::String:
  101. return Value(lhs.as_string() == rhs.as_string());
  102. case Value::Type::Boolean:
  103. return Value(lhs.as_bool() == rhs.as_bool());
  104. case Value::Type::Object:
  105. return Value(lhs.as_object() == rhs.as_object());
  106. }
  107. ASSERT_NOT_REACHED();
  108. }
  109. Value greater(Value lhs, Value rhs)
  110. {
  111. ASSERT(lhs.is_number());
  112. ASSERT(rhs.is_number());
  113. return Value(lhs.as_double() > rhs.as_double());
  114. }
  115. Value smaller(Value lhs, Value rhs)
  116. {
  117. ASSERT(lhs.is_number());
  118. ASSERT(rhs.is_number());
  119. return Value(lhs.as_double() < rhs.as_double());
  120. }
  121. Value bit_and(Value lhs, Value rhs)
  122. {
  123. ASSERT(lhs.is_number());
  124. ASSERT(rhs.is_number());
  125. return Value((i32)lhs.as_double() & (i32)rhs.as_double());
  126. }
  127. Value bit_or(Value lhs, Value rhs)
  128. {
  129. ASSERT(lhs.is_number());
  130. ASSERT(rhs.is_number());
  131. return Value((i32)lhs.as_double() | (i32)rhs.as_double());
  132. }
  133. Value bit_xor(Value lhs, Value rhs)
  134. {
  135. ASSERT(lhs.is_number());
  136. ASSERT(rhs.is_number());
  137. return Value((i32)lhs.as_double() ^ (i32)rhs.as_double());
  138. }
  139. Value bit_not(Value lhs)
  140. {
  141. ASSERT(lhs.is_number());
  142. return Value(~(i32)lhs.as_double());
  143. }
  144. Value bit_left(Value lhs, Value rhs)
  145. {
  146. ASSERT(lhs.is_number());
  147. ASSERT(rhs.is_number());
  148. return Value((i32)lhs.as_double() << (i32)rhs.as_double());
  149. }
  150. Value bit_right(Value lhs, Value rhs)
  151. {
  152. ASSERT(lhs.is_number());
  153. ASSERT(rhs.is_number());
  154. return Value((i32)lhs.as_double() >> (i32)rhs.as_double());
  155. }
  156. Value BinaryExpression::execute(Interpreter& interpreter) const
  157. {
  158. auto lhs_result = m_lhs->execute(interpreter);
  159. auto rhs_result = m_rhs->execute(interpreter);
  160. switch (m_op) {
  161. case BinaryOp::Plus:
  162. return add(lhs_result, rhs_result);
  163. case BinaryOp::Minus:
  164. return sub(lhs_result, rhs_result);
  165. case BinaryOp::TypedEquals:
  166. return typed_eq(lhs_result, rhs_result);
  167. case BinaryOp::TypedInequals:
  168. return Value(!typed_eq(lhs_result, rhs_result).as_bool());
  169. case BinaryOp::Greater:
  170. return greater(lhs_result, rhs_result);
  171. case BinaryOp::Smaller:
  172. return smaller(lhs_result, rhs_result);
  173. case BinaryOp::BitAnd:
  174. return bit_and(lhs_result, rhs_result);
  175. case BinaryOp::BitOr:
  176. return bit_or(lhs_result, rhs_result);
  177. case BinaryOp::BitXor:
  178. return bit_xor(lhs_result, rhs_result);
  179. case BinaryOp::BitLeftShift:
  180. return bit_left(lhs_result, rhs_result);
  181. case BinaryOp::BitRightShift:
  182. return bit_right(lhs_result, rhs_result);
  183. }
  184. ASSERT_NOT_REACHED();
  185. }
  186. Value LogicalExpression::execute(Interpreter& interpreter) const
  187. {
  188. auto lhs_result = m_lhs->execute(interpreter).as_bool();
  189. auto rhs_result = m_rhs->execute(interpreter).as_bool();
  190. switch (m_op) {
  191. case LogicalOp::And:
  192. return Value(lhs_result && rhs_result);
  193. case LogicalOp::Or:
  194. return Value(lhs_result || rhs_result);
  195. }
  196. ASSERT_NOT_REACHED();
  197. }
  198. Value UnaryExpression::execute(Interpreter& interpreter) const
  199. {
  200. auto lhs_result = m_lhs->execute(interpreter);
  201. switch (m_op) {
  202. case UnaryOp::BitNot:
  203. return bit_not(lhs_result);
  204. case UnaryOp::Not:
  205. return Value(!lhs_result.as_bool());
  206. }
  207. ASSERT_NOT_REACHED();
  208. }
  209. static void print_indent(int indent)
  210. {
  211. for (int i = 0; i < indent * 2; ++i)
  212. putchar(' ');
  213. }
  214. void ASTNode::dump(int indent) const
  215. {
  216. print_indent(indent);
  217. printf("%s\n", class_name());
  218. }
  219. void ScopeNode::dump(int indent) const
  220. {
  221. ASTNode::dump(indent);
  222. for (auto& child : children())
  223. child.dump(indent + 1);
  224. }
  225. void BinaryExpression::dump(int indent) const
  226. {
  227. const char* op_string = nullptr;
  228. switch (m_op) {
  229. case BinaryOp::Plus:
  230. op_string = "+";
  231. break;
  232. case BinaryOp::Minus:
  233. op_string = "-";
  234. break;
  235. case BinaryOp::TypedEquals:
  236. op_string = "===";
  237. break;
  238. case BinaryOp::TypedInequals:
  239. op_string = "!==";
  240. break;
  241. case BinaryOp::Greater:
  242. op_string = ">";
  243. break;
  244. case BinaryOp::Smaller:
  245. op_string = "<";
  246. break;
  247. case BinaryOp::BitAnd:
  248. op_string = "&";
  249. break;
  250. case BinaryOp::BitOr:
  251. op_string = "|";
  252. break;
  253. case BinaryOp::BitXor:
  254. op_string = "^";
  255. break;
  256. case BinaryOp::BitLeftShift:
  257. op_string = "<<";
  258. break;
  259. case BinaryOp::BitRightShift:
  260. op_string = ">>";
  261. break;
  262. }
  263. print_indent(indent);
  264. printf("%s\n", class_name());
  265. m_lhs->dump(indent + 1);
  266. print_indent(indent + 1);
  267. printf("%s\n", op_string);
  268. m_rhs->dump(indent + 1);
  269. }
  270. void LogicalExpression::dump(int indent) const
  271. {
  272. const char* op_string = nullptr;
  273. switch (m_op) {
  274. case LogicalOp::And:
  275. op_string = "&&";
  276. break;
  277. case LogicalOp::Or:
  278. op_string = "||";
  279. break;
  280. }
  281. print_indent(indent);
  282. printf("%s\n", class_name());
  283. m_lhs->dump(indent + 1);
  284. print_indent(indent + 1);
  285. printf("%s\n", op_string);
  286. m_rhs->dump(indent + 1);
  287. }
  288. void UnaryExpression::dump(int indent) const
  289. {
  290. const char* op_string = nullptr;
  291. switch (m_op) {
  292. case UnaryOp::BitNot:
  293. op_string = "~";
  294. break;
  295. case UnaryOp::Not:
  296. op_string = "!";
  297. break;
  298. }
  299. print_indent(indent);
  300. printf("%s\n", class_name());
  301. print_indent(indent + 1);
  302. printf("%s\n", op_string);
  303. m_lhs->dump(indent + 1);
  304. }
  305. void CallExpression::dump(int indent) const
  306. {
  307. print_indent(indent);
  308. printf("%s '%s'\n", class_name(), name().characters());
  309. }
  310. void Literal::dump(int indent) const
  311. {
  312. print_indent(indent);
  313. if (m_value.is_object())
  314. ASSERT_NOT_REACHED();
  315. if (m_value.is_string())
  316. printf("%s\n", m_value.as_string()->characters());
  317. else
  318. printf("%s\n", m_value.to_string().characters());
  319. }
  320. void FunctionDeclaration::dump(int indent) const
  321. {
  322. print_indent(indent);
  323. printf("%s '%s'\n", class_name(), name().characters());
  324. body().dump(indent + 1);
  325. }
  326. void ReturnStatement::dump(int indent) const
  327. {
  328. ASTNode::dump(indent);
  329. argument().dump(indent + 1);
  330. }
  331. void IfStatement::dump(int indent) const
  332. {
  333. ASTNode::dump(indent);
  334. print_indent(indent);
  335. printf("If\n");
  336. predicate().dump(indent + 1);
  337. consequent().dump(indent + 1);
  338. print_indent(indent);
  339. printf("Else\n");
  340. alternate().dump(indent + 1);
  341. }
  342. void WhileStatement::dump(int indent) const
  343. {
  344. ASTNode::dump(indent);
  345. print_indent(indent);
  346. printf("While\n");
  347. predicate().dump(indent + 1);
  348. body().dump(indent + 1);
  349. }
  350. Value Identifier::execute(Interpreter& interpreter) const
  351. {
  352. return interpreter.get_variable(string());
  353. }
  354. void Identifier::dump(int indent) const
  355. {
  356. print_indent(indent);
  357. printf("Identifier \"%s\"\n", m_string.characters());
  358. }
  359. Value AssignmentExpression::execute(Interpreter& interpreter) const
  360. {
  361. ASSERT(m_lhs->is_identifier());
  362. auto name = static_cast<const Identifier&>(*m_lhs).string();
  363. auto rhs_result = m_rhs->execute(interpreter);
  364. switch (m_op) {
  365. case AssignmentOp::Assign:
  366. interpreter.set_variable(name, rhs_result);
  367. break;
  368. }
  369. return rhs_result;
  370. }
  371. void AssignmentExpression::dump(int indent) const
  372. {
  373. const char* op_string = nullptr;
  374. switch (m_op) {
  375. case AssignmentOp::Assign:
  376. op_string = "=";
  377. break;
  378. }
  379. ASTNode::dump(indent);
  380. print_indent(indent + 1);
  381. printf("%s\n", op_string);
  382. m_lhs->dump(indent + 1);
  383. m_rhs->dump(indent + 1);
  384. }
  385. Value VariableDeclaration::execute(Interpreter& interpreter) const
  386. {
  387. interpreter.declare_variable(name().string());
  388. if (m_initializer) {
  389. auto initalizer_result = m_initializer->execute(interpreter);
  390. interpreter.set_variable(name().string(), initalizer_result);
  391. }
  392. return js_undefined();
  393. }
  394. void VariableDeclaration::dump(int indent) const
  395. {
  396. ASTNode::dump(indent);
  397. m_name->dump(indent + 1);
  398. if (m_initializer)
  399. m_initializer->dump(indent + 1);
  400. }
  401. }