compiler.cpp 30 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141
  1. /*=============================================================================
  2. Copyright (c) 2001-2011 Joel de Guzman
  3. Distributed under the Boost Software License, Version 1.0. (See accompanying
  4. file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  5. =============================================================================*/
  6. #include "config.hpp"
  7. #include "compiler.hpp"
  8. #include "annotation.hpp"
  9. #include "vm.hpp"
  10. #include <boost/foreach.hpp>
  11. #include <boost/variant/apply_visitor.hpp>
  12. #include <boost/range/adaptor/transformed.hpp>
  13. #include <boost/assert.hpp>
  14. #include <set>
  15. namespace client { namespace code_gen
  16. {
  17. value::value()
  18. : v(0),
  19. is_lvalue_(false),
  20. builder(0)
  21. {}
  22. value::value(
  23. llvm::Value* v,
  24. bool is_lvalue_,
  25. llvm::IRBuilder<>* builder)
  26. : v(v),
  27. is_lvalue_(is_lvalue_),
  28. builder(builder)
  29. {}
  30. value::value(value const& rhs)
  31. : v(rhs.v),
  32. is_lvalue_(rhs.is_lvalue_),
  33. builder(rhs.builder)
  34. {}
  35. bool value::is_lvalue() const
  36. {
  37. return is_lvalue_;
  38. }
  39. bool value::is_valid() const
  40. {
  41. return v != 0;
  42. }
  43. value::operator bool() const
  44. {
  45. return v != 0;
  46. }
  47. void value::name(char const* id)
  48. {
  49. v->setName(id);
  50. }
  51. void value::name(std::string const& id)
  52. {
  53. v->setName(id);
  54. }
  55. value::operator llvm::Value*() const
  56. {
  57. if (is_lvalue_)
  58. {
  59. BOOST_ASSERT(builder != 0);
  60. return builder->CreateLoad(v, v->getName());
  61. }
  62. return v;
  63. }
  64. value& value::operator=(value const& rhs)
  65. {
  66. v = rhs.v;
  67. is_lvalue_ = rhs.is_lvalue_;
  68. builder = rhs.builder;
  69. return *this;
  70. }
  71. value& value::assign(value const& rhs)
  72. {
  73. BOOST_ASSERT(is_lvalue());
  74. BOOST_ASSERT(builder != 0);
  75. builder->CreateStore(rhs, v);
  76. return *this;
  77. }
  78. value operator-(value a)
  79. {
  80. BOOST_ASSERT(a.builder != 0);
  81. return value(
  82. a.builder->CreateNeg(a, "neg_tmp"),
  83. false, a.builder
  84. );
  85. }
  86. value operator!(value a)
  87. {
  88. BOOST_ASSERT(a.builder != 0);
  89. return value(
  90. a.builder->CreateNot(a, "not_tmp"),
  91. false, a.builder
  92. );
  93. }
  94. value operator+(value a, value b)
  95. {
  96. BOOST_ASSERT(a.builder != 0);
  97. return value(
  98. a.builder->CreateAdd(a, b, "add_tmp"),
  99. false, a.builder
  100. );
  101. }
  102. value operator-(value a, value b)
  103. {
  104. BOOST_ASSERT(a.builder != 0);
  105. return value(
  106. a.builder->CreateSub(a, b, "sub_tmp"),
  107. false, a.builder
  108. );
  109. }
  110. value operator*(value a, value b)
  111. {
  112. BOOST_ASSERT(a.builder != 0);
  113. return value(
  114. a.builder->CreateMul(a, b, "mul_tmp"),
  115. false, a.builder
  116. );
  117. }
  118. value operator/(value a, value b)
  119. {
  120. BOOST_ASSERT(a.builder != 0);
  121. return value(
  122. a.builder->CreateSDiv(a, b, "div_tmp"),
  123. false, a.builder
  124. );
  125. }
  126. value operator%(value a, value b)
  127. {
  128. BOOST_ASSERT(a.builder != 0);
  129. return value(
  130. a.builder->CreateSRem(a, b, "mod_tmp"),
  131. false, a.builder
  132. );
  133. }
  134. value operator&(value a, value b)
  135. {
  136. BOOST_ASSERT(a.builder != 0);
  137. return value(
  138. a.builder->CreateAnd(a, b, "and_tmp"),
  139. false, a.builder
  140. );
  141. }
  142. value operator|(value a, value b)
  143. {
  144. BOOST_ASSERT(a.builder != 0);
  145. return value(
  146. a.builder->CreateOr(a, b, "or_tmp"),
  147. false, a.builder
  148. );
  149. }
  150. value operator^(value a, value b)
  151. {
  152. BOOST_ASSERT(a.builder != 0);
  153. return value(
  154. a.builder->CreateXor(a, b, "xor_tmp"),
  155. false, a.builder
  156. );
  157. }
  158. value operator<<(value a, value b)
  159. {
  160. BOOST_ASSERT(a.builder != 0);
  161. return value(
  162. a.builder->CreateShl(a, b, "shl_tmp"),
  163. false, a.builder
  164. );
  165. }
  166. value operator>>(value a, value b)
  167. {
  168. BOOST_ASSERT(a.builder != 0);
  169. return value(
  170. a.builder->CreateLShr(a, b, "shr_tmp"),
  171. false, a.builder
  172. );
  173. }
  174. value operator==(value a, value b)
  175. {
  176. BOOST_ASSERT(a.builder != 0);
  177. return value(
  178. a.builder->CreateICmpEQ(a, b, "eq_tmp"),
  179. false, a.builder
  180. );
  181. }
  182. value operator!=(value a, value b)
  183. {
  184. BOOST_ASSERT(a.builder != 0);
  185. return value(
  186. a.builder->CreateICmpNE(a, b, "ne_tmp"),
  187. false, a.builder
  188. );
  189. }
  190. value operator<(value a, value b)
  191. {
  192. BOOST_ASSERT(a.builder != 0);
  193. return value(
  194. a.builder->CreateICmpSLT(a, b, "slt_tmp"),
  195. false, a.builder
  196. );
  197. }
  198. value operator<=(value a, value b)
  199. {
  200. BOOST_ASSERT(a.builder != 0);
  201. return value(
  202. a.builder->CreateICmpSLE(a, b, "sle_tmp"),
  203. false, a.builder
  204. );
  205. }
  206. value operator>(value a, value b)
  207. {
  208. BOOST_ASSERT(a.builder != 0);
  209. return value(
  210. a.builder->CreateICmpSGT(a, b, "sgt_tmp"),
  211. false, a.builder
  212. );
  213. }
  214. value operator>=(value a, value b)
  215. {
  216. BOOST_ASSERT(a.builder != 0);
  217. return value(
  218. a.builder->CreateICmpSGE(a, b, "sge_tmp"),
  219. false, a.builder
  220. );
  221. }
  222. struct function::to_value
  223. {
  224. typedef value result_type;
  225. llvm_compiler* c;
  226. to_value(llvm_compiler* c = 0) : c(c) {}
  227. value operator()(llvm::Value& v) const
  228. {
  229. return c->val(&v);
  230. }
  231. };
  232. bool basic_block::has_terminator() const
  233. {
  234. return b->getTerminator() != 0;
  235. }
  236. bool basic_block::is_valid() const
  237. {
  238. return b != 0;
  239. }
  240. function::operator llvm::Function*() const
  241. {
  242. return f;
  243. }
  244. std::size_t function::arg_size() const
  245. {
  246. return f->arg_size();
  247. }
  248. void function::add(basic_block const& b)
  249. {
  250. f->getBasicBlockList().push_back(b);
  251. }
  252. void function::erase_from_parent()
  253. {
  254. f->eraseFromParent();
  255. }
  256. basic_block function::last_block()
  257. {
  258. return &f->getBasicBlockList().back();
  259. }
  260. bool function::empty() const
  261. {
  262. return f->empty();
  263. }
  264. std::string function::name() const
  265. {
  266. return f->getName();
  267. }
  268. function::arg_range function::args() const
  269. {
  270. BOOST_ASSERT(c != 0);
  271. arg_val_iterator first(f->arg_begin(), to_value());
  272. arg_val_iterator last(f->arg_end(), to_value());
  273. return arg_range(first, last);
  274. }
  275. bool function::is_valid() const
  276. {
  277. return f != 0;
  278. }
  279. void function::verify() const
  280. {
  281. llvm::verifyFunction(*f);
  282. }
  283. value llvm_compiler::val(unsigned int x)
  284. {
  285. return value(
  286. llvm::ConstantInt::get(context(), llvm::APInt(int_size, x)),
  287. false, &llvm_builder);
  288. }
  289. value llvm_compiler::val(int x)
  290. {
  291. return value(
  292. llvm::ConstantInt::get(context(), llvm::APInt(int_size, x)),
  293. false, &llvm_builder);
  294. }
  295. value llvm_compiler::val(bool x)
  296. {
  297. return value(
  298. llvm::ConstantInt::get(context(), llvm::APInt(1, x)),
  299. false, &llvm_builder);
  300. }
  301. value llvm_compiler::val(llvm::Value* v)
  302. {
  303. return value(v, false, &llvm_builder);
  304. }
  305. namespace
  306. {
  307. // Create an alloca instruction in the entry block of
  308. // the function. This is used for mutable variables etc.
  309. llvm::AllocaInst*
  310. make_entry_block_alloca(
  311. llvm::Function* f,
  312. char const* name,
  313. llvm::LLVMContext& context)
  314. {
  315. llvm::IRBuilder<> builder(
  316. &f->getEntryBlock(),
  317. f->getEntryBlock().begin());
  318. return builder.CreateAlloca(
  319. llvm::Type::getIntNTy(context, int_size), 0, name);
  320. }
  321. }
  322. value llvm_compiler::var(char const* name)
  323. {
  324. llvm::Function* f = llvm_builder.GetInsertBlock()->getParent();
  325. llvm::IRBuilder<> builder(
  326. &f->getEntryBlock(),
  327. f->getEntryBlock().begin());
  328. llvm::AllocaInst* alloca = builder.CreateAlloca(
  329. llvm::Type::getIntNTy(context(), int_size), 0, name);
  330. return value(alloca, true, &llvm_builder);
  331. }
  332. struct value::to_llvm_value
  333. {
  334. typedef llvm::Value* result_type;
  335. llvm::Value* operator()(value const& x) const
  336. {
  337. return x;
  338. }
  339. };
  340. template <typename C>
  341. llvm::Value* llvm_compiler::call_impl(
  342. function callee,
  343. C const& args_)
  344. {
  345. // Sigh. LLVM requires CreateCall arguments to be random access.
  346. // It would have been better if it can accept forward iterators.
  347. // I guess it needs the arguments to be in contiguous memory.
  348. // So, we have to put the args into a temporary std::vector.
  349. std::vector<llvm::Value*> args(
  350. args_.begin(), args_.end());
  351. // Check the args for null values. We can't have null values.
  352. // Return 0 if we find one to flag error.
  353. BOOST_FOREACH(llvm::Value* arg, args)
  354. {
  355. if (arg == 0)
  356. return 0;
  357. }
  358. return llvm_builder.CreateCall(
  359. callee, args.begin(), args.end(), "call_tmp");
  360. }
  361. template <typename Container>
  362. value llvm_compiler::call(
  363. function callee,
  364. Container const& args)
  365. {
  366. llvm::Value* call = call_impl(
  367. callee,
  368. args | boost::adaptors::transformed(value::to_llvm_value()));
  369. if (call == 0)
  370. return val();
  371. return value(call, false, &llvm_builder);
  372. }
  373. function llvm_compiler::get_function(char const* name)
  374. {
  375. return function(vm.module()->getFunction(name), this);
  376. }
  377. function llvm_compiler::get_current_function()
  378. {
  379. // get the current function
  380. return function(llvm_builder.GetInsertBlock()->getParent(), this);
  381. }
  382. function llvm_compiler::declare_function(
  383. bool void_return
  384. , std::string const& name
  385. , std::size_t nargs)
  386. {
  387. llvm::Type const* int_type =
  388. llvm::Type::getIntNTy(context(), int_size);
  389. llvm::Type const* void_type = llvm::Type::getVoidTy(context());
  390. std::vector<llvm::Type const*> ints(nargs, int_type);
  391. llvm::Type const* return_type = void_return ? void_type : int_type;
  392. llvm::FunctionType* function_type =
  393. llvm::FunctionType::get(void_return ? void_type : int_type, ints, false);
  394. return function(llvm::Function::Create(
  395. function_type, llvm::Function::ExternalLinkage,
  396. name, vm.module()), this);
  397. }
  398. basic_block llvm_compiler::make_basic_block(
  399. char const* name
  400. , function parent
  401. , basic_block before)
  402. {
  403. return llvm::BasicBlock::Create(context(), name, parent, before);
  404. }
  405. value llvm_compiler::var(std::string const& name)
  406. {
  407. return var(name.c_str());
  408. }
  409. function llvm_compiler::get_function(std::string const& name)
  410. {
  411. return get_function(name.c_str());
  412. }
  413. basic_block llvm_compiler::get_insert_block()
  414. {
  415. return llvm_builder.GetInsertBlock();
  416. }
  417. void llvm_compiler::set_insert_point(basic_block b)
  418. {
  419. llvm_builder.SetInsertPoint(b);
  420. }
  421. void llvm_compiler::conditional_branch(
  422. value cond, basic_block true_br, basic_block false_br)
  423. {
  424. llvm_builder.CreateCondBr(cond, true_br, false_br);
  425. }
  426. void llvm_compiler::branch(basic_block b)
  427. {
  428. llvm_builder.CreateBr(b);
  429. }
  430. void llvm_compiler::return_()
  431. {
  432. llvm_builder.CreateRetVoid();
  433. }
  434. void llvm_compiler::return_(value v)
  435. {
  436. llvm_builder.CreateRet(v);
  437. }
  438. void llvm_compiler::optimize_function(function f)
  439. {
  440. // Optimize the function.
  441. fpm.run(*f);
  442. }
  443. void llvm_compiler::init_fpm()
  444. {
  445. // Set up the optimizer pipeline. Start with registering info about how the
  446. // target lays out data structures.
  447. fpm.add(new llvm::TargetData(*vm.execution_engine()->getTargetData()));
  448. // Provide basic AliasAnalysis support for GVN.
  449. fpm.add(llvm::createBasicAliasAnalysisPass());
  450. // Promote allocas to registers.
  451. fpm.add(llvm::createPromoteMemoryToRegisterPass());
  452. // Do simple "peephole" optimizations and bit-twiddling optzns.
  453. fpm.add(llvm::createInstructionCombiningPass());
  454. // Reassociate expressions.
  455. fpm.add(llvm::createReassociatePass());
  456. // Eliminate Common SubExpressions.
  457. fpm.add(llvm::createGVNPass());
  458. // Simplify the control flow graph (deleting unreachable blocks, etc).
  459. fpm.add(llvm::createCFGSimplificationPass());
  460. fpm.doInitialization();
  461. }
  462. value compiler::operator()(unsigned int x)
  463. {
  464. return val(x);
  465. }
  466. value compiler::operator()(bool x)
  467. {
  468. return val(x);
  469. }
  470. value compiler::operator()(ast::primary_expr const& x)
  471. {
  472. return boost::apply_visitor(*this, x.get());
  473. }
  474. value compiler::operator()(ast::identifier const& x)
  475. {
  476. // Look this variable up in the function.
  477. if (locals.find(x.name) == locals.end())
  478. {
  479. error_handler(x.id, "Undeclared variable: " + x.name);
  480. return val();
  481. }
  482. return locals[x.name];
  483. }
  484. value compiler::operator()(ast::unary_expr const& x)
  485. {
  486. value operand = boost::apply_visitor(*this, x.operand_);
  487. if (!operand.is_valid())
  488. return val();
  489. switch (x.operator_)
  490. {
  491. case token_ids::compl_: return operand ^ val(-1);
  492. case token_ids::minus: return -operand;
  493. case token_ids::not_: return !operand;
  494. case token_ids::plus: return operand;
  495. case token_ids::plus_plus:
  496. {
  497. if (!operand.is_lvalue())
  498. {
  499. error_handler(x.id, "++ needs an var");
  500. return val();
  501. }
  502. value r = operand + val(1);
  503. operand.assign(r);
  504. return operand;
  505. }
  506. case token_ids::minus_minus:
  507. {
  508. if (!operand.is_lvalue())
  509. {
  510. error_handler(x.id, "-- needs an var");
  511. return val();
  512. }
  513. value r = operand - val(1);
  514. operand.assign(r);
  515. return operand;
  516. }
  517. default:
  518. BOOST_ASSERT(0);
  519. return val();
  520. }
  521. }
  522. namespace
  523. {
  524. struct compile_args
  525. {
  526. compiler& c;
  527. compile_args(compiler& c) : c(c) {}
  528. typedef value result_type;
  529. value operator()(ast::expression const& expr) const
  530. {
  531. return c(expr);
  532. }
  533. };
  534. }
  535. value compiler::operator()(ast::function_call const& x)
  536. {
  537. function callee = get_function(x.function_name.name);
  538. if (!callee.is_valid())
  539. {
  540. error_handler(x.function_name.id,
  541. "Function not found: " + x.function_name.name);
  542. return val();
  543. }
  544. if (callee.arg_size() != x.args.size())
  545. {
  546. error_handler(x.function_name.id,
  547. "Wrong number of arguments: " + x.function_name.name);
  548. return val();
  549. }
  550. return call(callee,
  551. x.args | boost::adaptors::transformed(compile_args(*this)));
  552. }
  553. namespace
  554. {
  555. int precedence[] = {
  556. // precedence 1
  557. 1, // op_comma
  558. // precedence 2
  559. 2, // op_assign
  560. 2, // op_plus_assign
  561. 2, // op_minus_assign
  562. 2, // op_times_assign
  563. 2, // op_divide_assign
  564. 2, // op_mod_assign
  565. 2, // op_bit_and_assign
  566. 2, // op_bit_xor_assign
  567. 2, // op_bitor_assign
  568. 2, // op_shift_left_assign
  569. 2, // op_shift_right_assign
  570. // precedence 3
  571. 3, // op_logical_or
  572. // precedence 4
  573. 4, // op_logical_and
  574. // precedence 5
  575. 5, // op_bit_or
  576. // precedence 6
  577. 6, // op_bit_xor
  578. // precedence 7
  579. 7, // op_bit_and
  580. // precedence 8
  581. 8, // op_equal
  582. 8, // op_not_equal
  583. // precedence 9
  584. 9, // op_less
  585. 9, // op_less_equal
  586. 9, // op_greater
  587. 9, // op_greater_equal
  588. // precedence 10
  589. 10, // op_shift_left
  590. 10, // op_shift_right
  591. // precedence 11
  592. 11, // op_plus
  593. 11, // op_minus
  594. // precedence 12
  595. 12, // op_times
  596. 12, // op_divide
  597. 12 // op_mod
  598. };
  599. }
  600. inline int precedence_of(token_ids::type op)
  601. {
  602. return precedence[op & 0xFF];
  603. }
  604. value compiler::compile_binary_expression(
  605. value lhs, value rhs, token_ids::type op)
  606. {
  607. switch (op)
  608. {
  609. case token_ids::plus: return lhs + rhs;
  610. case token_ids::minus: return lhs - rhs;
  611. case token_ids::times: return lhs * rhs;
  612. case token_ids::divide: return lhs / rhs;
  613. case token_ids::mod: return lhs % rhs;
  614. case token_ids::logical_or:
  615. case token_ids::bit_or: return lhs | rhs;
  616. case token_ids::logical_and:
  617. case token_ids::bit_and: return lhs & rhs;
  618. case token_ids::bit_xor: return lhs ^ rhs;
  619. case token_ids::shift_left: return lhs << rhs;
  620. case token_ids::shift_right: return lhs >> rhs;
  621. case token_ids::equal: return lhs == rhs;
  622. case token_ids::not_equal: return lhs != rhs;
  623. case token_ids::less: return lhs < rhs;
  624. case token_ids::less_equal: return lhs <= rhs;
  625. case token_ids::greater: return lhs > rhs;
  626. case token_ids::greater_equal: return lhs >= rhs;
  627. default: BOOST_ASSERT(0); return val();
  628. }
  629. }
  630. // The Shunting-yard algorithm
  631. value compiler::compile_expression(
  632. int min_precedence,
  633. value lhs,
  634. std::list<ast::operation>::const_iterator& rest_begin,
  635. std::list<ast::operation>::const_iterator rest_end)
  636. {
  637. while ((rest_begin != rest_end) &&
  638. (precedence_of(rest_begin->operator_) >= min_precedence))
  639. {
  640. token_ids::type op = rest_begin->operator_;
  641. value rhs = boost::apply_visitor(*this, rest_begin->operand_);
  642. if (!rhs.is_valid())
  643. return val();
  644. ++rest_begin;
  645. while ((rest_begin != rest_end) &&
  646. (precedence_of(rest_begin->operator_) > precedence_of(op)))
  647. {
  648. token_ids::type next_op = rest_begin->operator_;
  649. rhs = compile_expression(
  650. precedence_of(next_op), rhs, rest_begin, rest_end);
  651. }
  652. lhs = compile_binary_expression(lhs, rhs, op);
  653. }
  654. return lhs;
  655. }
  656. value compiler::operator()(ast::expression const& x)
  657. {
  658. value lhs = boost::apply_visitor(*this, x.first);
  659. if (!lhs.is_valid())
  660. return val();
  661. std::list<ast::operation>::const_iterator rest_begin = x.rest.begin();
  662. return compile_expression(0, lhs, rest_begin, x.rest.end());
  663. }
  664. value compiler::operator()(ast::assignment const& x)
  665. {
  666. if (locals.find(x.lhs.name) == locals.end())
  667. {
  668. error_handler(x.lhs.id, "Undeclared variable: " + x.lhs.name);
  669. return val();
  670. }
  671. value lhs = locals[x.lhs.name];
  672. value rhs = (*this)(x.rhs);
  673. if (!rhs.is_valid())
  674. return val();
  675. if (x.operator_ == token_ids::assign)
  676. {
  677. lhs.assign(rhs);
  678. return lhs;
  679. }
  680. value result;
  681. switch (x.operator_)
  682. {
  683. case token_ids::plus_assign: result = lhs + rhs; break;
  684. case token_ids::minus_assign: result = lhs - rhs; break;
  685. case token_ids::times_assign: result = lhs * rhs; break;
  686. case token_ids::divide_assign: result = lhs / rhs; break;
  687. case token_ids::mod_assign: result = lhs % rhs; break;
  688. case token_ids::bit_and_assign: result = lhs & rhs; break;
  689. case token_ids::bit_xor_assign: result = lhs ^ rhs; break;
  690. case token_ids::bit_or_assign: result = lhs | rhs; break;
  691. case token_ids::shift_left_assign: result = lhs << rhs; break;
  692. case token_ids::shift_right_assign: result = lhs >> rhs; break;
  693. default: BOOST_ASSERT(0); return val();
  694. }
  695. lhs.assign(result);
  696. return lhs;
  697. }
  698. bool compiler::operator()(ast::variable_declaration const& x)
  699. {
  700. if (locals.find(x.lhs.name) != locals.end())
  701. {
  702. error_handler(x.lhs.id, "Duplicate variable: " + x.lhs.name);
  703. return false;
  704. }
  705. value init;
  706. std::string const& name = x.lhs.name;
  707. if (x.rhs) // if there's an RHS initializer
  708. {
  709. init = (*this)(*x.rhs);
  710. if (!init.is_valid()) // don't add the variable if the RHS fails
  711. return false;
  712. }
  713. value var_ = var(name.c_str());
  714. if (init.is_valid())
  715. var_.assign(init);
  716. // Remember this binding.
  717. locals[name] = var_;
  718. return true;
  719. }
  720. struct compiler::statement_compiler : compiler
  721. {
  722. typedef bool result_type;
  723. };
  724. compiler::statement_compiler& compiler::as_statement()
  725. {
  726. return *static_cast<statement_compiler*>(this);
  727. }
  728. bool compiler::operator()(ast::statement const& x)
  729. {
  730. if (boost::get<ast::nil>(&x) != 0) // empty statement
  731. return true;
  732. return boost::apply_visitor(as_statement(), x);
  733. }
  734. bool compiler::operator()(ast::statement_list const& x)
  735. {
  736. BOOST_FOREACH(ast::statement const& s, x)
  737. {
  738. if (!(*this)(s))
  739. return false;
  740. }
  741. return true;
  742. }
  743. bool compiler::operator()(ast::if_statement const& x)
  744. {
  745. value condition = (*this)(x.condition);
  746. if (!condition.is_valid())
  747. return false;
  748. function f = get_current_function();
  749. // Create blocks for the then and else cases. Insert the 'then' block at the
  750. // end of the function.
  751. basic_block then_block = make_basic_block("if.then", f);
  752. basic_block else_block;
  753. basic_block exit_block;
  754. if (x.else_)
  755. {
  756. else_block = make_basic_block("if.else");
  757. conditional_branch(condition, then_block, else_block);
  758. }
  759. else
  760. {
  761. exit_block = make_basic_block("if.end");
  762. conditional_branch(condition, then_block, exit_block);
  763. }
  764. // Emit then value.
  765. set_insert_point(then_block);
  766. if (!(*this)(x.then))
  767. return false;
  768. if (!then_block.has_terminator())
  769. {
  770. if (!exit_block.is_valid())
  771. exit_block = make_basic_block("if.end");
  772. branch(exit_block);
  773. }
  774. // Codegen of 'then' can change the current block, update then_block
  775. then_block = get_insert_block();
  776. if (x.else_)
  777. {
  778. // Emit else block.
  779. f.add(else_block);
  780. set_insert_point(else_block);
  781. if (!(*this)(*x.else_))
  782. return false;
  783. if (!else_block.has_terminator())
  784. {
  785. if (!exit_block.is_valid())
  786. exit_block = make_basic_block("if.end");
  787. branch(exit_block);
  788. }
  789. // Codegen of 'else' can change the current block, update else_block
  790. else_block = get_insert_block();
  791. }
  792. if (exit_block.is_valid())
  793. {
  794. // Emit exit block
  795. f.add(exit_block);
  796. set_insert_point(exit_block);
  797. }
  798. return true;
  799. }
  800. bool compiler::operator()(ast::while_statement const& x)
  801. {
  802. function f = get_current_function();
  803. basic_block cond_block = make_basic_block("while.cond", f);
  804. basic_block body_block = make_basic_block("while.body");
  805. basic_block exit_block = make_basic_block("while.end");
  806. branch(cond_block);
  807. set_insert_point(cond_block);
  808. value condition = (*this)(x.condition);
  809. if (!condition.is_valid())
  810. return false;
  811. conditional_branch(condition, body_block, exit_block);
  812. f.add(body_block);
  813. set_insert_point(body_block);
  814. if (!(*this)(x.body))
  815. return false;
  816. if (!body_block.has_terminator())
  817. branch(cond_block); // loop back
  818. // Emit exit block
  819. f.add(exit_block);
  820. set_insert_point(exit_block);
  821. return true;
  822. }
  823. bool compiler::operator()(ast::return_statement const& x)
  824. {
  825. if (void_return)
  826. {
  827. if (x.expr)
  828. {
  829. error_handler(
  830. x.id, "'void' function returning a value: ");
  831. return false;
  832. }
  833. }
  834. else
  835. {
  836. if (!x.expr)
  837. {
  838. error_handler(
  839. x.id, current_function_name
  840. + " function must return a value: ");
  841. return false;
  842. }
  843. }
  844. if (x.expr)
  845. {
  846. value return_val = (*this)(*x.expr);
  847. if (!return_val.is_valid())
  848. return false;
  849. return_var.assign(return_val);
  850. }
  851. branch(return_block);
  852. return true;
  853. }
  854. function compiler::function_decl(ast::function const& x)
  855. {
  856. void_return = x.return_type == "void";
  857. current_function_name = x.function_name.name;
  858. function f =
  859. declare_function(
  860. void_return
  861. , current_function_name
  862. , x.args.size());
  863. // If function conflicted, the function already exixts. If it has a
  864. // body, don't allow redefinition or reextern.
  865. if (f.name() != current_function_name)
  866. {
  867. // Delete the one we just made and get the existing one.
  868. f.erase_from_parent();
  869. f = get_function(current_function_name);
  870. // If function already has a body, reject this.
  871. if (!f.empty())
  872. {
  873. error_handler(
  874. x.function_name.id,
  875. "Duplicate function: " + x.function_name.name);
  876. return function();
  877. }
  878. // If function took a different number of args, reject.
  879. if (f.arg_size() != x.args.size())
  880. {
  881. error_handler(
  882. x.function_name.id,
  883. "Redefinition of function with different # args: "
  884. + x.function_name.name);
  885. return function();
  886. }
  887. // Set names for all arguments.
  888. function::arg_range rng = f.args();
  889. function::arg_range::const_iterator iter = rng.begin();
  890. BOOST_FOREACH(ast::identifier const& arg, x.args)
  891. {
  892. iter->name(arg.name);
  893. ++iter;
  894. }
  895. }
  896. return f;
  897. }
  898. void compiler::function_allocas(ast::function const& x, function f)
  899. {
  900. // Create variables for each argument and register the
  901. // argument in the symbol table so that references to it will succeed.
  902. function::arg_range rng = f.args();
  903. function::arg_range::const_iterator iter = rng.begin();
  904. BOOST_FOREACH(ast::identifier const& arg, x.args)
  905. {
  906. // Create an arg_ for this variable.
  907. value arg_ = var(arg.name);
  908. // Store the initial value into the arg_.
  909. arg_.assign(*iter);
  910. // Add arguments to variable symbol table.
  911. locals[arg.name] = arg_;
  912. ++iter;
  913. }
  914. if (!void_return)
  915. {
  916. // Create an alloca for the return value
  917. return_var = var("return.val");
  918. }
  919. }
  920. bool compiler::operator()(ast::function const& x)
  921. {
  922. ///////////////////////////////////////////////////////////////////////
  923. // the signature:
  924. function f = function_decl(x);
  925. if (!f.is_valid())
  926. return false;
  927. ///////////////////////////////////////////////////////////////////////
  928. // the body:
  929. if (x.body) // compile the body if this is not a prototype
  930. {
  931. // Create a new basic block to start insertion into.
  932. basic_block block = make_basic_block("entry", f);
  933. set_insert_point(block);
  934. function_allocas(x, f);
  935. return_block = make_basic_block("return");
  936. if (!(*this)(*x.body))
  937. {
  938. // Error reading body, remove function.
  939. f.erase_from_parent();
  940. return false;
  941. }
  942. basic_block last_block = f.last_block();
  943. // If the last block is unterminated, connect it to return_block
  944. if (!last_block.has_terminator())
  945. {
  946. set_insert_point(last_block);
  947. branch(return_block);
  948. }
  949. f.add(return_block);
  950. set_insert_point(return_block);
  951. if (void_return)
  952. return_();
  953. else
  954. return_(return_var);
  955. // Validate the generated code, checking for consistency.
  956. f.verify();
  957. // Optimize the function.
  958. optimize_function(f);
  959. }
  960. return true;
  961. }
  962. bool compiler::operator()(ast::function_list const& x)
  963. {
  964. BOOST_FOREACH(ast::function const& f, x)
  965. {
  966. locals.clear(); // clear the variables
  967. if (!(*this)(f))
  968. return false;
  969. }
  970. return true;
  971. }
  972. }}