// ---------------------------------------------------------------------------
// - Interp.hpp -
// - afnix engine - interpreter class definition -
// ---------------------------------------------------------------------------
// - This program is free software; you can redistribute it and/or modify -
// - it provided that this copyright notice is kept intact. -
// - -
// - This program 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. In no event shall -
// - the copyright holder be liable for any direct, indirect, incidental or -
// - special damages arising in any way out of the use of this software. -
// ---------------------------------------------------------------------------
// - copyright (c) 1999-2007 amaury darsch -
// ---------------------------------------------------------------------------
#ifndef AFNIX_INTERP_HPP
#define AFNIX_INTERP_HPP
#ifndef AFNIX_STACK_HPP
#include "Stack.hpp"
#endif
#ifndef AFNIX_LOADER_HPP
#include "Loader.hpp"
#endif
#ifndef AFNIX_OPTIONS_HPP
#include "Options.hpp"
#endif
#ifndef AFNIX_TERMINAL_HPP
#include "Terminal.hpp"
#endif
#ifndef AFNIX_SUPERSET_HPP
#include "Superset.hpp"
#endif
#ifndef AFNIX_RESOLVER_HPP
#include "Resolver.hpp"
#endif
#ifndef AFNIX_RUNNABLE_HPP
#include "Runnable.hpp"
#endif
namespace afnix {
/// The Interp class is the main afnix interpreter engine. The interpreter
/// operates on three streams, the standard input, the standard output and
/// the standard error stream. By default, the interpreter install a
/// terminal object, unless the three streams are specified at construction.
/// The interpreter holds a series of registers. For each basic types,
/// like integer, real, character and boolean, the interpreter has 256
/// local thread registers. The operations associated with the registers
/// are type dependant. For integer and real, these are mostly arithmetic
/// operations. For boolean, these are logical operations. The interpreter
/// has a top level (or global) nameset. The global nameset is shared
/// between all interpreters and is referenced as '...'. On top of this,
/// the interpreter provides a 'compile' method which takes a form and
/// generates a new one. The sole purpose of the compile method is to
/// perform static checking and generate a new form ready for execution.
/// @author amaury darsch
class Interp : public Runnable {
public:
/// @return an interpreter option object
static Options* getopts (void);
private:
/// the standard input stream
mutable Input* p_is;
/// the standard output stream
mutable Output* p_os;
/// the standard error stream
mutable Output* p_es;
/// the assert flag
bool d_assert;
/// the cloned interpreter flag
bool d_cloned;
/// the posted object
Object* p_posted;
/// the super global nameset
Superset* p_gset;
/// the execution stack
Stack* p_stk;
/// the vector arguments
Vector* p_argv;
/// the runnable form
Object* p_rform;
/// the library loader
Loader* p_shld;
protected:
/// the default terminal
Terminal* p_term;
/// the path resolver
Resolver* p_rslv;
/// the encoding mode
String d_emod;
/// the next flag
bool d_next;
public:
/// create a default interpreter
Interp (void);
/// create a new interpreter with or without a terminal
/// @param tflg the terminal flag
Interp (const bool tflg);
/// create a new interpreter
/// @param is the standard input stream
/// @param os the standard output stream
/// @param es the standard error stream
Interp (Input* is, Output* os, Output* es);
/// copy constructor for this interpreter
/// @param that the interpreter to copy
Interp (const Interp& that);
/// destroy this interpreter
~Interp (void);
/// @return the class name
String repr (void) const;
/// make this interpreter a shared object
void mksho (void);
/// post an object in this interpreter
void post (Object* object);
/// @return a clone of this interpreter
Object* clone (void);
/// clone this interpreter and set the runnable form
/// @param form the runnable form to set
Interp* dup (Object* form) const;
/// duplicate this interpreter by seeting the terminal
/// @param term the teminal stream to set
Interp* dup (Terminal* term) const;
/// duplicate this interpreter by updating the streams
/// @param is the input stream to update
/// @param os the output stream to update
/// @param es the error stream to update
Interp* dup (Input* is, Output* os, Output* es) const;
/// evaluate the runnable form
Object* run (void);
/// evaluate a form in a thread by cloning this interpreter
/// @param form the form to evaluate
Object* launch (Object* form);
/// evaluate a form in a daemon thread by cloning this interpreter
/// @param form the form to evaluate
Object* daemon (Object* form);
/// @return the interpreter input stream
Input* getis (void) const;
/// @return the interpreter output stream
Output* getos (void) const;
/// @return the interpreter error stream
Output* getes (void) const;
/// set the primary prompt
/// @param value the prompt to set
void setpp (const String& value);
/// set the secondary prompt
/// @param value the prompt to set
void setsp (const String& value);
/// @return the primary prompt
String getpp (void) const;
/// @return the secondary prompt
String getsp (void) const;
/// set the interpreter encoding mode
/// @param emod the encoding mode
void setemod (const String& emod);
/// @return the interpreter stack
Stack* getstk (void) const;
/// @return the interpreter global set
Nameset* getgset (void) const;
/// create a new reserved name in the global nameset
/// @param name the reserved name
/// @param object the object to bind
void mkrsv (const String& name, Object* object);
/// create a child nameset in the superset
/// @param name the nameset name to create
Nameset* mknset (const String& name);
/// set the interpreter arguments
/// @param args the arguments to set
void setargs (const Strvec& args);
/// @return the interpreter arguments
Strvec getargs (void) const;
/// add a path to the resolver
/// @param path the path to add
void addpath (const String& path);
/// set the resolver with a list of path
/// @param path the path to set
void setpath (const Strvec& path);
/// set the assert flag
/// @param flag the flag to set
void setasrt (const bool flag);
/// @return the assert flag
bool getasrt (void) const;
/// @return the interpreter loader
Loader* getld (void) const;
/// register a library by name and handle
/// @param name the library name to register
/// @param hand the library handle
void reglib (const String& name, void* hand);
/// open a new dynamic library by name
/// @param name the library name
/// @param argv the vector arguments
Object* library (const String& name, Vector* argv);
/// set the next flag
/// @param flag the flag to set
void setnext (const bool flag);
/// @return the next flag
bool getnext (void) const;
/// break the runnable in a nameset with an object
/// @param nset the nameset to loop
/// @param object the object to break on
bool bpt (Nameset* nset, Object* object);
/// run the read-eval loop on the standard streams
/// @return false if something bad happen
bool loop (void);
/// loop in the context of a nameset and an input stream
/// @param nset the nameset context
/// @param is the input stream to use
bool loop (Nameset* nset, Input* is);
/// run the read-eval loop with a file
/// @param fname the file name to read
/// @return false if something bad happen
bool loop (const String& fname);
/// run the read-eval loop with a file
/// @param fname the file name to read
void load (const String& fname);
/// compile from an input stream to an output stream
/// @param the file to compile
/// @param os the output stream to write
void compile (const String& name, Output& os);
private:
// make the assignment operator private
Interp& operator = (const Interp&);
public:
/// @return true if the given quark is defined
bool isquark (const long quark, const bool hflg) const;
/// evaluate an object in this object
/// @param object the object to evaluate
Object* eval (Object* object);
/// evaluate an object method by quark
/// @param robj the current runnable
/// @param nset the current nameset
/// @param quark the quark to evaluate
Object* eval (Runnable* robj, Nameset* nset, const long quark);
/// apply this object with a set of arguments and a quark
/// @param robj the current runnable
/// @param nset the current nameset
/// @param quark the quark to apply these arguments
/// @param argv the arguments to apply
Object* apply (Runnable* robj, Nameset* nset, const long quark,
Vector* argv);
};
}
#endif
syntax highlighted by Code2HTML, v. 0.9.1