KNOW-HOW.SLANG
Add-on general purpose Language Interpreter. 

Introduction.
	SLANG is the BASIC-like language. KH_SLANG is the DLL implementing 
SLANG interpreter. It is possible to derive from KH_SLANG classes, and 
add your own functions to SLANG. For example, if you are creating 
database engine, you will probably want to use cycles, condition operators 
(IF - ELSE), subroutines and so on from SLAMG, and add database-specific 
functions, for example, EXEC_SQL, OPEN_DATABASE... To do so you 
should use inheritance and follow easy steps described in documentation.

To see example of SLANG-based package, you could download SLANG (not 
KH_SLANG, but end-user package) which is powerful data processing tool, 
drawing tool and charting tool. For URL of KNOW-HOW Home Page see 
LICENSE.TXT 


KNOW-HOW SLANG tutorial

*	Classes. 
The following class hierarchy is used in KH.SLANG:

Slang - SlangFiles - SlangMath

Slang is the base class in the hierarchy, it implements the following functions of 
SLANG language:

*	The following set of operations is defined for SLANG (SLANG extentions 
could add new operations, if this document is part of SLANG-based 
program, see program description for list of program-specific functions). 
Some of this functions are just reserved names, they will be implemented in 
further versions of SLANG:

/*  */ 	commented block of code
'	commented line
@	user-defined function
#	label
BREAK	exit the cycle
CONTINUE	start the next cycle
COS	cosinus
DELETE	release variable
ELSE	IF operator fails
END	end of main program block
ENDIF	end of condition operator
ENDSUB	skip the rest of subroutine, go to RETURN
FOR	cycle operator
GETREAL	parse the string, expect numeric
GETTOKEN	parse the string
GOTO	unconditional jump
IF	condition operator
LG	logarithm
LPLAY	play external file - keep functions
NEXT	end of FOR cycle
PLAY	play external file, do not keep functions
PUTTOKEN	add token to string
RETURN	return from subroutine
SIN	sinus
SPLAY	load program from string, not file
STRCHR	search string for substring
STRCMP	compare two strings
THEN	see IF
TO	see FOR

*	Class SlangFile extends Slang functionality. It deals with files. In some cases 
your program do not need file operations. For example, if you write database 
engine, it will probably have its own file functions. In this case you can inherit 
your classes directly from Slang, and ignore SlangFile functionality.

PRINT	formatted output
INPUT	formatted input
PAUSE	suspend program for some period (reserved)
REMOVE	delete file
RENAME	rename file
SEEK	move cursor inside file
SETMODE	change file access mode
WRITE	write to file
NEXT_LINE	skip to the next line in file
OPEN	open file
READ	read from file
CLOSE	close file
EOF	check if we are at end of file
FILELEN	get length of file
GETPOS	get current position in file

*	Class SlangMath contains extended set of math operations, for example, 
array operations. 

ARRDIV	divide elements of one array to elementd of another
ARRMULT	multiply corresponding elements of arrays
ARRSUB	subtract two arrays
ARRSUM	add elements of two arrays
AVG	compute average
CEIL	round down
COMBIN	reserved
CORREL	reserved
COSH	hyperbolic cosinus
COVAR	reserved
DEGREES	radians to degrees
DEVSQ	reserved
EXPODIST	reserved
FACT	factorial
GEOMEAN	reserved
LOADER	read ASCII table to array (s) by columns
MAX	maximum for REAL (s) or array elements
MIN	minimum for REAL (s) or array elements
MVAVG	moing average
MVMAX	moving maximum
MVMIN	moving minimum
NORMDIST	reserved
PERMUT	reserved
POISSON	reserved
PRODUCT	reserved
RADIANS	degrees to radians
RAND	generate random number
REGR	reserved
SINH	hyper sin
STDDEV	reserved
STDEVP	reserved
SUM	sum of REAL(s)  or array (s)
SUMSQ	sum of squares
SUMXMY2	sum of squares of ar1[i] * ar2[i]
TANH	hyper tangent
VAR	reserved
VARP	reserved



Files of KNOW-HOW.SLANG library

*	VARIABLE.H

#ifndef __VARIABLE_H_
#define __VARIABLE_H_

#include "general\simple.h"
#include "general\kh_error.h"
#include <string.h>
#include "general\strdup.h"

