/*
This file is part of GNU APL, a free implementation of the
ISO/IEC Standard 13751, "Programming Language APL, Extended"
Copyright (C) 2008-2016 Dr. Jürgen Sauermann
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
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. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see .
*/
#ifndef __COMMAND_HH_DEFINED__
#define __COMMAND_HH_DEFINED__
#include
#include "Common.hh"
#include "LibPaths.hh"
#include "Value.hh"
#include "UCS_string.hh"
#include "UTF8_string.hh"
class Workspace;
//-----------------------------------------------------------------------------
/*!
Some command related functions, including the main input loop
of the APL interpreter.
*/
/// The class implementing all APL commands
class Command
{
public:
/// process a single line entered by the user (in immediate execution mode)
static void process_line();
/// process \b line which contains a command or statements
static void process_line(UCS_string & line);
/// process \b line which contains an APL command. Return true iff the
/// command was user-defined (and then the function for that command is
/// stored in \b line and shall be executed)).
static bool do_APL_command(ostream & out, UCS_string & line);
/// process \b line which contains APL statements
static void do_APL_expression(UCS_string & line);
/// finish the current SI->top() and pop it when done
static void finish_context();
/// parse user-suplied argument (of )VARS, )OPS, or )NMS commands)
/// into strings from and to
static bool parse_from_to(UCS_string & from, UCS_string & to,
const UCS_string & user_input);
/// return true if \b lib looks like a library reference (a 1-digit number
/// or a path containing . or / chars
static bool is_lib_ref(const UCS_string & lib);
/// clean-up and exit from APL interpreter
static void cmd_OFF(int exit_val);
/// return the current boxing format
static int get_boxing_format()
{ return boxing_format; }
/// return the number of APL expressions entered in immediate execution mode
static ShapeItem get_APL_expression_count()
{ return APL_expression_count; }
/// one user defined command
struct user_command
{
UCS_string prefix; ///< the first characters of the command
UCS_string apl_function; ///< APL function implementing the command
int mode; ///< how left arg of apl_function is computed
};
/// check workspace integrity (stale Value and IndexExpr objects, etc)
static void cmd_CHECK(ostream & out);
/// a helper for finding sub-values with two parents
struct val_val
{
/// the parent (0 unless child is a sub-value
const Value * parent;
/// the value (always valid)
const Value * child;
/// compare function for Heapsort::sort()
static bool compare_val_val(const val_val & A, const val_val & B,
const void *);
/// compare function for bsearch()
static int compare_val_val1(const void * key, const void * B);
};
/// return true if entry is a directory
static bool is_directory(dirent * entry, const UTF8_string & path);
/// format for ]BOXING
static int boxing_format;
protected:
/// )BOXING command
static void cmd_BOXING(ostream & out, const UCS_string & arg);
/// )SAVE active WS as CONTINUE and )OFF
static void cmd_CONTINUE(ostream & out);
/// )COPY: copy a workspace file
static void cmd_COPY(ostream & out, UCS_string_vector & args,
bool protection);
/// ]DOXY: create doxygen-like documentation of the current workspace
static void cmd_DOXY(ostream & out, UCS_string_vector & args);
/// )DROP: delete a workspace file
static void cmd_DROP(ostream & out, const UCS_string_vector & args);
/// )DUMP: dump a workspace file (.apl)
static void cmd_DUMP(ostream & out, const UCS_string_vector & args,
bool html, bool silent);
/// )ERASE: erase symbols
static void cmd_ERASE(ostream & out, UCS_string_vector & args);
/// show list of commands
static void cmd_HELP(ostream & out, const UCS_string & arg);
/// show help for APL primitives
static void primitive_help(ostream & out, const char * arg, int arity,
const char * prim, const char * name,
const char * title, const char * descr);
/// show or clear input history
static void cmd_HISTORY(ostream & out, const UCS_string & arg);
/// )HOST: execute OS command
static void cmd_HOST(ostream & out, const UCS_string & arg);
/// )IN: import a workspace file
static void cmd_IN(ostream & out, UCS_string_vector & args, bool protect);
/// show US keyboard layout
static void cmd_KEYB(ostream & out);
/// )LOAD: load a workspace file
static void cmd_LOAD(ostream & out, UCS_string_vector & args,
UCS_string & quad_lx, bool silent);
/// show performance counters
static void cmd_PSTAT(ostream & out, const UCS_string & arg);
/// open directory arg and follow symlinks
static DIR * open_LIB_dir(UTF8_string & path, ostream & out,
const UCS_string_vector & args);
/// list library: common helper
static void lib_common(ostream & out, const UCS_string_vector & args,
int variant);
/// list content of workspace and wslib directories: )LIB [N]
static void cmd_LIB1(ostream & out, const UCS_string_vector & args);
/// list content of workspace and wslib directories: ]LIB [N]
static void cmd_LIB2(ostream & out, const UCS_string_vector & args);
/// control logging facilities
static void cmd_LOG(ostream & out, const UCS_string & arg);
/// list paths of workspace and wslib directories
static void cmd_LIBS(ostream & out, const UCS_string_vector & lib_ref);
/// print more error info
static void cmd_MORE(ostream & out);
/// )OUT: export a workspace file
static void cmd_OUT(ostream & out, UCS_string_vector & args);
/// )SAVE: save a workspace file (.xml)
static void cmd_SAVE(ostream & out, const UCS_string_vector & args);
/// create a user defined command
static void cmd_USERCMD(ostream & out, const UCS_string & arg,
UCS_string_vector & args);
/// enable and disable colors
static void cmd_XTERM(ostream & out, const UCS_string & args);
/// split whitespace separated arguments into individual arguments
static UCS_string_vector split_arg(const UCS_string & arg);
/// execute a user defined command
static void do_USERCMD(ostream & out, UCS_string & line,
const UCS_string & line1, const UCS_string & cmd,
UCS_string_vector & args, int uidx);
/// check if a command name conflicts with an existing command
static bool check_name_conflict(ostream & out, const UCS_string & cnew,
const UCS_string cold);
/// check if a command is being redefined
static bool check_redefinition(ostream & out, const UCS_string & cnew,
const UCS_string fnew, const int mnew);
/// check the number of parameters in a command
static bool check_params(ostream & out, const char * command, int argc,
const char * args);
/// resolve an optional lib followed by a WS name
static bool resolve_lib_wsname(ostream & out, const UCS_string_vector & args,
LibRef &lib, UCS_string & wsname);
/// a helper struct for the )IN command
struct transfer_context
{
/// constructor
transfer_context(bool prot)
: new_record(true),
recnum(0),
timestamp(0),
protection(prot)
{}
/// process one record of a workspace file
void process_record(const UTF8 * record,
const UCS_string_vector & objects);
/// get the name, rank, and shape of a 1 ⎕TF record
uint32_t get_nrs(UCS_string & name, Shape & shape) const;
/// process a 'A' (array in 2 ⎕TF format) item.
void array_2TF(const UCS_string_vector & objects) const;
/// process a 'C' (character, in 1 ⎕TF format) item.
void chars_1TF(const UCS_string_vector & objects) const;
/// process an 'F' (function in 2 ⎕TF format) item.
void function_2TF(const UCS_string_vector & objects) const;
/// process an 'N' (numeric in 1 ⎕TF format) item.
void numeric_1TF(const UCS_string_vector & objects) const;
/// add \b len UTF8 bytes to \b this transfer_context
void add(const UTF8 * str, int len);
/// true if a new record has started
bool new_record;
/// true if record is EBCDIC (not yet supported)
bool is_ebcdic;
/// the record number
int recnum;
/// the record type ('A', 'C', 'N', or 'F')
int item_type;
/// the last timestamp (if any)
APL_time_us timestamp;
/// true if )IN shall not iverride existing objects
bool protection; // protect existing objects
/// accumulator for data of different records
UCS_string data;
};
/// parse the argument of the ]LOG command and set logging accordingly
static void log_control(const UCS_string & args);
/// the number of APL expressions entered in immediate execution mode
static ShapeItem APL_expression_count;
};
//-----------------------------------------------------------------------------
inline void Hswap(Command::val_val & vp1, Command::val_val & vp2)
{
const Command::val_val tmp = vp1; vp1 = vp2; vp2 = tmp;
}
//-----------------------------------------------------------------------------
#endif // __COMMAND_HH_DEFINED__