mirror of
				https://github.com/ton-blockchain/ton
				synced 2025-03-09 15:40:10 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			200 lines
		
	
	
	
		
			5.3 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			200 lines
		
	
	
	
		
			5.3 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
/*
 | 
						|
    This file is part of TON Blockchain Library.
 | 
						|
 | 
						|
    TON Blockchain Library is free software: you can redistribute it and/or modify
 | 
						|
    it under the terms of the GNU Lesser General Public License as published by
 | 
						|
    the Free Software Foundation, either version 2 of the License, or
 | 
						|
    (at your option) any later version.
 | 
						|
 | 
						|
    TON Blockchain Library is distributed in the hope that it will be useful,
 | 
						|
    but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
						|
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
						|
    GNU Lesser General Public License for more details.
 | 
						|
 | 
						|
    You should have received a copy of the GNU Lesser General Public License
 | 
						|
    along with TON Blockchain Library.  If not, see <http://www.gnu.org/licenses/>.
 | 
						|
 | 
						|
    Copyright 2017-2020 Telegram Systems LLP
 | 
						|
*/
 | 
						|
#pragma once
 | 
						|
 | 
						|
#include <functional>
 | 
						|
#include <map>
 | 
						|
 | 
						|
#include "IntCtx.h"
 | 
						|
#include "Continuation.h"
 | 
						|
 | 
						|
