Advertisement
Guest User

Untitled

a guest
Dec 22nd, 2014
205
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 17.50 KB | None | 0 0
  1. /*-
  2. * Copyright (c) 2014 Katsuyuki Tateishi <kt@wheel.jp>
  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
  7. * are met:
  8. * 1. Redistributions of source code must retain the above copyright
  9. * notice, this list of conditions and the following disclaimer.
  10. * 2. Redistributions in binary form must reproduce the above copyright
  11. * notice, this list of conditions and the following disclaimer in the
  12. * documentation and/or other materials provided with the distribution.
  13. *
  14. * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
  15. * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  16. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  17. * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
  18. * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  19. * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  20. * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  21. * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  22. * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  23. * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  24. * SUCH DAMAGE.
  25. *
  26. */
  27. #define dbg(...) fprintf(stderr,__VA_ARGS__)
  28. #define dpr(x) cerr<<"*DBG: "<<#x<<": "<<x<<endl;
  29. #define dprc(c) do{cerr<<#c<<":";for(auto&_i:(c)){cerr<<" "<<_i;}cerr<<endl;}while(0)
  30. #include <bits/stdc++.h>
  31. using namespace std;
  32. typedef pair<int, int> pii;
  33. typedef vector<int> vi;
  34. typedef vector<vi> vvi;
  35. int INF = 1e9+7;
  36. #define all(c) begin(c), end(c)
  37. #define tr(i,c) for(auto i=begin(c);i!=end(c);i++)
  38. #define rtr(i,c) for(auto i=(c).rbegin();i!=(c).rend();i++)
  39. #define rep(i,b) for(auto i=0;i<(b);i++)
  40. #define pb push_back
  41. #define sz(c) int((c).size())
  42.  
  43. class LObj {
  44. public:
  45. virtual ~LObj() {}
  46. virtual string str() const = 0;
  47. template <typename T> T *rawptr() {
  48. return dynamic_cast<T *>(this);
  49. }
  50.  
  51. template <typename T> bool eqtype() {
  52. return typeid(T) == typeid(*this);
  53. }
  54.  
  55. template <typename T> bool isa() {
  56. return dynamic_cast<T *>(this) != nullptr;
  57. }
  58. };
  59.  
  60. typedef shared_ptr<LObj> lptr;
  61. typedef function<lptr(const lptr&)> primfunc_t;
  62. typedef function<lptr(const lptr&, const lptr&)> specialform_t;
  63.  
  64. lptr eval(const lptr& expr, const lptr& env);
  65.  
  66. bool eq(const lptr& l, const lptr& r) {
  67. return l.get() == r.get();
  68. }
  69.  
  70. template <typename T>
  71. bool eqtype(const lptr& p) {
  72. return typeid(T) == typeid(*p);
  73. }
  74.  
  75. template <typename T>
  76. T *rawptr(const lptr& p) {
  77. return dynamic_cast<T *>(p.get());
  78. }
  79.  
  80. template <typename T>
  81. bool isa(const lptr& p) {
  82. return rawptr<T>(p) != nullptr;
  83. }
  84.  
  85. class True : virtual public LObj {
  86. public:
  87. virtual string str() const { return "T"; }
  88. };
  89.  
  90. const lptr THE_T(new True());
  91.  
  92. class Error : public True {
  93. private:
  94. string name;
  95. public:
  96. Error(const string& s) : name(s) {}
  97. virtual string str() const {
  98. return "#<Error: " + name + ">";
  99. }
  100. };
  101.  
  102. lptr makeError(const string& s) {
  103. return lptr(new Error(s));
  104. }
  105.  
  106. class List : virtual public LObj {
  107. public:
  108. };
  109.  
  110. bool isList(const lptr& p) { return isa<List>(p); }
  111.  
  112. class Nil : public List {
  113. public:
  114. Nil() {}
  115. virtual string str() const { return string("NIL"); }
  116. };
  117. const lptr THE_NIL(new Nil());
  118.  
  119. bool isNIL(const lptr& p) { return eq(p, THE_NIL); }
  120.  
  121. class Cons : public True, public List {
  122. private:
  123. lptr car;
  124. lptr cdr;
  125. public:
  126. Cons(const lptr& a, const lptr& d) : car(a), cdr(d) {}
  127.  
  128. lptr getcar() const { return car; }
  129. lptr getcdr() const { return cdr; }
  130.  
  131. void setcar(const lptr& val) { car = val; }
  132. void setcdr(const lptr& val) { cdr = val; }
  133.  
  134. virtual string str() const {
  135. return string("(" + car->str() + " . " + cdr->str() + ")");
  136. }
  137. };
  138.  
  139. bool isCons(const lptr& p) {
  140. return eqtype<Cons>(p);
  141. }
  142.  
  143. lptr makeCons(const lptr& x, const lptr& y) {
  144. return lptr(new Cons(x, y));
  145. }
  146.  
  147. lptr prmcar(const lptr& p) {
  148. return p->rawptr<Cons>()->getcar();
  149. }
  150.  
  151. lptr prmcdr(const lptr& p) {
  152. return p->rawptr<Cons>()->getcdr();
  153. }
  154.  
  155. lptr prmcadr(const lptr& p) {
  156. return prmcar(prmcdr(p));
  157. }
  158.  
  159. lptr prmcons(const lptr& args) {
  160. return makeCons(prmcar(args), prmcadr(args));
  161. }
  162.  
  163. lptr set_car(const lptr& c, const lptr& val) {
  164. c->rawptr<Cons>()->setcar(val);
  165. return c;
  166. }
  167.  
  168. lptr prmset_car(const lptr& args) {
  169. return set_car(prmcar(args), prmcadr(args));
  170. }
  171.  
  172. lptr set_cdr(const lptr& c, const lptr& val) {
  173. c->rawptr<Cons>()->setcdr(val);
  174. return c;
  175. }
  176.  
  177. lptr prmset_cdr(const lptr& args) {
  178. return set_cdr(prmcar(args), prmcadr(args));
  179. }
  180.  
  181. lptr prmnreverse(const lptr& p) {
  182. lptr acc, lst, head, rest;
  183.  
  184. acc = THE_NIL;
  185. lst = p;
  186. while (!isNIL(lst)) {
  187. rest = prmcdr(lst);
  188. acc = set_cdr(lst, acc);
  189. lst = rest;
  190. }
  191. return acc;
  192. }
  193.  
  194. bool isAtom(const lptr& p) {
  195. return isNIL(p) || !isList(p);
  196. }
  197.  
  198. class String : public True {
  199. private:
  200. string val;
  201. public:
  202. String(const string& s) : val(s) {}
  203.  
  204. virtual string str() const {
  205. return val;
  206. }
  207. };
  208.  
  209. lptr makeString(const string& s) {
  210. return lptr(new String(s));
  211. }
  212.  
  213. class Fixnum : public True {
  214. private:
  215. int val;
  216. public:
  217. Fixnum(const string& s) {
  218. val = stoi(s);
  219. }
  220.  
  221. Fixnum(int i) {
  222. val = i;
  223. }
  224.  
  225. int value() {
  226. return val;
  227. }
  228.  
  229. virtual string str() const {
  230. return to_string(val);
  231. }
  232. };
  233.  
  234. lptr makeFixnum(const string& s) {
  235. return lptr(new Fixnum(s));
  236. }
  237.  
  238. class Symbol : public True {
  239. private:
  240. string name;
  241.  
  242. public:
  243. Symbol(string str) {
  244. name = str;
  245. }
  246.  
  247. virtual string str() const {
  248. return name;
  249. }
  250. };
  251.  
  252. bool isSymbol(const lptr& p) {
  253. return eqtype<Symbol>(p);
  254. }
  255.  
  256. unordered_map<string, const lptr> THE_SYMBOL_TABLE;
  257.  
  258. lptr makeSymbol(const string& s) {
  259. return lptr(new Symbol(s));
  260. }
  261.  
  262. lptr getSymbol(const string& s) {
  263. auto got = THE_SYMBOL_TABLE.find(s);
  264. if (got != end(THE_SYMBOL_TABLE)) {
  265. return got->second;
  266. } else {
  267. lptr res = makeSymbol(s);
  268. THE_SYMBOL_TABLE.emplace(s, res);
  269. return res;
  270. }
  271. }
  272.  
  273. class Env : public True {
  274. private:
  275. unordered_map<string, const lptr> hash;
  276. lptr parent;
  277. public:
  278. Env() : parent(THE_NIL) {}
  279. Env(const lptr& p) : parent(p) {}
  280.  
  281. lptr get(const string& s) {
  282. auto ret = hash.find(s);
  283. if (ret != end(hash)) {
  284. return ret->second;
  285. } else if (!isNIL(parent)) {
  286. return parent->rawptr<Env>()->get(s);
  287. } else {
  288. return makeError("Undefined symbol: " + s);
  289. }
  290. }
  291.  
  292. lptr get(const lptr& sym) {
  293. return get(sym->rawptr<Symbol>()->str());
  294. }
  295.  
  296. lptr set(const string& s, const lptr& val) {
  297. auto ret = hash.find(s);
  298. if (ret != end(hash)) {
  299. hash.emplace(s, val);
  300. return val;
  301. } else if (!isNIL(parent)) {
  302. return parent->rawptr<Env>()->set(s, val);
  303. } else {
  304. return makeError("Undefined symbol: " + s);
  305. }
  306. }
  307.  
  308. lptr set(const lptr& sym, const lptr& val) {
  309. return set(sym->rawptr<Symbol>()->str(), val);
  310. }
  311.  
  312. lptr define(const string& s, const lptr& val) {
  313. hash.emplace(s, val);
  314. return val;
  315. }
  316.  
  317. lptr define(const lptr& sym, const lptr& val) {
  318. return define(sym->rawptr<Symbol>()->str(), val);
  319. }
  320.  
  321. virtual string str() const {
  322. return string("#<Environment >");
  323. }
  324. };
  325.  
  326. template <typename T>
  327. lptr envget(const lptr& env, const T& sym) {
  328. return rawptr<Env>(env)->get(sym);
  329. }
  330.  
  331. template <typename T>
  332. lptr envset(const lptr& env, const T& sym, const lptr& val) {
  333. return rawptr<Env>(env)->set(sym, val);
  334. }
  335.  
  336. template <typename T>
  337. lptr envdefine(const lptr& env, const T& sym, const lptr& val) {
  338. return rawptr<Env>(env)->define(sym, val);
  339. }
  340.  
  341. lptr makeEnv(const lptr& parent) {
  342. return lptr(new Env(parent));
  343. }
  344.  
  345. lptr THE_ENVIRONMENT(new Env());
  346.  
  347. class Proc : public True {
  348. private:
  349. string name;
  350. public:
  351. Proc(const string& s) : name(s) {}
  352.  
  353. string getname() const { return name; }
  354.  
  355. void setname(const string& s) {
  356. name = s;
  357. }
  358.  
  359. virtual string str() const {
  360. return string("#<Procedure " + name + ">");
  361. }
  362.  
  363. virtual lptr apply(const lptr& values) const = 0;
  364. };
  365.  
  366. bool isProc(const lptr& p) {
  367. return isa<Proc>(p);
  368. }
  369.  
  370. bool isProcForm(const lptr& expr) {
  371. return isCons(expr) && isProc(prmcar(expr));
  372. }
  373.  
  374. class PrimitiveProc : public Proc {
  375. private:
  376. primfunc_t primproc;
  377. public:
  378. PrimitiveProc(const string& s, primfunc_t f) : Proc(s), primproc(f) {};
  379.  
  380. lptr apply(const lptr& values) const {
  381. return primproc(values);
  382. }
  383. };
  384.  
  385. lptr makePrimitiveProc(const string& name, primfunc_t f) {
  386. return lptr(new PrimitiveProc(name, f));
  387. }
  388.  
  389. lptr sf_begin(const lptr& args, const lptr& env);
  390. class CompoundProc : public Proc {
  391. private:
  392. lptr args;
  393. lptr body;
  394. lptr env;
  395. public:
  396. CompoundProc(const string& s, const lptr& a, const lptr& b, const lptr& e) :
  397. Proc(s), args(a), body(b), env(e) {}
  398.  
  399. lptr setupenv(const lptr& env, const lptr& args, const lptr& values) const {
  400. if (isNIL(args) && isNIL(values)) return THE_NIL;
  401. if (isNIL(args)) return makeError("Applying Procedure: Too much arguments");
  402. if (isNIL(values)) return makeError("Applying Procedure: Too few arguments");
  403. if (args->eqtype<Cons>()) {
  404. envdefine(env, prmcar(args), prmcar(values));
  405. return setupenv(env, prmcdr(args), prmcdr(values));
  406. } else {
  407. envdefine(env, args, values);
  408. return THE_NIL;
  409. }
  410. }
  411.  
  412. lptr apply(const lptr& values) const {
  413. lptr newenv = makeEnv(env);
  414. lptr status = setupenv(newenv, args, values);
  415. if (status->isa<Error>()) {
  416. return status;
  417. } else {
  418. return sf_begin(body, newenv);
  419. return eval(body, newenv);
  420. }
  421. }
  422. };
  423.  
  424. lptr makeCompoundProc(const string& name, const lptr& args,
  425. const lptr& body, const lptr& env) {
  426. return lptr(new CompoundProc(name, args, body, env));
  427. }
  428.  
  429. lptr prm_plus(const lptr& args) {
  430. lptr rest;
  431. int res = 0;
  432.  
  433. for (rest = args; !isNIL(rest); rest = prmcdr(rest)) {
  434. Fixnum *tmp = rawptr<Fixnum>(prmcar(rest));
  435. res += tmp->value();
  436. }
  437. return lptr(new Fixnum(res));
  438. }
  439.  
  440. lptr prm_multiply(const lptr& args) {
  441. lptr rest;
  442. int res = 1;
  443.  
  444. for (rest = args; !isNIL(rest); rest = prmcdr(rest)) {
  445. Fixnum *tmp = rawptr<Fixnum>(prmcar(rest));
  446. res *= tmp->value();
  447. }
  448. return lptr(new Fixnum(res));
  449. }
  450.  
  451. /*
  452. * Syntax
  453. */
  454. class Syntax : public True {
  455. private:
  456. string name;
  457. public:
  458. Syntax(const string& s) : name(s) {}
  459.  
  460. string getname() const { return name; }
  461.  
  462. void setname(const string& s) {
  463. name = s;
  464. }
  465.  
  466. virtual string str() const {
  467. return string("#<Syntax " + name + ">");
  468. }
  469.  
  470. virtual lptr eval_syntax(const lptr& expr, const lptr& env) const = 0;
  471. };
  472.  
  473. bool isSyntax(const lptr& p) {
  474. return isa<Syntax>(p);
  475. }
  476.  
  477. bool isSyntaxForm(const lptr& expr) {
  478. return isCons(expr) && isSyntax(prmcar(expr));
  479. }
  480.  
  481. class SpecialForm : public Syntax {
  482. private:
  483. specialform_t sf;
  484. public:
  485. SpecialForm(const string& s, specialform_t f) : Syntax(s), sf(f) {}
  486.  
  487. lptr eval_syntax(const lptr& expr, const lptr& env) const {
  488. return sf(expr, env);
  489. }
  490. };
  491.  
  492. lptr makeSpecialForm(const string& s, specialform_t f) {
  493. return lptr(new SpecialForm(s, f));
  494. }
  495.  
  496. lptr sf_begin(const lptr& args, const lptr& env) {
  497. lptr clause, lst, ret;
  498. ret = THE_NIL;
  499. for (lst = args; !isNIL(lst); lst = prmcdr(lst)) {
  500. ret = eval(prmcar(lst), env);
  501. }
  502. return ret;
  503. }
  504.  
  505. lptr sf_cond(const lptr& args, const lptr& env) {
  506. lptr clause, rest, cond;
  507.  
  508. for (rest = args; !isNIL(rest); rest = prmcdr(rest)) {
  509. clause = prmcar(rest);
  510. cond = eval(prmcar(clause), env);
  511. if (isNIL(cond)) continue;
  512. return sf_begin(prmcdr(clause), env);
  513. }
  514. return THE_NIL;
  515. }
  516.  
  517. lptr sf_quote(const lptr& args, const lptr& env) {
  518. return args;
  519. }
  520.  
  521. lptr sf_lambda(const lptr& args, const lptr& env) {
  522. return makeCompoundProc("Anonymous", prmcar(args), prmcdr(args), env);
  523. }
  524.  
  525. /*
  526. * Evaluator
  527. */
  528.  
  529. lptr eval_symbol(const lptr& sym, const lptr& env) {
  530. return envget(env, sym);
  531. }
  532.  
  533. lptr eval_apply_values(const lptr& expr, const lptr& env) {
  534. lptr acc, rest, tmp;
  535. for (acc = THE_NIL, rest = expr; !isNIL(rest); rest = prmcdr(rest)) {
  536. tmp = eval(prmcar(rest), env);
  537. if (eqtype<Error>(tmp)) return tmp;
  538. acc = makeCons(tmp, acc);
  539. }
  540.  
  541. //return acc;
  542. return prmnreverse(acc);
  543. }
  544.  
  545. lptr eval(const lptr& expr, const lptr& env) {
  546. if (isAtom(expr)) {
  547. if (isSymbol(expr)) return eval_symbol(expr, env);
  548. else return expr;
  549. } else {
  550. lptr car = eval(prmcar(expr), env);
  551. if (isa<Syntax>(car)) {
  552. return rawptr<Syntax>(car)->eval_syntax(prmcdr(expr), env);
  553. } else if (isa<Proc>(car)) {
  554. lptr av = eval_apply_values(prmcdr(expr), env);
  555. if (eqtype<Error>(av)) {
  556. return av;
  557. } else {
  558. //dpr(av->str());
  559. return rawptr<Proc>(car)->apply(av);
  560. }
  561. } else {
  562. return makeError("Cannot Evaluate: " + car->str());
  563. }
  564. }
  565. }
  566.  
  567. /*
  568. * Reader
  569. */
  570. lptr reader(istream& is);
  571.  
  572. void read_skip_space(istream& is) {
  573. char c;
  574.  
  575. while (is.get(c)) {
  576. if (!isspace(c)) {
  577. is.unget();
  578. break;
  579. }
  580. }
  581. }
  582.  
  583. lptr read_list(istream& is) {
  584. char c;
  585. lptr acc = THE_NIL;
  586.  
  587. while (is.get(c)) {
  588. if (c == ')') {
  589. break;
  590. } else {
  591. is.unget();
  592. acc = makeCons(reader(is), acc);
  593. }
  594. }
  595. return prmnreverse(acc);
  596. }
  597.  
  598. lptr read_symbol(istream& is) {
  599. char c;
  600. string token;
  601. bool fixnum = true;
  602. while (is.get(c)) {
  603. if (c == '(' || c == ')' || isspace(c)) {
  604. is.unget();
  605. break;
  606. }
  607. fixnum = (fixnum && isdigit(c));
  608. token.push_back(toupper(c));
  609. }
  610. if (fixnum) {
  611. return makeFixnum(token);
  612. } else {
  613. return getSymbol(token);
  614. }
  615. }
  616.  
  617. lptr read_string(istream& is) {
  618. char c;
  619. string token;
  620.  
  621. while (is.get(c)) {
  622. if (c == '\\') {
  623. is.get(c);
  624. } else if (c == '"') {
  625. break;
  626. }
  627. token.push_back(c);
  628. }
  629.  
  630. return makeString(token);
  631. }
  632.  
  633. lptr read_quote(istream& is, char q) {
  634. string quote;
  635.  
  636. switch (q) {
  637. case '\'':
  638. quote = "QUOTE";
  639. break;
  640. case '`':
  641. quote = "QUASIQUOTE";
  642. break;
  643. case ',':
  644. char c;
  645. is.get(c);
  646. if (c == '@') {
  647. quote = "UNQUOTE-SPLICING";
  648. } else {
  649. is.unget();
  650. quote = "UNQUOTE";
  651. }
  652. break;
  653. }
  654. return makeCons(getSymbol(quote), reader(is));
  655. }
  656.  
  657. lptr reader(istream& is) {
  658. char c;
  659.  
  660. read_skip_space(is);
  661. if (is.get(c)) {
  662. if (c == '(') {
  663. return read_list(is);
  664. } else if (c == ')') {
  665. return makeError("READ: Additional close paren.");
  666. } else if (c == '"') {
  667. return read_string(is);
  668. } else if (c == '\'' || c == '`' || c == ',') {
  669. return read_quote(is, c);
  670. } else {
  671. is.unget();
  672. return read_symbol(is);
  673. }
  674. }
  675. return makeError("READ: Recieve EOF.");
  676. }
  677.  
  678. /*
  679. * Printer
  680. */
  681. void printlptr(ostream& os, const lptr& p);
  682.  
  683. void printCons(ostream& os, const lptr& p) {
  684. lptr x = prmcar(p);
  685. lptr rest = prmcdr(p);
  686. printlptr(os, x);
  687. if (isNIL(rest)) {
  688. return;
  689. } else if (eqtype<Cons>(rest)) {
  690. os << " ";
  691. printCons(os, rest);
  692. } else {
  693. os << " . ";
  694. printlptr(os, rest);
  695. }
  696. }
  697.  
  698. void printString(ostream& os, const lptr& p) {
  699. for (auto& c:p->str()) {
  700. if (c == '"') os << '\\';
  701. os << c;
  702. }
  703. }
  704.  
  705. void printlptr(ostream& os, const lptr& p) {
  706. if (eqtype<Cons>(p)) {
  707. os << "(";
  708. printCons(os, p);
  709. os << ")";
  710. } else if (eqtype<String>(p)) {
  711. os << "\"";
  712. printString(os, p);
  713. os << "\"";
  714. } else {
  715. os << p->str();
  716. }
  717. }
  718.  
  719. ostream& operator<<(ostream& os, const lptr& p) {
  720. printlptr(os, p);
  721. return os;
  722. }
  723.  
  724.  
  725. void register_specialform(const string& name, specialform_t sf) {
  726. lptr sym = getSymbol(name);
  727. envdefine(THE_ENVIRONMENT, sym, makeSpecialForm(name, sf));
  728. }
  729.  
  730. void register_primitive_proc(const string& name, primfunc_t f) {
  731. lptr sym = getSymbol(name);
  732. envdefine(THE_ENVIRONMENT, sym, makePrimitiveProc(name, f));
  733. }
  734.  
  735. void setup_specialforms() {
  736. register_specialform("BEGIN", sf_begin);
  737. register_specialform("COND", sf_cond);
  738. register_specialform("QUOTE", sf_quote);
  739. register_specialform("LAMBDA", sf_lambda);
  740. }
  741.  
  742. void setup_primitive_procs() {
  743. register_primitive_proc("CAR", prmcar);
  744. register_primitive_proc("CDR", prmcdr);
  745. register_primitive_proc("CADR", prmcadr);
  746. register_primitive_proc("CONS", prmcons);
  747. register_primitive_proc("SET-CAR!", prmset_car);
  748. register_primitive_proc("SET-CDR!", prmset_cdr);
  749. register_primitive_proc("REVERSE!", prmnreverse);
  750. register_primitive_proc("+", prm_plus);
  751. register_primitive_proc("*", prm_multiply);
  752. }
  753.  
  754. void setup_self_evaluatings() {
  755. lptr sym;
  756.  
  757. sym = getSymbol("NIL");
  758. envdefine(THE_ENVIRONMENT, sym, THE_NIL);
  759. sym = getSymbol("T");
  760. envdefine(THE_ENVIRONMENT, sym, THE_T);
  761. }
  762.  
  763. void setup() {
  764. setup_self_evaluatings();
  765. setup_specialforms();
  766. setup_primitive_procs();
  767. }
  768.  
  769.  
  770. int main(int argc, char **argv) {
  771. setup();
  772. while (!cin.eof()) {
  773. cout << " * ";
  774. cout.flush();
  775. lptr val = reader(cin);
  776. //dpr(val->str());
  777. //cout << "-> " << val << endl;
  778. cout << "=> " << eval(val, THE_ENVIRONMENT) << endl;
  779. }
  780. /*
  781. lptr x = lptr(new Fixnum(10));
  782. lptr y = lptr(new Fixnum(1));
  783. lptr z = lptr(new Fixnum(3));
  784. lptr a = lptr(new Fixnum(5));
  785. lptr b = lptr(new Fixnum(7));
  786. lptr c = makeCons(x, makeCons(y, makeCons(z, makeCons(a, makeCons(b, THE_NIL)))));
  787.  
  788. dpr(THE_NIL);
  789.  
  790. dpr(x);
  791. dpr(x->eqtype<Fixnum>());
  792. dpr(eqtype<Fixnum>(x));
  793. dpr(eqtype<Cons>(x));
  794. cout << endl;
  795. dpr(y);
  796. cout << endl;
  797. dpr(c);
  798. c = prmnreverse(c);
  799. dpr(c);
  800. cout << endl;
  801. lptr d = makeCons(x, y);
  802. dpr(d);
  803. dpr(prmcar(d));
  804. dpr(prmcdr(d));
  805. lptr tmp = prmcar(d);
  806. set_car(d, prmcdr(d));
  807. set_cdr(d, tmp);
  808. dpr(d);
  809.  
  810. cout << endl;
  811. //dpr(prm_add_fixnum(x, y));
  812.  
  813. cout << endl;
  814. envdefine(THE_ENVIRONMENT, "LST", c);
  815. dpr(envget(THE_ENVIRONMENT, "LST"));
  816. dpr(envget(THE_ENVIRONMENT, "CAR"));
  817.  
  818. lptr op = getSymbol("CONS");
  819. lptr form = makeCons(op, makeCons(x, makeCons(b, THE_NIL)));
  820. dpr(form);
  821. dpr(eval(form, THE_ENVIRONMENT));
  822. */
  823.  
  824. return 0;
  825. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement