Advertisement
anacrolix

fuck c++

May 6th, 2012
113
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 4.34 KB | None | 0 0
  1. #pragma once
  2.  
  3. #include <vector>
  4. #include <unordered_map>
  5. #include <typeinfo>
  6. #include <string>
  7. #include <assert.h>
  8. #include <string.h>
  9. #include <stdio.h>
  10. #include <stdlib.h>
  11.  
  12. using std::unordered_map;
  13. using std::vector;
  14. using std::make_pair;
  15.  
  16. class Env;
  17. class Print;
  18.  
  19. class Error {
  20. };
  21.  
  22. template<typename T>
  23. class Ref
  24. {
  25. public:
  26.     Ref() : t_(nullptr) {}
  27.  
  28.     Ref(T *t) :
  29.         t_(t)
  30.     {
  31.         t_->ref();
  32.     }
  33.  
  34.     Ref(T &t)
  35.         :   t_(&t)
  36.     {
  37.     }
  38.  
  39.     template<typename U> Ref(Ref<U> &ru) :
  40.         t_(&*ru)
  41.     {
  42.         t_->ref();
  43.     }
  44.     T &operator*() const {
  45.         return *t_;
  46.     }
  47.     T *operator->() const
  48.     {
  49.         return t_;
  50.     }
  51.     operator T &() const
  52.     {
  53.         return *t_;
  54.     }
  55.     operator T *() const {
  56.         return t_;
  57.     }
  58. private:
  59.     T *t_;
  60. };
  61.  
  62. class Node
  63. {
  64. public:
  65.     template<typename T, typename ...Args>
  66.         static
  67.         Ref<T> make(Args ...args)
  68.     {
  69.         return new T(args...);
  70.     }
  71.  
  72.     template<typename To, typename From>
  73.     static To *cast(From *from) {
  74.         To *ret = dynamic_cast<To *>(from);
  75.         if (!ret) throw Error();
  76.         return ret;
  77.     }
  78.  
  79.     void ref() {
  80.         refs++;
  81.     }
  82.     void deref() {
  83.         assert(refs > 0);
  84.         if (--refs > 0) return;
  85.         delete this;
  86.     }
  87.     virtual void print(Print &) const = 0;
  88.     virtual Ref<Node> eval(Env &) {
  89.         return this;
  90.     }
  91.     virtual Ref<Node> apply(vector<Node *>, Env &) {
  92.         throw Error();
  93.     }
  94. private:
  95.     int refs;
  96. };
  97.  
  98. enum class Token {
  99.     RightParen,
  100. };
  101.  
  102. class Print
  103. {
  104. public:
  105.     Print(FILE *file) :
  106.         file_(file)
  107.     {
  108.     }
  109.  
  110.     void atom(char const *format, ...)
  111.     {
  112.     }
  113.  
  114.     void token(Token t) {
  115.         print_space_if_required(t);
  116.         switch (t) {
  117.         case Token::RightParen:
  118.             fputc(')', file_);
  119.             break;
  120.         }
  121.         last_token_ = t;
  122.     }
  123. private:
  124.     void print_space_if_required(Token t) {
  125.         switch (last_token_) {
  126.         }
  127.     }
  128.     FILE *file_;
  129.     Token last_token_;
  130. };
  131.  
  132. class Symbol : public Node {
  133. public:
  134.     Symbol(char const *s)
  135.         : s_(s) {}
  136.     void print(Print &print) const {
  137.         print.atom("%s", s_.c_str());
  138.     }
  139.     size_t hash() const {
  140.         return std::hash<std::string>()(s_);
  141.     }
  142. private:
  143.     std::string s_;
  144. };
  145.  
  146. size_t hash_symbol(Symbol const &sym) {
  147.     return sym.hash();
  148. }
  149.  
  150. class Env : public Node {
  151. public:
  152.     virtual void define(Symbol &, Node *) = 0;
  153.     void define(char const *s, Node *value) {
  154.         define(Node::make<Symbol>(s), value);
  155.     }
  156. };
  157.  
  158. class Lexer
  159. {
  160. public:
  161.     Lexer(FILE *file) :
  162.         file_(file)
  163.     {
  164.     }
  165. private:
  166.     FILE *file_;
  167. };
  168.  
  169. Ref<Node> parse(Lexer &) {
  170. }
  171.  
  172. class GlobalEnv : public Env
  173. {
  174.     virtual void print(Print &print) const
  175.     {
  176.         print.atom("#(%s", typeid(*this).name());
  177.         for (auto const &i : vars_) {
  178.             i.first->print(print);
  179.             i.second->print(print);
  180.         }
  181.         print.token(Token::RightParen);
  182.     }
  183.  
  184.     virtual void define(Symbol &name, Node *value)
  185.     {
  186.         vars_.insert(make_pair<Ref<Symbol>, Ref<Node>>(name, value));
  187.     }
  188.  
  189.  
  190. private:
  191.     unordered_map<Ref<Symbol>, Ref<Node>, &hash_symbol> vars_;
  192. };
  193.  
  194. class Primitive : public Node {
  195. public:
  196.     typedef Ref<Node> (*ApplyFunc)(vector<Node *>, Env &);
  197.     Primitive(char const *name, ApplyFunc af)
  198.         : name_(name),
  199.           apply_func_(af)
  200.     {
  201.     }
  202.     void print(Print &print) const {
  203.         print.atom("#(%s", typeid(*this).name());
  204.         print.atom("%s", name_);
  205.         print.token(Token::RightParen);
  206.     }
  207. private:
  208.     char const *name_;
  209.     ApplyFunc apply_func_;
  210. };
  211.  
  212. void add_primitive(Env &env, char const *name, Primitive::ApplyFunc func)
  213. {
  214.     env.define(name, Node::make<Primitive>(name, func));
  215. }
  216.  
  217. Ref<Node> apply_define(vector<Node *> args, Env &env) {
  218.     Ref<Node> value;
  219.     Symbol *name;
  220.     switch (args.size()) {
  221.     case 2:
  222.         value = args[1]->eval(env);
  223.     case 1:
  224.         name = Node::cast<Symbol>(args[0]);
  225.         break;
  226.     default:
  227.         throw Error();
  228.     }
  229.     env.define(*name, value);
  230. }
  231.  
  232. Ref<Env> make_global_env()
  233. {
  234.     auto ret = Node::make<GlobalEnv>();
  235.     add_primitive(ret, "__define", apply_define);
  236.     return ret;
  237. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement