summaryrefslogtreecommitdiff
path: root/Build/source/utils/asymptote/item.h
diff options
context:
space:
mode:
Diffstat (limited to 'Build/source/utils/asymptote/item.h')
-rw-r--r--Build/source/utils/asymptote/item.h201
1 files changed, 201 insertions, 0 deletions
diff --git a/Build/source/utils/asymptote/item.h b/Build/source/utils/asymptote/item.h
new file mode 100644
index 00000000000..9df090cc948
--- /dev/null
+++ b/Build/source/utils/asymptote/item.h
@@ -0,0 +1,201 @@
+/*****
+ * inst.h
+ * Tom Prince and John Bowman 2005/04/12
+ *
+ * Descibes the items that are used by the virtual machine.
+ *****/
+
+#ifndef ITEM_H
+#define ITEM_H
+
+#include "common.h"
+#include <typeinfo>
+
+
+namespace vm {
+
+class item;
+class bad_item_value {};
+
+template<typename T>
+T get(const item&);
+
+class item : public gc {
+public:
+ bool empty()
+ { return *kind == typeid(void); }
+
+ item()
+ : kind(&typeid(void)) {}
+
+#ifndef Int
+ item(Int i)
+ : kind(&typeid(Int)), i(i) {}
+#endif
+ item(int i)
+ : kind(&typeid(Int)), i(i) {}
+ item(double x)
+ : kind(&typeid(double)), x(x) {}
+ item(bool b)
+ : kind(&typeid(bool)), b(b) {}
+
+#ifndef Int
+ item& operator= (int a)
+ { kind=&typeid(Int); i=a; return *this; }
+#endif
+ item& operator= (Int a)
+ { kind=&typeid(Int); i=a; return *this; }
+ item& operator= (double a)
+ { kind=&typeid(double); x=a; return *this; }
+ item& operator= (bool a)
+ { kind=&typeid(bool); b=a; return *this; }
+
+ template<class T>
+ item(T *p)
+ : kind(&typeid(T)), p((void *) p) {}
+
+ template<class T>
+ item(const T &p)
+ : kind(&typeid(T)), p(new(UseGC) T(p)) {}
+
+ template<class T>
+ item& operator= (T *a)
+ { kind=&typeid(T); p=(void *) a; return *this; }
+
+ template<class T>
+ item& operator= (const T &it)
+ { kind=&typeid(T); p=new(UseGC) T(it); return *this; }
+
+ template<typename T>
+ friend inline T get(const item&);
+
+ friend inline bool isdefault(const item&);
+ friend inline bool isarray(const item&);
+
+ const std::type_info &type() const
+ { return *kind; }
+
+ friend ostream& operator<< (ostream& out, const item& i);
+
+private:
+
+ const std::type_info *kind;
+
+ union {
+ Int i;
+ double x;
+ bool b;
+ void *p;
+ };
+
+ template <typename T>
+ struct help;
+
+ template <typename T>
+ struct help<T*> {
+ static T* unwrap(const item& it)
+ {
+ if (*it.kind == typeid(T))
+ return (T*) it.p;
+ throw vm::bad_item_value();
+ }
+ };
+
+ template <typename T>
+ struct help {
+ static T& unwrap(const item& it)
+ {
+ if (*it.kind == typeid(T))
+ return *(T*) it.p;
+ throw vm::bad_item_value();
+ }
+ };
+};
+
+class frame : public gc {
+ typedef mem::vector<item> vars_t;
+ vars_t vars;
+public:
+ frame(size_t size)
+ : vars(size)
+ {}
+
+ item& operator[] (size_t n)
+ { return vars[n]; }
+ item operator[] (size_t n) const
+ { return vars[n]; }
+
+ size_t size()
+ { return vars.size(); }
+
+ // Extends vars to ensure it has a place for any variable indexed up to n.
+ void extend(size_t n) {
+ if (vars.size() < n)
+ vars.resize(n);
+ }
+};
+
+template<typename T>
+inline T get(const item& it)
+{
+ return item::help<T>::unwrap(it);
+}
+
+#ifndef Int
+template <>
+inline int get<int>(const item&)
+{
+ throw vm::bad_item_value();
+}
+#endif
+
+template <>
+inline Int get<Int>(const item& it)
+{
+ if (*it.kind == typeid(Int))
+ return it.i;
+ throw vm::bad_item_value();
+}
+
+template <>
+inline double get<double>(const item& it)
+{
+ if (*it.kind == typeid(double))
+ return it.x;
+ throw vm::bad_item_value();
+}
+
+template <>
+inline bool get<bool>(const item& it)
+{
+ if (*it.kind == typeid(bool))
+ return it.b;
+ throw vm::bad_item_value();
+}
+
+// This serves as the object for representing a default argument.
+struct default_t : public gc {};
+
+inline bool isdefault(const item& it)
+{
+ return *it.kind == typeid(default_t);
+}
+
+inline ostream& operator<< (ostream& out, const item& i)
+{
+ out << "type " << i.type().name();
+ if (i.type() == typeid(Int))
+ cout << ", value = " << get<Int>(i) << endl;
+ else if (i.type() == typeid(double))
+ cout << ", value = " << get<double>(i) << endl;
+ else if (i.type() == typeid(string))
+ cout << ", value = " << get<string>(i) << endl;
+ else out << endl;
+ return out;
+}
+
+} // namespace vm
+
+GC_DECLARE_PTRFREE(vm::default_t);
+
+#endif // ITEM_H