// We use dynamically allocated arrays of double. Format is:
// d[0] == number of elements, d[1 - n] contains data.
// SLANG supports 3 types of variables: STRING, REAL and ARRAY (of REALs)
enum VAR_TYPE { REAL = 1, STR, ARRAY };

struct _export Variable
	{
	VAR_TYPE type;
	char* name;
	union
		{
		double d;
		char* s;
		double* da;
		};
	Variable(double D, char* s);		// Construct REAL
	Variable(char*  S, char* nm);		// Construct STRING
	Variable(double* D, char* s);		// Construct ARRAY
	Variable(int dim, char* s);		// Construct new ARRAY
	~Variable();
	};

#endif __VARIABLE_H_

*	VAR_TAB.H
SLANG keeps variables in sorted table. You will probably newer use this file.

#ifndef _VARIABLE_TABLE_H_
#define _VARIABLE_TABLE_H_

#include "kh_slang\variable.h"

#define VARIABLE_STEP 100	// Step in memory re-allocation

struct _export VarTable
	{
	int used;	// Memory used
	int size;	// Memory allocated
	Variable** table;	// List of variables.

	void free_var(Variable* v);	// Release variable. Called by DELETE

	VarTable();
	~VarTable();

	Variable* assign(Variable* v);			// x = y
	Variable* assign(double d, char* name);		// x = 3.5
	Variable* assign(char* s, char* name);		// s = "Hello"
	Variable* assign(double* da, char* name);		// ar = ar1
	Variable* assign(double d, char* name, int index);	// ar[10] = 3
	Variable* assign(int index, char* name);		// ar[10];

	void add(Variable* v, int to_sort = 0);	// Add to list, sort if necessary	
	Variable* remove(char* name);		// Remove from list
	Variable* find(char* name);			// Find in list

	void clear();	// Empty the list
	};

#endif _VARIABLE_TABLE_H_

*	SLANGTAB.H

This file is responsible for error messages and support of the list of functions.

#ifndef __SLANG_TABLE_H_
#define __SLANG_TABLE_H_

#include <string.h>

enum { DELIMITER = 1,     // '\0'(end),/*,*/,\r,<>=,' ',+-^/*%=;(),<>[]
	   VARIABLE,          // Symbolic name of variable, like x, k1 and so on
	   NUMBER,            // Double value
	   COMMAND,           // See "commands TABLE[]" later in this file
	   STRING,            // Remarked blocks or quoted text
	   QUOTE,             // Quote
	   ALPHA };           // @ (gosub) or ! (label) symbol

// SLANG commands are translated to the numbers
struct commands
	{
	char command[20];
	int tok;
	};
/////////////////////////////////////////////////////////
// User could register functions from DLL. Currently this feature is disabled

struct _export UserFunc
  {
  char* DLL_name;
  char* function_name;
  int tok;

  UserFunc(char* dll, char* func, int t);// = SLANG_USER)
  ~UserFunc();
  };
/////////////////////////////////////////////////////////
// List of SLANG functions. You can dynamically add new functions here.
struct _export FunctionList
	{
	int used;
	int total;
	UserFunc** list;

	FunctionList();
	~FunctionList();

	void init(commands* TABLE);	// See example below
	void add(char* dll, char* name, int tok);
	UserFunc* remove(char* function_name);
	UserFunc* find(char* function_name);
    };                     
////////////////////////////////////////////////////////
// The following is the list of error messages. If you need your own message, use numbers 
> USER_ERROR and overload error-reporting function in your class.

static char* error_string[] =
	{
	"Syntax error",                            //  0
	"Symbol '(' or ')' expected",              //  1
	"Not an expression",                       //  2
	"Symbol '=' expected",                     //  3
	"Not a variable",                          //  4
	"Too many subroutines",                    //  5
	"Duplicated subroutines",                  //  6
	"Undefined subroutine",                    //  7
	"Expected THEN operator",                  //  8
	"Expected TO operator",                    //  9
	"Number of nested FOR cycles too big",     //  10
	"NEXT without FOR",                        //  11
	"Number of nested GOSUB calls too big",    //  12
	"RETURN without GOSUB",                    //  13
	"Quote expected",			   //  14
	"Wrong arguments number",                  //  15
	"Out of range",                            //  16
	"It is no file",                           //  17
	"Symbol '=' or ARRAY expected",            //  18
	"Symbol '[' or ']' expected",              //  19
	"Name is already used ",                   //  20
	"File error",                              //  21
	"Memory allocation error",                 //  22
	"User break",                              //  23
	"Undefined variable",                      //  24
	"Use IF - THEN - ELSE - ENDIF",            //  25
	"Wrong argument type",                     //  26
	"Undefined function",                      //  27
	"DLL error",                               //  28
	"Print error",                             //  29
	"Math. error",                             //  30  
	"USER ERROR"
	};

