86 lines
		
	
	
		
			1.6 KiB
		
	
	
	
		
			C++
		
	
	
		
			Executable File
		
	
			
		
		
	
	
			86 lines
		
	
	
		
			1.6 KiB
		
	
	
	
		
			C++
		
	
	
		
			Executable File
		
	
| namespace factor
 | |
| {
 | |
| 
 | |
| template<typename Type> cell tag(Type *value)
 | |
| {
 | |
| 	return RETAG(value,Type::type_number);
 | |
| }
 | |
| 
 | |
| inline static cell tag_dynamic(object *value)
 | |
| {
 | |
| 	return RETAG(value,value->type());
 | |
| }
 | |
| 
 | |
| template<typename Type>
 | |
| struct tagged
 | |
| {
 | |
| 	cell value_;
 | |
| 
 | |
| 	cell type() const
 | |
| 	{
 | |
| 		return TAG(value_);
 | |
| 	}
 | |
| 
 | |
| 	bool type_p(cell type_) const
 | |
| 	{
 | |
| 		return type() == type_;
 | |
| 	}
 | |
| 
 | |
| 	bool type_p() const
 | |
| 	{
 | |
| 		if(Type::type_number == TYPE_COUNT)
 | |
| 			return true;
 | |
| 		else
 | |
| 			return type_p(Type::type_number);
 | |
| 	}
 | |
| 
 | |
| 	cell value() const
 | |
| 	{
 | |
| #ifdef FACTOR_DEBUG
 | |
| 		assert(type_p());
 | |
| #endif
 | |
| 		return value_;
 | |
| 	}
 | |
| 
 | |
| 	Type *untagged() const
 | |
| 	{
 | |
| #ifdef FACTOR_DEBUG
 | |
| 		assert(type_p());
 | |
| #endif
 | |
| 		return (Type *)(UNTAG(value_));
 | |
| 	}
 | |
| 
 | |
| 	Type *untag_check(factor_vm *parent) const
 | |
| 	{
 | |
| 		if(!type_p())
 | |
| 			parent->type_error(Type::type_number,value_);
 | |
| 		return untagged();
 | |
| 	}
 | |
| 
 | |
| 	explicit tagged(cell tagged) : value_(tagged) {}
 | |
| 	explicit tagged(Type *untagged) : value_(factor::tag(untagged)) {}
 | |
| 
 | |
| 	Type *operator->() const { return untagged(); }
 | |
| 	cell *operator&() const { return &value_; }
 | |
| 
 | |
| 	const tagged<Type> &operator=(const Type *x) { value_ = tag(x); return *this; }
 | |
| 	const tagged<Type> &operator=(const cell &x) { value_ = x; return *this; }
 | |
| 
 | |
| 	bool operator==(const tagged<Type> &x) { return value_ == x.value_; }
 | |
| 	bool operator!=(const tagged<Type> &x) { return value_ != x.value_; }
 | |
| 
 | |
| 	template<typename NewType> tagged<NewType> as() { return tagged<NewType>(value_); }
 | |
| };
 | |
| 
 | |
| template<typename Type> Type *factor_vm::untag_check(cell value)
 | |
| {
 | |
| 	return tagged<Type>(value).untag_check(this);
 | |
| }
 | |
| 
 | |
| template<typename Type> Type *untag(cell value)
 | |
| {
 | |
| 	return tagged<Type>(value).untagged();
 | |
| }
 | |
| 
 | |
| }
 |