]> gitweb.factorcode.org Git - factor.git/blob - vm/tagged.hpp
vm: use iostreams instead of printf for debug messages, clean up a few things
[factor.git] / vm / tagged.hpp
1 namespace factor
2 {
3
4 template<typename Type> cell tag(Type *value)
5 {
6         return RETAG(value,tag_for(Type::type_number));
7 }
8
9 inline static cell tag_dynamic(object *value)
10 {
11         return RETAG(value,tag_for(value->h.hi_tag()));
12 }
13
14 template<typename Type>
15 struct tagged
16 {
17         cell value_;
18
19         cell value() const { return value_; }
20         Type *untagged() const { return (Type *)(UNTAG(value_)); }
21
22         cell type() const {
23                 cell tag = TAG(value_);
24                 if(tag == OBJECT_TYPE)
25                         return untagged()->h.hi_tag();
26                 else
27                         return tag;
28         }
29
30         bool type_p(cell type_) const
31         {
32                 return type() == type_;
33         }
34
35         bool type_p() const
36         {
37                 if(Type::type_number == TYPE_COUNT)
38                         return true;
39                 else
40                         return type_p(Type::type_number);
41         }
42
43         Type *untag_check(factor_vm *parent) const {
44                 if(!type_p())
45                         parent->type_error(Type::type_number,value_);
46                 return untagged();
47         }
48
49         explicit tagged(cell tagged) : value_(tagged) {
50 #ifdef FACTOR_DEBUG
51                 assert(type_p());
52 #endif
53         }
54
55         explicit tagged(Type *untagged) : value_(factor::tag(untagged)) {
56 #ifdef FACTOR_DEBUG
57                 assert(type_p());
58 #endif
59         }
60
61         Type *operator->() const { return untagged(); }
62         cell *operator&() const { return &value_; }
63
64         const tagged<Type> &operator=(const Type *x) { value_ = tag(x); return *this; }
65         const tagged<Type> &operator=(const cell &x) { value_ = x; return *this; }
66
67         bool operator==(const tagged<Type> &x) { return value_ == x.value_; }
68         bool operator!=(const tagged<Type> &x) { return value_ != x.value_; }
69
70         template<typename NewType> tagged<NewType> as() { return tagged<NewType>(value_); }
71 };
72
73 template<typename Type> Type *factor_vm::untag_check(cell value)
74 {
75         return tagged<Type>(value).untag_check(this);
76 }
77
78 template<typename Type> Type *untag(cell value)
79 {
80         return tagged<Type>(value).untagged();
81 }
82
83 }