#endif __SLANG_TABLE_H_


*	SLANG.H
One of the most important files in the library.

#ifndef __BASIC_H_
#define __BASIC_H_

#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include <ctype.h>

#include "general\simple.h"
#include "kh_slang\slangtab.h"
#include "kh_slang\var_tab.h"

#define NUM_LAB   100	// Maximum number of labels in program
#define LAB_LEN   10	// Max. length of label name
#define FOR_NEST  25	// Max. Number of nested FOR cycles
#define SUB_NEST  25	// Max. Number of nested SUBROUTINES calls
#define PROG_SIZE 32000	// Maximum program size (or use multyfile projects)
#define LINE_LEN 160	// Program line len (LINE - CR - LINE ...)
#define DEF_STRING_LEN 200 // Default len of string, see f.e. READ()

// SLANG uses this enum in PLAY, SPLAY and LPLAY
enum PLAY_SOURCE { FROM_FILE, FROM_STRING };

/* The following enumeration lists all SLANG functions. To add new functions in Slang 
descendants, you should create enum for them. See SlangFiles and SlangMath
*/
enum { SLANG_IF = 1, SLANG_THEN, SLANG_ENDIF, SLANG_ELSE, 
	SLANG_FOR, SLANG_CONTINUE, SLANG_BREAK, SLANG_NEXT, 
	SLANG_TO, SLANG_GOTO, SLANG_END_SUB, SLANG_RETURN, 
	SLANG_END, SLANG_REMARK, SLANG_REMARK_BLOCK, 
	SLANG_EOL,
	SLANG_DELETE, SLANG_PAUSE,
	SLANG_FINISHED, SLANG_GOSUB, SLANG_LABEL,
	SLANG_PLAYEX, SLANG_LPLAY, SLANG_SPLAY,
	SLANG_SIN, SLANG_COS, SLANG_TAN, SLANG_ASIN, SLANG_ACOS, 
	SLANG_ATAN, SLANG_ABS, SLANG_EXP, SLANG_LOG, SLANG_LG,
	SLANG_STRCMP, SLANG_STRCHR, SLANG_GETTOKEN, 
	SLANG_GETREAL, SLANG_PUTTOKEN,
//       SLANG_USER = 10000, SLANG_REGISTER
	};  // All functions after this are user-defined in Slang childs

// Used for FOR operator
struct for_stack
	{
	char name[10];  // Counter - cycle variable name
	double endval;  // Cycle end value
	uint entrance; // Point in the program string
	};
// Used for PLAY operator and subroutines
struct play_stack
	{
	char* prog;                            // Name of file
	uint shift;                             // Offset in this file
	play_stack(char* s, int i)
		  { prog = new char[strlen(s)]; strcpy(prog, s); shift = i; }
	~play_stack() { delete prog; prog = NULL; }
	};
// Used for #label construction
struct label               // Label : LABEL NAME and pointer to the place
	{                      // in the program
	char name[LAB_LEN];
	uint p;
	};
