// avp 2016 (for ru.stackoverflow.com) #ifndef _FCALC_H #define _FCALC_H // fcalc.c http://pastebin.com/nnQN8zcX #ifdef __cplusplus typedef double (*function)(...); #else typedef double (*function)(); #endif // лексема, заполняется calc_getlex() struct calc_lexem { double v; // прочитанное число для type == 'N' int type, /* тип лексемы (операция): + - * / ( ) M унарный минус P унарный плюс N число S имя переменной, присваивание V имя переменной, число F имя переменной, вызов функции , разделитель аргументов функции */ pos, // индекс начала лексемы в строке len; // количество символов в лексеме (имени переменной, числе) }; // указатели на таблицы переменных и функций пользователя typedef struct u_item *Symtab; // inout структура для вычисляемого выражения struct calc { double result; // результат struct calc_lexem curlex; /* последняя прочитанная лексема может использоваться для печати ошибки */ Symtab *varlist, /* переменные, которые могут использоваться в выражении новые переменные, определяемые оператором присваивания данного выражения, создаются в этой таблице */ *funlist; /* функции, определяемые пользователем sin, asin, cos, acos, tan, atan, fabs, round, cell, floor, trunc, sqrt, cbrt, pow, exp, log, log2 и log10 уже определены в калькуляторе */ int rc; // код возврата (OK == 0 иначе, код ошибки) }; // коды возврата calc() #define CALC_OK 0 #define CALC_OUT_OF_MEM 1 #define CALC_NO_OP 2 // нет операции меэду парой операндов #define CALC_NO_VAL 3 // вместо операнда найдена операция (или `)`) #define CALC_NO_RP 4 // лишняя '(' (найдена в стеке по EOF) #define CALC_NO_LP 5 // лишняя ')' (в стеке нет '(' для ')') #define CALC_ERR_OP 6 // неизвестная операция в expr() (internal error) #define CALC_NO_NUMS 7 // для операции не хватает операндов #define CALC_NUMS_ERR 8 // в стеке остались операнды (internal error) #define CALC_OPRS_ERR 9 // в стеке остались операции (internal error) #define CALC_ERR_INPUT 10 // прочли неизвестный символ (graph ...) #define CALC_NO_FRP 11 // нет `)` для функции ('F' найдена в стеке по EOF) #define CALC_NO_INPUT 12 // в строке нет выражения #define CALC_ERR_CODE 13 // неверный код возврата для получения текста ошибки #define CALC_EOD 14 // EOF (NULL вместо str) #define CALC_ARGS_ERR 15 // слишком много аргументов в вызове функции #define CALC_ASSG_ERR 16 // присваивание в середине выражения #define CALC_COMMA_ERR 17 // `,` вне списка аргументов функции #define CALC_NO_VAR 18 // неизвестная переменная #define CALC_NO_FUNC 19 // функция не найдена #define CALC_ERR_PRTY 20 // неправильный приоритет операции (internal error) extern #ifdef __cplusplus "C" { #endif // калькулятор, вычисляет арифметическое выражение в str int calc (const char *str, double *pres, struct calc *ctx); // возвращает текст по коду возврата calc() const char *calc_strerr (int code); // создает переменную или меняет значение существующей double *calc_set_var (Symtab **p, const char *name, int len, double v); // доступ к значению существующей переменной double *calc_get_var (Symtab **p, const char *name, int len); // добавляет функцию или меняет указатель на нее function *calc_set_func (Symtab **p, const char *name, function f); // доступ к указателю на функцию function *calc_get_func (Symtab **p, const char *name, int len); // удаляет из таблицы переменную или функцию int calc_delsymb (Symtab **p, const char *name); // для отладки (или любопытным) печатает таблицу переменных/функций // pri_content = 0 -- только статистика, 1 -- печать имен, 2 -- и значений int calc_pristat (Symtab *t, int pri_content); // удаляет всю таблицу переменных/функций void calc_destroy_symtab (Symtab **p); // удаляет таблицу предопределенных функций внутри calc() void calc_free(); #ifdef __cplusplus } #endif #endif