namespace fift {
 | 
						|
using td::Ref;
 | 
						|
 | 
						|
/*
 | 
						|
 *
 | 
						|
 *    WORD CLASSES
 | 
						|
 *
 | 
						|
 */
 | 
						|
 | 
						|
typedef std::function<void(vm::Stack&)> StackWordFunc;
 | 
						|
typedef std::function<void(IntCtx&)> CtxWordFunc;
 | 
						|
 | 
						|
class StackWord : public FiftCont {
 | 
						|
  StackWordFunc f;
 | 
						|
 | 
						|
 public:
 | 
						|
  StackWord(StackWordFunc _f) : f(std::move(_f)) {
 | 
						|
  }
 | 
						|
  ~StackWord() override = default;
 | 
						|
  Ref<FiftCont> run_tail(IntCtx& ctx) const override;
 | 
						|
};
 | 
						|
 | 
						|
class CtxWord : public FiftCont {
 | 
						|
  CtxWordFunc f;
 | 
						|
 | 
						|
 public:
 | 
						|
  CtxWord(CtxWordFunc _f) : f(std::move(_f)) {
 | 
						|
  }
 | 
						|
  ~CtxWord() override = default;
 | 
						|
  Ref<FiftCont> run_tail(IntCtx& ctx) const override;
 | 
						|
};
 | 
						|
 | 
						|
typedef std::function<Ref<FiftCont>(IntCtx&)> CtxTailWordFunc;
 | 
						|
 | 
						|
class CtxTailWord : public FiftCont {
 | 
						|
  CtxTailWordFunc f;
 | 
						|
 | 
						|
 public:
 | 
						|
  CtxTailWord(CtxTailWordFunc _f) : f(std::move(_f)) {
 | 
						|
  }
 | 
						|
  ~CtxTailWord() override = default;
 | 
						|
  Ref<FiftCont> run_tail(IntCtx& ctx) const override;
 | 
						|
};
 | 
						|
 | 
						|
class WordList : public FiftCont {
 | 
						|
  std::vector<Ref<FiftCont>> list;
 | 
						|
 | 
						|
 public:
 | 
						|
  ~WordList() override = default;
 | 
						|
  WordList() = default;
 | 
						|
  WordList(std::vector<Ref<FiftCont>>&& _list);
 | 
						|
  WordList(const std::vector<Ref<FiftCont>>& _list);
 | 
						|
  WordList& push_back(Ref<FiftCont> word_def);
 | 
						|
  WordList& push_back(FiftCont& wd);
 | 
						|
  Ref<FiftCont> run_tail(IntCtx& ctx) const override;
 | 
						|
  void close();
 | 
						|
  bool is_list() const override {
 | 
						|
    return true;
 | 
						|
  }
 | 
						|
  long long list_size() const override {
 | 
						|
    return (long long)list.size();
 | 
						|
  }
 | 
						|
  std::size_t size() const {
 | 
						|
    return list.size();
 | 
						|
  }
 | 
						|
  const Ref<FiftCont>& at(std::size_t idx) const {
 | 
						|
    return list.at(idx);
 | 
						|
  }
 | 
						|
  const Ref<FiftCont>* get_list() const override {
 | 
						|
    return list.data();
 | 
						|
  }
 | 
						|
  WordList& append(const std::vector<Ref<FiftCont>>& other);
 | 
						|
  WordList& append(const Ref<FiftCont>* begin, const Ref<FiftCont>* end);
 | 
						|
  WordList* make_copy() const override {
 | 
						|
    return new WordList(list);
 | 
						|
  }
 | 
						|
  bool dump(std::ostream& os, const IntCtx& ctx) const override;
 | 
						|
};
 | 
						|
 | 
						|
class ListCont : public FiftCont {
 | 
						|
  Ref<FiftCont> next;
 | 
						|
  Ref<WordList> list;
 | 
						|
  std::size_t pos;
 | 
						|
 | 
						|
 public:
 | 
						|
  ListCont(Ref<FiftCont> nxt, Ref<WordList> wl, std::size_t p = 0) : next(std::move(nxt)), list(std::move(wl)), pos(p) {
 | 
						|
  }
 | 
						|
  ~ListCont() override = default;
 | 
						|
  Ref<FiftCont> run_tail(IntCtx& ctx) const override;
 | 
						|
  Ref<FiftCont> run_modify(IntCtx& ctx) override;
 | 
						|
  Ref<FiftCont> up() const override {
 | 
						|
    return next;
 | 
						|
  }
 | 
						|
  bool dump(std::ostream& os, const IntCtx& ctx) const override;
 | 
						|
};
 | 
						|
 | 
						|
class DictEntry {
 | 
						|
  Ref<FiftCont> def;
 | 
						|
  bool active;
 | 
						|
 | 
						|
 public:
 | 
						|
  DictEntry() = delete;
 | 
						|
  DictEntry(const DictEntry& ref) = default;
 | 
						|
  DictEntry(DictEntry&& ref) = default;
 | 
						|
  DictEntry(Ref<FiftCont> _def, bool _act = false) : def(std::move(_def)), active(_act) {
 | 
						|
  }
 | 
						|
  DictEntry(StackWordFunc func);
 | 
						|
  DictEntry(CtxWordFunc func, bool _act = false);
 | 
						|
  DictEntry(CtxTailWordFunc func, bool _act = false);
 | 
						|
  //DictEntry(const std::vector<Ref<FiftCont>>& word_list);
 | 
						|
  //DictEntry(std::vector<Ref<FiftCont>>&& word_list);
 | 
						|
  DictEntry& operator=(const DictEntry&) = default;
 | 
						|
  DictEntry& operator=(DictEntry&&) = default;
 | 
						|
  Ref<FiftCont> get_def() const& {
 | 
						|
    return def;
 | 
						|
  }
 | 
						|
  Ref<FiftCont> get_def() && {
 | 
						|
    return std::move(def);
 | 
						|
  }
 | 
						|
  bool is_active() const {
 | 
						|
    return active;
 | 
						|
  }
 | 
						|
};
 | 
						|
 | 
						|
/*
 | 
						|
DictEntry::DictEntry(const std::vector<Ref<FiftCont>>& word_list) : def(Ref<WordList>{true, word_list}) {
 | 
						|
}
 | 
						|
 | 
						|
DictEntry::DictEntry(std::vector<Ref<FiftCont>>&& word_list) : def(Ref<WordList>{true, std::move(word_list)}) {
 | 
						|
}
 | 
						|
*/
 | 
						|
 | 
						|
/*
 | 
						|
 *
 | 
						|
 *    DICTIONARIES
 | 
						|
 *
 | 
						|
 */
 | 
						|
 | 
						|
class Dictionary {
 | 
						|
 public:
 | 
						|
  DictEntry* lookup(td::Slice name);
 | 
						|
  void def_ctx_word(std::string name, CtxWordFunc func);
 | 
						|
  void def_ctx_tail_word(std::string name, CtxTailWordFunc func);
 | 
						|
  void def_active_word(std::string name, CtxWordFunc func);
 | 
						|
  void def_stack_word(std::string name, StackWordFunc func);
 | 
						|
  void def_word(std::string name, DictEntry word);
 | 
						|
  void undef_word(td::Slice name);
 | 
						|
  bool lookup_def(const FiftCont* cont, std::string* word_ptr = nullptr) const;
 | 
						|
  bool lookup_def(Ref<FiftCont> cont, std::string* word_ptr = nullptr) const {
 | 
						|
    return lookup_def(cont.get(), word_ptr);
 | 
						|
  }
 | 
						|
  auto begin() const {
 | 
						|
    return words_.begin();
 | 
						|
  }
 | 
						|
  auto end() const {
 | 
						|
    return words_.end();
 | 
						|
  }
 | 
						|
 | 
						|
  static Ref<FiftCont> nop_word_def;
 | 
						|
 | 
						|
 private:
 | 
						|
  std::map<std::string, DictEntry, std::less<>> words_;
 | 
						|
};
 | 
						|
 | 
						|
/*
 | 
						|
 *
 | 
						|
 *      AUX FUNCTIONS FOR WORD DEFS
 | 
						|
 *
 | 
						|
 */
 | 
						|
 | 
						|
Ref<FiftCont> pop_exec_token(vm::Stack& stack);
 | 
						|
Ref<WordList> pop_word_list(vm::Stack& stack);
 | 
						|
void push_argcount(vm::Stack& stack, int args);
 | 
						|
}  // namespace fift
 |