// Used to catch unexpected math errors
static int math_error = 0;
int _matherr(struct _exeption* exept);
//////////////////////////////////////////////////////////////////////////////////
class _export Slang                     // The base interpreter class
	{
	public:
		PLAY_SOURCE play_source;  // FROM_FILE or FROM_STRING
		int error;                         // Number of the error
		char* program;          // SLANG program (contents of current file)
		uint substack[SUB_NEST];          // Subroutines stack
		play_stack* playstack[SUB_NEST];   // External files player
		for_stack fstack[FOR_NEST];        // FOR stack

		int variable_type;  // Type of current variable
		char   token_type;  // Type of token obtained
		int tok;           // Group of token obtained
		char token[LINE_LEN]; // Token obtained
		int for_used;       // FOR stack top
		int sub_used;       // Gosub stack top
		int play_used;      // Play stack top
		char* prog;         // Program - from the current point to the end
		label* labels;      // Table of labels in current file
		VarTable* variables; // Table of variables
		VarTable* arguments; // Parameters for user DLL functions
		FunctionList* FuncTable;
		UserFunc* function;  // Current function
	public:
		Slang();
		~Slang();
// Used to add user-defined functions - see below
		int prepare_interprete(); 
		virtual void further_processing() {}
		virtual double further_math(double x) { return 0.0; }
		virtual double further_math_first() { return 0.0; }
// Used internally by Slang, could be used in your functions. 
		char* get_string_arg(char* dst); // token contains string or variable
// Currently disabled - DLL support
//	virtual double slang_user(char* DLL_name, char* function_name) = 0;
//	virtual void slang_register() = 0;
//	virtual void slang_unregister() = 0;

	 virtual void interprete(); // basic() call it in cycle

	 void del();	// Release variable

	 void slang_end_sub();         // Go to return
	 void slang_get_token();              // Parse string
	 double slang_get_real(Variable* s);  //
	 void slang_put_token();

	 void slang_goto();         // GOTO operator
	 void slang_if();           // IF operator
	 void slang_else();         // ELSE operator
	 void slang_for();          // FOR operator
	 void slang_continue();     // CONTINUE operator
	 void slang_break();        // BREAK operator
	 void next();               // NEXT operator
	 void gosub();              // Pass control to the subroutine
	 void sub_return();         // Return from subroutine
	 void play();               // Play external file
	 void lplay();              // Link functions of current module
	 void get_label();
	 int slang_strcmp();             // compare two strings
	 int slang_strchr();             // check string for given char
	 void pause();               // See "C" delay() function

// Internal functions. Could be used in your functions. Use existing
// SLANG functions as examples
	 void set_error(int err) { error = err; }
	 int get_argument(double* x);
	 int get_error() { return error; }
	 void set_program(char* p) { program = p; }
	 char* get_program() { return program; }
	 char* load_program(char*); // Remove old program and load new file
	 uint find_label(char*);   // Find label name in the table
	 uint sub_pop();           // Get subroutine parameters from stack
	 void sub_push(char*);      // Push Gosub parameters to stack
	 for_stack for_pop();       // Get FOR parameters from stack
	 void for_push(for_stack);  // Push FOR parameters to stack
	 void playpush(char*, int); // Push external file parameters to stack
	 play_stack* playpop();     // Get external file parameters from stack

	 void scan_labels();        // Scan file and fill labels
	 void find_eol();           // Scip line
	 void find_return();        // Search for RETURN (\r\n)

	 void label_init();         // Init labels
	 int get_next_label(char*); // Get next label
	 int reassign_arguments();  // We use assign_ and reassign_arguments
	 int assign_arguments();    // with subroutines calls to pass args.
	 void release_var(char* );  // Remove variable from table
	 void assigment();          // Assign value to variable
	 void basic(char*);         // Executes program pointed by char*
// Parser
	 void math(double* result);  // sin, cos...
	 char* get_exp(double*);
	 char* level0(double*);
	 char* level1(double*), *level2(double*); // Recursive analyser
	 char* level3(double*), *level4(double*);  // User could modify
	 char* level5(double*), *level6(double*);  // the "primitive" function
	 char* level7(double*);                    // and add COMMAND group
	 char* primitive(double*);                 // user-defined functions
	 void arith(char, double*, double*, char op1 = '0');
	 void unary(char, double*);

// Error reporting system - overwrite in child classes if need your own
// messages
	 virtual void serror(int);  // Error processor
	 virtual void error_report(char* text); // Overload for your own print

	 void putback();            // Put token back
	 int get_token();           // Get token from prog
	 int iswhite(char);         // Recognize symbols to skip
	 int isdelim(char);         // Recognize delimiters (),:;" and so on

	 virtual void terminate();  // User-defined terminator (ESC and so on)
	 };

#endif __BASIC_H_


*	S_FILES.H
File operations and formatted input-output.
Lets use this file to examine steps you should take to create your own class using 
Slang as the base class. First, we create header file:

#ifndef __SLANG_FILES_H_
#define __SLANG_FILES_H_

/*  This class inherits Slang functionality and has additional functions:
		INPUT - BASIC-like input operator, able to handle both user input
			and ASCII file data
		PRINT - BASIC-like print operator, output could be directed to
			screen (window) or to the file
		OPEN, READ, WRITE, CLOSE, EOFILE, FILELEN, SEEK, RENAME,
		SETMODE, GETPOS, REMOVE, NEXT_LINE - file operating functions,
			see manual for details
*/

Then we include reference to the header of the base class, in our case SLANH.H:
#include "kh_slang\slang.h"

