Mercurial > hg > Members > nobuyasu > SampleSource
diff WindowsOnly/WinScript2/vm_value.h @ 0:db40c85cad7a default tip
upload sample source
author | nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp> |
---|---|
date | Mon, 09 May 2011 03:11:59 +0900 |
parents | |
children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/WindowsOnly/WinScript2/vm_value.h Mon May 09 03:11:59 2011 +0900 @@ -0,0 +1,185 @@ +#ifndef __vm_value_h__ +#define __vm_value_h__ + +#include <iostream> +#include <exception> +#include <string> + +namespace vm { + + // 参照カウンタ付きstring + class string { + public: + string(): ref_(0) + { + } + string(const std::string &str): ref_(1), str_(str) + { + } + + void addref() + { + ref_++; + } + + void release() + { + if (--ref_ == 0) + delete this; + } + + public: + int ref_; + std::string str_; + } ; + + // 変数 + class value { + enum { + type_integer, + type_string, + } ; + + public: + value() + { + s_ = 0; + type_ = type_integer; + } + + value(int ival) + { + i_ = ival; + type_ = type_integer; + } + + value(const std::string &str) + { + s_ = new string(str); + type_ = type_string; + } + + value(string *p) + { + s_ = p; + type_ = type_string; + } + + ~value() + { + clear(); + } + + value(const value &a) + { + copy(a); + } + + value& operator=(const value &a) + { + if (this == &a) + return *this; + + clear(); + copy(a); + + return *this; + } + + void clear() + { + if (type_ == type_string) + s_->release(); + } + + void copy(const value &a) + { + type_ = a.type_; + s_ = a.s_; + if (type_ == type_string) + s_->addref(); + } + + public: + union { + string *s_; + int i_; + } ; + char type_; + } ; + + class stack_overflow: public std::exception { + public: + const char *what() const throw() + { + return "stack overflow"; + } + } ; + + // 固定サイズのスタック + // スタックオーバーフローの場合は例外を送出 + + template< typename Ty, int Size > + class stack { + public: + stack(): size_(0) + { + } + + ~stack() + { + resize(0); + } + + void push(const Ty& value) + { + if (Size <= size_) + throw stack_overflow(); + *(::new(data_[size_++]) Ty) = value; + } + + void pop() + { + ((Ty *)data_[--size_])->~Ty(); + } + + void pop(int count) + { + resize(size_ - count); + } + + void resize(int newsize) + { + int oldsize = size_; + + if (oldsize > newsize) { + for (int i = newsize; i < oldsize; ++i) + ((Ty *)data_[i])->~Ty(); + } + if (oldsize < newsize) { + if (Size < newsize) + throw stack_overflow(); + for (int i = oldsize; i < newsize; ++i) + ::new(data_[i]) Ty; + } + size_ = newsize; + } + + const Ty& top() const { return *(const Ty *)data_[size_ - 1]; } + Ty& top() { return *(Ty *)data_[size_ - 1]; } + + bool overflow() const { return size_ >= Size; } + bool empty() const { return size_ == 0; } + int size() const { return size_; } + + const Ty& operator[](int index) const { return *(const Ty *)data_[index]; } + Ty& operator[](int index) { return *(Ty *)data_[index]; } + + protected: + char data_[Size][sizeof(Ty)]; + int size_; + } ; + +} // namespace + +#endif