#ifndef __ALEX_H
#define __ALEX_H

#ifndef __VARIANT_H
#include <variant.h>
#endif

// Generic bytecode for any language

class TBytecode : public TArray
{
  TString _name, _lib;

public:
  void set_name(const char* name) { _name = name; }
  const TString& name() const { return _name; }

  void set_library(const char* lib) { _lib = lib; }
  const TString& library() const { return _lib; }
};

// ALEX = Another Language EXtension

class TAVM;

class TAlex_virtual_machine : public TObject
{
  TAVM* _avm; // Chesire's cat class

protected:
  TAVM& avm();

public:
  virtual size_t get_usr_words(TString_array& names) const;
  virtual bool execute_dot(const TVariant& var);
  virtual bool execute_usr_word(unsigned int opcode, TVariant_stack& stack);
  virtual bool get_usr_val(const TString& name, TVariant& var) const;
  virtual bool set_usr_val(const TString& name, const TVariant& var);
  virtual void include_libraries(bool reload = false);

  virtual void log_error(const char* msg);
  const TString& get_last_error() const;

  bool compile(istream& instr, TBytecode& bc);
  bool compile(const char* cmd, TBytecode& bc);
  bool execute(const TBytecode& bc);
  bool include(const char* fname);

  void warm_restart();
  void cold_restart();
  void set_interactive(bool inter);
  bool defined(const char* name);

  TAlex_virtual_machine();
  virtual ~TAlex_virtual_machine();
};

#endif