Create enum for functions we are going to add. First member of an enum is 1000, this 
will leave enought space for enum members of the Slang class (see enum in SLANG.H):

enum { SLANG_PRINT = 1000, SLANG_INPUT, SLANG_OPEN, SLANG_READ, 
	SLANG_WRITE, SLANG_CLOSE, 	SLANG_EOFILE, SLANG_FILELEN, 
	SLANG_SEEK, SLANG_RENAME, SLANG_SETMODE, 
	SLANG_GETPOS, SLANG_REMOVE, SLANG_NEXT_LINE
	};

Then we are creating our class, in this case SlangFiles. We specify whatever data 
members we need and constructor:

class _export SlangFiles : public Slang    // File and i/o functions added
	{
	public:
		int in_file, out_file; // Handles of files for input and output

	public:
		SlangFiles();

The next very important step is to create functions to actually process operators you 
added to SLANG. This functions are virtual, as soon as you create them, Slang will call 
them instead of default functions:

		virtual void further_processing();
		virtual double further_math(double x);

At this point it is useful to take a look at Slang code, which is not available with 
SHAREWARE version of library. Function Slang::interprete(), for example, will call 
further_processing, when it fails to process incoming operator:
void Slang::interprete()
	{
	......
	case SLANG_END_SUB:
	case SLANG_RETURN:   sub_return();  break;
	case SLANG_DELETE:   del(); break;
	case SLANG_PAUSE:    pause(); break;
	......
	default:
		further_processing();
		break;

In your code you should implement further_processing() like this (file s_files.cpp):
void  SlangFiles::further_processing()
	{
	switch(tok)  // If it is operator or subroutine call
		{
		case SLANG_PRINT:    print();    break;
		case SLANG_INPUT:    input();    break;
		case SLANG_OPEN: slang_open(); break;   // Open file
		case SLANG_READ: slang_read(); break;   // Read from file
		case SLANG_WRITE: slang_write(); break; // Write to file
		case SLANG_CLOSE: slang_close(); break; // Close file
		case SLANG_EOFILE:   slang_eof();  break;  // EOF reached
		case SLANG_FILELEN: slang_filelength(); break; // End of file
		case SLANG_SEEK: slang_lseek(); break;  // Move position in file
		case SLANG_RENAME: slang_rename(); break; // Rename file
		case SLANG_SETMODE: slang_setmode(); break; // Set access mode
		case SLANG_GETPOS: slang_tell(); break; // Get current pos. in file
		case SLANG_REMOVE: slang_unlink(); break; // Delete file
		case SLANG_NEXT_LINE: next_line(); break;
		case SLANG_GETTOKEN: slang_get_token(); break; // Get token 
		case SLANG_PUTTOKEN: slang_put_token(); break; // Put token 
		}
	}

Function further_math() is used in parser and should be created according to this 
example (FILE s_files.cpp):

double SlangFiles::further_math(double x)
	{
// No explination - just do it
	if(error)
		return 0.0;
	double result;		// Value to return
	int t = tok;		// tok is inherited from Slang
	switch(t)
		{
		case SLANG_EOFILE: result = eof((int)(x)); break;
		case SLANG_FILELEN: result = filelength((int)x); break;
		case SLANG_GETPOS: result = tell((int)x); break;
		default:
			serror(0); break;
		}
	return result;
	}
 
It is important that in second generation (for example in SlangMath) default clause 
should look like this:

result = SlangFiles::further_math_first();
break;


We continue with S_FILES.H:
	user-defined functions. Use S_FILES.CPP (the only CPP file available in the 
SHAREWARE edition) as an example of how to create functions:
		void slang_open();            // Open file
		void slang_read();            // Read from file
		void slang_write();           // Write to file
		void slang_close();           // Close the file
		int slang_eof();              // Detect end of file
		ulong slang_filelength();     // Return length of file
		void slang_lseek();           // Position file cursor
		void slang_rename();          // Rename file
		void slang_setmode();         // Change file mode
		ulong slang_tell();           // Get file pos
		void slang_unlink();          // Remove file
		void next_line();             // Go to next line in file
		void input();              // General input function
		virtual void print();              // General output function

print() and input() functions will call printf() and Gets(). This functions could be 
overloaded in child classes, to produce output to the Window, or somewhere else.
// This functions will be overloaded in child class (which is Windows-aware)
		virtual int printf(double argument)
			{ return ::printf("%f", argument); }
		virtual int printf(char * argument)
			{ return ::printf(argument); }
		virtual int printf(char * format, double argument)
			{ return ::printf(format, argument); }

		virtual void Gets(char* str, char* prompt) // For input function
			{ printf(prompt); gets(str); }
	 };

#endif __SLANG_FILES_H_


In the constructor of your class you should register new functions:

SlangFiles::SlangFiles() : Slang()
	{
	/////////////
	commands TABLE[] =  {
		{ "PRINT",  SLANG_PRINT    },
		{ "INPUT",  SLANG_INPUT    },
		{ "PAUSE", SLANG_PAUSE     },
		{ "REMOVE", SLANG_REMOVE   },
		{ "RENAME", SLANG_RENAME   },
		{ "SEEK", SLANG_SEEK       },
		{ "SETMODE", SLANG_SETMODE },
		{ "WRITE", SLANG_WRITE      },
		{ "NEXT_LINE", SLANG_NEXT_LINE },
		{ "OPEN", SLANG_OPEN       },
		{ "READ", SLANG_READ       },
		{ "CLOSE", SLANG_CLOSE     },
		{ "EOF", SLANG_EOFILE      },
		{ "FILELEN", SLANG_FILELEN },
		{ "GETPOS", SLANG_GETPOS   }
		};
	FuncTable->init(TABLE);
	in_file = out_file = -1;
	}

Registration is performed by call init().

*	FILE SLANGMAT.H

This file provide user with extended set of math. operations. It is, however, 
possible that some operations will not be available in SHAREWARE edition.

#ifndef __SLANG_MATH_H_
#define __SLANG_MATH_H_

#include "kh_slang\s_files.h"

enum { SLANG_CEIL = 3000, SLANG_COMBIN, SLANG_COSH, 
	SLANG_DEGREES, SLANG_FACT, SLANG_PRODUCT, SLANG_RADIANS,
	SLANG_RAND, SLANG_SINH, SLANG_SUM, SLANG_SUMSQ, 
	SLANG_SUMXMY2, SLANG_TANH, SLANG_AVERAGE, 
	SLANG_CORREL, SLANG_COVAR, SLANG_DEVSQ, SLANG_EXPODIST,
	SLANG_GEOMEAN, SLANG_REGRESSION, SLANG_MAX, SLANG_MIN, 
	SLANG_NORMDIST, SLANG_PERMUT, SLANG_POISSON, 
	SLANG_STDDEV, SLANG_STDEVP, SLANG_VAR, SLANG_VARP,
	SLANG_ARRSUM, SLANG_ARRSUB, SLANG_ARRDIV, 
	SLANG_ARRMULT, SLANG_MVAVG, SLANG_MVMAX, SLANG_MVMIN,
	SLANG_LOADER
	};
/////////////////////////////////////////////////////////////////////
class _export SlangMath : public SlangFiles    // The base interpreter class
	{
	public:
		SlangMath();

		virtual void further_processing();
		virtual double further_math(double x);
        		virtual double further_math_first();

		Variable* get_array();

		double slang_combin();
		double slang_product();
		double slang_rand();
		double slang_sum();      // a[0] + a[1] +...
		double slang_sumsq();    // a[0]^2 + a[1]^2 +...
		double slang_sumxmy2();  // (a[0] - b[0])^2 + ...
		double slang_average();  // sum(a[i])/n
		double slang_correl();
		double slang_covar();
		double slang_devsq();
		double slang_expodist();
		double slang_geomean();
		double slang_max();      // Max array el-t
		double slang_min();      // Min array el-t
		double slang_normdist();
		double slang_permut();
		double slang_poisson();
		double slang_stddev();
		double slang_stdevp();
		double slang_var();
		double slang_varp();

		void slang_arrsum();     // a1 + b1, ...
		void slang_arrsub();     // a1 - b1, ...
		void slang_arrdiv();     // a1 / b1, 0 if /0...
		void slang_arrmult();    // a1 * b1, ...
		void slang_regression();
// Mv... functions take 4 arguments:
//	 array - to be processed, array name for result, interval for operation,
//	 and shift. If index == 5, interval == 3 and shift == 0, process a5, a6,
//	 a7; if shift == 1, then a4, a5, a6; if shift == 2, a3, a4, a5.
		void slang_mvavg();
		void slang_mvmax();
		void slang_mvmin();

       	void slang_loader();
	 };

#endif __SLANG_MATH_H_











