Библиотека EXPRINT — API-документация
Пакет TMC Suite. Статическая библиотека-интерпретатор строковых математических выражений (разбор и вычисление формул). Язык документации: русский. Все сигнатуры приведены по исходникам из
src/libs/Expr/,src/libs/Inter/и общим заголовкам изsrc/Include/.
1. Назначение библиотеки
EXPRINT — статическая библиотека, реализующая интерпретатор строковых математических выражений (вычислитель формул).
Библиотека принимает на вход формулу в виде текстовой строки (например, "sin(x)+2*y", "return(A^2)", "if(x-1) y=5") и возвращает её численное значение типа _real. Поддерживаются:
- арифметика:
=(присваивание),+,-,*,/,^(степень); - скобки группировки
( )и блочные скобки{ }; - встроенные элементарные функции:
abs,exp,log,log10,sin,cos,tan,sqrt,sinh,cosh,tanh,asin,acos,atan; - переменные — одна латинская буква
A–Z/a–z(массив из 256 ячеек, индексируемый кодом символа); - управляющие операторы интерпретатора:
return(...),if(...) ...,while(...) ...; - выбор единиц измерения углов для тригонометрии (радианы или градусы).
Библиотека логически делится на два модуля:
- Модуль Expr (
src/libs/Expr/) — ядро арифметики: лексический разбор, вычисление выражений, функции, переменные, обработка кодов ошибок. - Модуль Inter (
src/libs/Inter/) — надстройка интерпретатора: операторыreturn/if/while, разбиение строки на последовательность операторов, очистка пробелов.
Библиотека используется во вьюверах пакета (класс CTMCGrExpression — он не входит в EXPRINT и документируется в составе вьюверов) для построения пользовательских графиков по введённым формулам.
Происхождение: TAMIC_soft(R), 25.10.1991, v2.00 — исторический код для DOS / win16, перенесённый в TMC Suite.
О макросах
_far,fortran. Это legacy-атрибуты модели памяти и соглашения о вызове из 16-битного кода (Microsoft C / ранний Visual C++). В заголовкеINTER.Hряд прототипов объявлен как_real _far fortran inte_atof(...). В современной 32/64-битной сборке эти макросы, как правило, разворачиваются в пустоту и на семантику не влияют. Для краткости ниже в сигнатурах они опускаются (приводится «чистый» прототип). Полные прототипы см. вEXPR.H/INTER.H.О типе
_real. Тип_realопределён во внешнем заголовкеtypedef.hи в зависимости от сборки соответствуетfloatлибоdouble. Все вычисления и возвращаемые значения библиотеки имеют тип_real.
2. Расположение исходников
Важно: каталог src/libs/exprint/ содержит только проектные файлы (exprint.vcxproj и т. п.). Реального исходного кода в нём нет. Проект exprint.vcxproj ссылается на исходники через относительные пути ..\Expr\ и ..\Inter\.
Модуль Expr — src/libs/Expr/
| Файл | Функции |
|---|---|
Expr_com.cpp |
expr_comp, expr_set_angle |
Expr_err.cpp |
expr_set_error_cod, expr_get_error_cod |
Expr_in1.cpp |
expr_atof, expr_inter, expr_numbern |
Expr_per.cpp |
expr_get_per, expr_set_per, expr_is_per |
Expremsg.cpp |
expr_get_error |
Get_err.cpp |
get_expr_err |
Модуль Inter — src/libs/Inter/
| Файл | Функции |
|---|---|
Inte_in1.cpp |
inte_atof, inte_inter, i1nte_atof_1, expr_del_Blanks1 |
Inte_ope.cpp |
inte_oper, inte_select_blanck |
Inte_val.cpp |
inte_set_inter_value, inte_get_inter_value |
Заголовки — src/Include/
| Заголовок | Содержание |
|---|---|
EXPR.H |
Основной API: коды функций, коды ошибок, константы режима углов, прототипы всех публичных функций обоих модулей |
INTER.H |
Структура INTE_OPER, прототипы inte_* (с legacy-атрибутами _far fortran), expr_del_Blanks1 |
M\INTE_FUN.H |
Расширенные прототипы inte_fun / inte_f / inte_logic_expr и др. — реализаций в EXPRINT НЕ найдено |
Файлы вне сборки (не документируются)
DRV_EXPR.CPP,DRV_INTE.CPP— тестовые консольные драйверы (содержатmain, реализуют интерактивный калькулятор). В сборку EXPRINT не входят.Expr.rar— архив, не распакован; содержимое неизвестно.
3. Структуры, типы и константы
3.1. INTE_OPER (INTER.H)
Описание одного ключевого слова оператора интерпретатора (имя + длина).
typedef struct {
char lpszName[32]; // имя ключевого слова оператора, например "return("
int nLenght; // длина ключевого слова (число символов)
} INTE_OPER;
| Поле | Тип | Смысл |
|---|---|---|
lpszName |
char[32] |
Имя оператора с открывающей скобкой: "return(", "if(", "while(" |
nLenght |
int |
Длина строки lpszName (например, 7 для "return(", 3 для "if(", 6 для "while(") |
В Inte_ope.cpp определён статический массив этих структур:
INTE_OPER lpsOper[] = {
{ "return(", 7 },
{ "if(", 3 },
{ "while(", 6 },
};
3.2. Коды встроенных функций (EXPR.H)
Числовые коды функций, передаваемые в expr_comp (см. раздел 4.1 и грамматику в разделе 5).
| Константа | Значение | Функция |
|---|---|---|
ABS |
0 | fabs |
EXP |
1 | exp |
LOG |
2 | log (натуральный) |
SIN |
3 | sin |
COS |
4 | cos |
TAN |
5 | tan |
| (нет имени) | 6 | заглушка "1111", не используется |
SQRT |
7 | sqrt |
SINH |
8 | sinh |
COSH |
9 | cosh |
TANH |
10 | tanh |
ASIN |
11 | asin |
ACOS |
12 | acos |
ATAN |
13 | atan |
LOG10 |
14 | log10 (десятичный) |
3.3. Константы режима углов (EXPR.H)
| Константа | Значение | Смысл |
|---|---|---|
EXPR_RADIAN |
1 | Тригонометрия в радианах (множитель expr_angle = 1.0) |
EXPR_GRADUS |
0 | Тригонометрия в градусах (множитель expr_angle = PI/180) — режим по умолчанию |
3.4. Прочие константы (EXPR.H)
| Константа | Значение | Смысл |
|---|---|---|
FLT_MAX_SIN |
65536. |
Порог модуля аргумента для sin/cos/tan: при |x| > 65536 фиксируется ошибка |
3.5. Внутреннее состояние модулей
Библиотека хранит несколько глобальных статических переменных (не экспортируются напрямую, доступны через функции):
| Переменная | Файл | Тип | Смысл | По умолчанию |
|---|---|---|---|---|
error_cod |
Expr_err.cpp |
int |
Текущий код ошибки разбора | 0 |
expr_angle |
Expr_com.cpp |
_real |
Множитель угла (радианы/градусы) | PI/180 (градусы) |
rExpr_per[256] |
Expr_per.cpp |
_real[256] |
Значения переменных (индекс — код символа имени) | нули |
inter_value |
Inte_val.cpp |
_real |
Сохранённое значение оператора return |
0 |
4. Публичные функции
Сводная таблица
| Функция | Модуль | Файл | Назначение |
|---|---|---|---|
expr_set_angle |
Expr | Expr_com.cpp |
Установить единицы углов (радианы/градусы) |
expr_comp |
Expr | Expr_com.cpp |
Выполнить одну операцию/функцию над операндами |
expr_set_error_cod |
Expr | Expr_err.cpp |
Установить код ошибки |
expr_get_error_cod |
Expr | Expr_err.cpp |
Получить код ошибки |
expr_atof |
Expr | Expr_in1.cpp |
Вычислить арифметическое выражение целиком |
expr_inter |
Expr | Expr_in1.cpp |
Рекурсивный разбор/вычисление подстроки |
expr_numbern |
Expr | Expr_in1.cpp |
Проверить, является ли строка числовым литералом |
expr_get_per |
Expr | Expr_per.cpp |
Получить значение переменной |
expr_set_per |
Expr | Expr_per.cpp |
Задать значение переменной |
expr_is_per |
Expr | Expr_per.cpp |
Проверить, является ли строка именем переменной |
expr_get_error |
Expr | Expremsg.cpp |
Текстовое (англ.) описание текущей ошибки |
get_expr_err |
Expr | Get_err.cpp |
Преобразовать внутренний код ошибки в код проекта (2400+) |
inte_atof |
Inter | Inte_in1.cpp |
Вычислить выражение/последовательность операторов |
inte_inter |
Inter | Inte_in1.cpp |
Интерпретатор верхнего уровня |
i1nte_atof_1 |
Inter | Inte_in1.cpp |
Очистить пробелы + вычислить, результат через указатель |
expr_del_Blanks1 |
Inter | Inte_in1.cpp |
Удалить пробелы/табы/переводы строк (in-place) |
inte_oper |
Inter | Inte_ope.cpp |
Распознать и выполнить return/if/while |
inte_select_blanck |
Inter | Inte_ope.cpp |
Найти закрывающую ) верхнего уровня |
inte_set_inter_value |
Inter | Inte_val.cpp |
Сохранить результат return |
inte_get_inter_value |
Inter | Inte_val.cpp |
Получить сохранённый результат return |
4.1. Модуль Expr (арифметика)
void expr_set_angle(int flag)
Файл: Expr_com.cpp.
Задаёт единицы измерения углов для тригонометрических функций.
- Параметры:
flag(int) —EXPR_GRADUS(0) → градусы (expr_angle = PI/180); любое другое значение, в частностиEXPR_RADIAN(1) → радианы (expr_angle = 1.0).- Возврат: нет.
- Влияние: множитель
expr_angleприменяется внутриexpr_comp: дляsin/cos/tanаргумент умножается наexpr_angle; дляasin/acos/atanрезультат делится наexpr_angle. - По умолчанию: градусы (
expr_angle = PI/180).
_real expr_comp(int cod, char *oper1, int n1, char *oper2, int n2)
Файл: Expr_com.cpp.
Выполняет одну операцию или функцию cod над операндами, заданными строками. Операнды сначала рекурсивно вычисляются через expr_inter.
- Параметры:
cod(int) — код операции. Может быть символом арифметического оператора ('=','+','-','*','/','^'— фактически ASCII-код символа) или числовым кодом функции (ABS…LOG10, см. раздел 3.2).oper1(char*) — строка первого операнда (для функций — её аргумент);n1(int) — длинаoper1; если0, тоop1 = 0;oper2(char*) — строка второго операнда (используется только для бинарных операторов, у которыхcod > LOG10);n2(int) — длинаoper2; если0для бинарного оператора — устанавливаетсяERROR_EXPRESSION.- Возврат: результат операции (
_real). - Особенности и ошибки (по
cod): - если на входе уже установлен ненулевой код ошибки — функция сразу возвращает
0; '='— присваивание:oper1обязан быть именем переменной (expr_is_per), иначеERROR_VARи возврат0; иначе значениеop2записывается в переменную и возвращается;'^'— степень: требуетop1 > 0, иначеERROR_POW; приop2 > |log(FLT_MAX)/log(op1)|→ERROR_OVERFLOW, возвратFLT_MAX;'+','-','*'— арифметика; при результате> FLT_MAX→ERROR_OVERFLOW, возвратFLT_MAX;'/'— деление: приop2 == 0→ERROR_DIV_0, возвратFLT_MAX; при переполнении →ERROR_OVERFLOW;- функции
EXP,LOG,SIN,COS,TAN,ABS,SQRT,SINH,COSH,TANH,ASIN,ACOS,ATAN,LOG10— см. таблицу проверок в разделе 5.5; default(неизвестный код) → устанавливается код ошибки-cod, возврат0.
void expr_set_error_cod(int n)
Файл: Expr_err.cpp.
Устанавливает глобальный код ошибки разбора.
- Параметры:
n(int) — код ошибки (0— нет ошибки; отрицательные значения — см. раздел 6). - Возврат: нет.
int expr_get_error_cod(void)
Файл: Expr_err.cpp.
Возвращает текущий глобальный код ошибки.
- Параметры: нет.
- Возврат: код ошибки (
int).0— ошибок нет.
_real expr_atof(char *string)
Файл: Expr_in1.cpp.
Вычисляет арифметическое выражение целиком. Сбрасывает код ошибки в 0 и делегирует разбор expr_inter.
- Параметры:
string(char*) — строка выражения (без поддержки операторовreturn/if/while— для них используетсяinte_atof). - Возврат: значение выражения (
_real). При ошибке см.expr_get_error_cod(). - Примечание: имя функции (
atof) историческое — это полноценный разбор выражения, а не только преобразование числа.
_real expr_inter(char *lex, int n)
Файл: Expr_in1.cpp.
Рекурсивный разбор и вычисление подстроки lex длиной n. Ядро арифметического интерпретатора.
- Параметры:
lex(char*) — буфер строки выражения (функция временно модифицирует символlex[n], подставляя'\0', затем восстанавливает — буфер должен допускать запись по индексуn);n(int) — длина разбираемой подстроки.- Возврат: значение подстроки (
_real). - Алгоритм (кратко):
1. если уже есть ошибка — возврат
0; 2. если подстрока — числовой литерал (expr_numbern), вычисляется черезatof(при> FLT_MAX→ERROR_OVERFLOW); 3. если подстрока — имя переменной (expr_is_per), возвращается её значение; 4. поиск бинарного оператора верхнего уровня в порядке приоритета строкиarif[] = "=+-*/^"(с учётом вложенности()и{}); при нахождении — вызовexpr_comp; 5. если строка целиком заключена в( )— рекурсия по внутренней части; 6. распознавание имени функции (abs(…log10() и вызовexpr_comp; 7. иначе —ERROR_FUNCTION. - Ошибки:
ERROR_BRACKET(несбалансированные скобки),ERROR_FUNCTION(нераспознанная конструкция),ERROR_OVERFLOW.
int expr_numbern(char *lex, int n)
Файл: Expr_in1.cpp.
Проверяет, является ли строка lex (длиной n) корректным числовым литералом.
- Параметры:
lex(char*) — строка;n(int) — длина.- Возврат:
0— строка является числом;1— не является числом.- Поддерживаемый формат: ведущий знак
-, цифры, одна десятичная точка, экспонента видаe+/e-. Длина литерала ограничена: приn > 40сразу возвращается1.
_real expr_get_per(char *lpszName, int nLenghtName)
Файл: Expr_per.cpp.
Возвращает значение переменной.
- Параметры:
lpszName(char*) — имя переменной; используется только первый символlpszName[0]как индекс в массивеrExpr_per[256];nLenghtName(int) — длина имени (фактически игнорируется в теле функции).- Возврат: значение переменной (
_real).
void expr_set_per(char *lpszName, int nLenghtName, _real rValue)
Файл: Expr_per.cpp.
Устанавливает значение переменной.
- Параметры:
lpszName(char*) — имя переменной; используется только первый символ как индекс вrExpr_per[256];nLenghtName(int) — длина имени (игнорируется в теле);rValue(_real) — записываемое значение.- Возврат: нет.
int expr_is_per(char *lpszName, int nLenghtName)
Файл: Expr_per.cpp.
Проверяет, является ли строка именем переменной (ровно один символ — латинская буква).
- Параметры:
lpszName(char*) — проверяемая строка;nLenghtName(int) — длина строки; должна быть равна 1.- Возврат:
0— это имя переменной (длина 1 и символ изA–Zлибоa–z);-1— не имя переменной.
char* expr_get_error(void)
Файл: Expremsg.cpp.
Возвращает текстовое (на английском) описание текущей ошибки.
- Параметры: нет.
- Возврат: указатель на строку из статического массива
char_error[]. Индекс вычисляется как-expr_get_error_cod(). Массив содержит 23 элемента (индексы0…22), см. раздел 6. - Осторожно: функция не проверяет диапазон. Корректный результат — только для кодов ошибки
0и-1…-22. Иные значения приведут к выходу за границы массива.
int get_expr_err(char *lpszExpr)
Файл: Get_err.cpp.
Преобразует внутренний код ошибки в общий код проекта (диапазон 2400+).
- Параметры:
lpszExpr(char*) — строка выражения (передаётся для возможного вывода сообщения; вызовput_error_messegeв текущей сборке закомментирован). - Возврат:
0— если ошибок нет (nTmp == 0);-nTmp, гдеnTmp = -error_cod, приnTmp > 20ограничивается значением21, затем+= 2400. Итоговые коды проекта: 2401…2421 (возвращаются со знаком минус, т. е.-2401…-2421).- Соответствие внутренних кодов проектным — см. раздел 6.
4.2. Модуль Inter (операторы return / if / while)
_real inte_atof(char *string)
Файл: Inte_in1.cpp.
Вычисляет выражение или последовательность операторов интерпретатора. Точка входа для формул с return/if/while.
- Параметры:
string(char*) — строка (буфер должен допускать модификацию по индексу длины — см.inte_inter/expr_inter). - Возврат: значение (
_real). - Логика: сбрасывает код ошибки в
0, вычисляет черезinte_inter. Если по завершении установленERROR_RETURN— возвращается сохранённое значениеinte_get_inter_value(), а код ошибки сбрасывается в0(то естьreturnтрактуется как штатное завершение).
_real inte_inter(char *lex, int n)
Файл: Inte_in1.cpp.
Интерпретатор верхнего уровня. Разбивает строку на последовательность операторов и вычисляет их по порядку.
- Параметры:
lex(char*) — буфер строки;n(int) — длина.- Возврат: значение (
_real). - Алгоритм:
1. если есть ошибка — возврат
0; пустая строка или одиночный;— возврат0; 2. если строка целиком в блочных скобках{ }— рекурсия по внутренней части; 3. поиск разделителя операторов — символа;верхнего уровня (с учётом вложенности{}и()); при нахождении — последовательное вычисление левой и правой частей (возвращается результат правой); 4. при несбалансированных скобках —ERROR_BRACKET; 5. попытка вычислить как арифметическое выражение черезexpr_inter; если успех — возврат результата; если ошибка неERROR_FUNCTION— возврат0; 6. иначе попытка распознать оператор черезinte_oper; при коде0илиERROR_RETURN— возврат результата; 7. иначе —ERROR_FUNCTION. - Разделитель операторов: символ
;(INTER_BLANCK) на верхнем уровне вложенности.
int i1nte_atof_1(char *string, double *r)
Файл: Inte_in1.cpp.
Удаляет из строки пробельные символы и вычисляет её; результат возвращает через указатель.
- Параметры:
string(char*) — строка (модифицируется in-place функциейexpr_del_Blanks1);r(double*) — выход: вычисленное значение.- Возврат: код ошибки (
int) — результатexpr_get_error_cod()после вычисления (0— успех). - Логика:
expr_del_Blanks1(string)→*r = inte_atof(string)→ возврат кода ошибки.
int expr_del_Blanks1(char *ch)
Файл: Inte_in1.cpp.
Удаляет из строки (in-place) все пробелы, табуляции и переводы строк.
- Параметры:
ch(char*) — строка (изменяется на месте; завершающий'\0'сохраняется). - Возврат: всегда
0. - Удаляемые символы:
' '(пробел),'\t'(табуляция),'\n'(перевод строки).
_real inte_oper(char *lex, int n)
Файл: Inte_ope.cpp.
Распознаёт и выполняет один из управляющих операторов: return(...), if(...) ..., while(...) ....
- Параметры:
lex(char*) — буфер строки оператора;n(int) — длина.- Возврат: значение (
_real). - Поведение по операторам:
return(expr)— вычисляетexprчерезinte_inter; при отсутствии ошибки устанавливаетERROR_RETURN, сохраняет значение черезinte_set_inter_valueи возвращает его;if(cond) stmt— находит конец условия (inte_select_blanck), вычисляетcond; еслиcond < 0— операторstmtпропускается (ветвиelseнет), возвращаетсяcond; иначе вычисляется и возвращаетсяstmt;while(cond) stmt— покаcond >= 0: вычисляетstmt, затем повторно вычисляетcond; завершает работу, когдаcond < 0; при ошибке на любом шаге — возврат0;- если ни один оператор не распознан —
ERROR_FUNCTION, возврат0.
int inte_select_blanck(char *lex, int n)
Файл: Inte_ope.cpp.
Находит позицию закрывающей скобки ) верхнего уровня (конец условия оператора), учитывая вложенность () и {}.
- Параметры:
lex(char*) — строка (начиная сразу после ключевого слова оператора);n(int) — длина.- Возврат: индекс закрывающей
)верхнего уровня (илиn, если не найдена). - Учёт вложенности: счётчики глубины для круглых
()и фигурных{}скобок.
void inte_set_inter_value(_real r)
Файл: Inte_val.cpp.
Сохраняет значение, возвращаемое оператором return.
- Параметры:
r(_real) — сохраняемое значение. - Возврат: нет.
_real inte_get_inter_value(void)
Файл: Inte_val.cpp.
Возвращает значение, ранее сохранённое оператором return.
- Параметры: нет.
- Возврат: сохранённое значение (
_real); по умолчанию0.
5. Грамматика выражений
5.1. Числа
- Числовые литералы: целые и дробные (десятичная точка
.), с необязательным ведущим знаком-. - Экспоненциальная запись:
e+/e-(например,1.5e-3). - Распознаются функцией
expr_numbern. Максимальная длина литерала — 40 символов (свыше — не считается числом).
5.2. Переменные
- Имя переменной — ровно один латинский символ:
A–Zилиa–z. - Значения хранятся в массиве из 256 ячеек
rExpr_per[256], индексируемом кодом первого символа имени. Строчные и прописные буквы — разные переменные (разные коды). - Чтение —
expr_get_per, запись — оператор=илиexpr_set_per, проверка имени —expr_is_per.
5.3. Операторы (строка arif[] = "=+-*/^")
Бинарные операторы ищутся в строке выражения справа налево, в порядке элементов строки arif. Поиск ведётся только на верхнем уровне вложенности (с учётом () и {}).
| Оператор | Назначение | Проверки и ошибки |
|---|---|---|
= |
Присваивание var = expr |
Левый операнд обязан быть именем переменной, иначе ERROR_VAR |
+ |
Сложение | При результате > FLT_MAX → ERROR_OVERFLOW |
- |
Вычитание | При результате > FLT_MAX → ERROR_OVERFLOW |
* |
Умножение | При результате > FLT_MAX → ERROR_OVERFLOW |
/ |
Деление | При делителе 0 → ERROR_DIV_0 (возврат FLT_MAX); при переполнении → ERROR_OVERFLOW |
^ |
Возведение в степень | Требует основание op1 > 0, иначе ERROR_POW; при op2 > \|log(FLT_MAX)/log(op1)\| → ERROR_OVERFLOW |
5.4. Скобки
( )— группировка арифметических подвыражений. Должны быть сбалансированы, иначеERROR_BRACKET.{ }— блочные скобки уровня интерпретатора (тело операторовif/while, группировка операторов). Учитываются при поиске разделителей и закрывающих скобок.
5.5. Встроенные функции
Имя функции записывается со скобкой, например sin(x). Аргумент вычисляется рекурсивно. Угловой режим (см. expr_set_angle) влияет на тригонометрию.
| Имя | Код | Действие | Проверки и ошибки |
|---|---|---|---|
abs( |
ABS (0) |
fabs(x) |
нет |
exp( |
EXP (1) |
exp(x) |
при x > log(FLT_MAX) → ошибка -EXP, возврат FLT_MAX |
log( |
LOG (2) |
натуральный логарифм | при x <= 0 → ошибка -LOG, возврат 0 |
sin( |
SIN (3) |
sin(x * expr_angle) |
при \|x\| > 65536 → ошибка -SIN, возврат 0 |
cos( |
COS (4) |
cos(x * expr_angle) |
при \|x\| > 65536 → ошибка -COS, возврат 0 |
tan( |
TAN (5) |
tan(x * expr_angle) |
при \|x\| > 65536 → ошибка -TAN, возврат 0 |
| — | (6) | заглушка "1111" |
не используется |
sqrt( |
SQRT (7) |
sqrt(x) |
при x < 0 → ошибка -SQRT, возврат 0 |
sinh( |
SINH (8) |
sinh(x) |
при x > log(FLT_MAX) → ошибка -SINH, возврат FLT_MAX |
cosh( |
COSH (9) |
cosh(x) |
при x > log(FLT_MAX) → ошибка -COSH, возврат FLT_MAX |
tanh( |
TANH (10) |
tanh(x) |
проверок нет |
asin( |
ASIN (11) |
asin(x) / expr_angle |
при \|x\| > 1 → ошибка -ASIN, возврат 0 |
acos( |
ACOS (12) |
acos(x) / expr_angle |
при \|x\| > 1 → ошибка -ACOS, возврат 0 |
atan( |
ATAN (13) |
atan(x) / expr_angle |
проверок нет |
log10( |
LOG10 (14) |
десятичный логарифм | при x <= 0 → ошибка -LOG10, возврат 0 |
5.6. Операторы интерпретатора (модуль Inter)
| Оператор | Синтаксис | Семантика |
|---|---|---|
return |
return(expr) |
Вычисляет expr, сохраняет результат (inte_set_inter_value), устанавливает ERROR_RETURN. inte_atof трактует это как штатное завершение и возвращает сохранённое значение. |
if |
if(cond) stmt |
Если cond < 0 — stmt пропускается (ветви else нет), результат равен cond; иначе выполняется stmt. |
while |
while(cond) stmt |
Пока cond >= 0: выполняет stmt, затем пересчитывает cond. |
Разделитель операторов в последовательности — символ ; на верхнем уровне (см. примечание в inte_inter).
5.7. Угловой режим
Тригонометрические функции и обратные к ним учитывают глобальный множитель expr_angle, задаваемый expr_set_angle:
- градусы (по умолчанию):
expr_angle = PI/180; - радианы:
expr_angle = 1.0.
Для прямых функций (sin/cos/tan) аргумент умножается на expr_angle; для обратных (asin/acos/atan) результат делится на expr_angle.
6. Коды ошибок разбора
6.1. Внутренние коды (EXPR.H)
Внутренние коды ошибок — отрицательные целые. Хранятся в error_cod (Expr_err.cpp).
| Константа | Значение | Смысл | Текст char_error[-cod] (англ.) |
|---|---|---|---|
| (нет ошибки) | 0 |
Всё в порядке | "all right" |
-EXP |
-1 |
Переполнение в exp |
"overflow in function exp" |
-LOG |
-2 |
Аргумент log <= 0 |
"argument LOG <= 0 (bad)" |
-SIN |
-3 |
\|x\| > 65536 в sin |
"overflow in function sin (argument > 65536)" |
-COS |
-4 |
\|x\| > 65536 в cos |
"overflow in function cos (argument > 65536)" |
-TAN |
-5 |
\|x\| > 65536 в tan |
"overflow in function tan (argument > 65536 or = pi/2" |
| (код 6) | -6 |
(заглушка) | "overflow" |
-SQRT |
-7 |
Аргумент sqrt < 0 |
"argument SQRT < 0 (bad)" |
-SINH |
-8 |
Переполнение в sinh |
"overflow in function sinh" |
-COSH |
-9 |
Переполнение в cosh |
"overflow in function cosh" |
-TANH |
-10 |
(зарезервировано) | "overflow in function tanh" |
-ASIN |
-11 |
Аргумент asin > 1 |
"argument ASIN > 1 (bad)" |
-ACOS |
-12 |
Аргумент acos > 1 |
"argument ACOS > 1 (bad)" |
| (код 13) | -13 |
(зарезервировано) | "overflow" |
-LOG10 |
-14 |
Аргумент log10 <= 0 |
"argument LOG10 <=0 (bad)" |
ERROR_DIV_0 |
-15 |
Деление на ноль | "overflow x/y" |
ERROR_POW |
-16 |
x^y при x < 0 (основание ≤ 0) |
"for x^y x<0" |
ERROR_BRACKET |
-17 |
Несбалансированные скобки | "abnormal bracket" |
ERROR_FUNCTION |
-18 |
Нераспознанная функция/конструкция | "abnormal function" |
ERROR_EXPRESSION |
-19 |
Некорректное выражение | "abnormal expression" |
ERROR_OVERFLOW |
-20 |
Переполнение float |
"float overflow" |
ERROR_RETURN |
-21 |
Сработал оператор return |
"bad parameter in =" |
ERROR_VAR |
-22 |
Левый операнд = не переменная |
"bad return" |
Внимание на сдвиг: тексты в
char_error[]для индексов 21 и 22 смещены относительно смысла кодов (ERROR_RETURN = -21соответствует тексту"bad parameter in =", аERROR_VAR = -22— тексту"bad return"). Это особенность исходного массива вExpremsg.cpp(массив содержит 23 элемента, индексы 0…22). Сообщения на английском.
6.2. Маппинг в коды проекта (2401…2421) через get_expr_err
Функция get_expr_err (Get_err.cpp) преобразует внутренний код в общий код проекта:
int nTmp = -expr_get_error_cod(); // 0..22
if (nTmp == 0) return 0; // нет ошибок
if (nTmp > 20) nTmp = 21; // все коды > 20 схлопываются в 21
nTmp += 2400; // 2401..2421
return -nTmp; // возвращается со знаком минус
Внутренний код (error_cod) |
nTmp |
Код проекта | Возврат get_expr_err |
|---|---|---|---|
0 |
0 | — | 0 |
-1…-20 |
1…20 | 2401…2420 | -2401…-2420 |
-21, -22 (ERROR_RETURN, ERROR_VAR) |
→ 21 | 2421 | -2421 |
Коды проекта ERROR_EXPR_* (2401…2420) определены в Error1.h.
7. Зависимости
Общие заголовки (src/Include/):
| Заголовок | Где используется | Назначение |
|---|---|---|
typedef.h |
оба модуля | Определение типа _real (float/double) и др. |
expr.h (EXPR.H) |
модуль Expr, INTER.H |
Основной API, коды функций/ошибок |
inter.h (INTER.H) |
модуль Inter | Структура INTE_OPER, прототипы inte_* |
tmc_lib.h |
Expr_in1.cpp, Inte_*.cpp |
Назначение не исследовано |
error1.h (Error1.h) |
только Get_err.cpp |
Коды ошибок проекта (ERROR_EXPR_*) |
Стандартные заголовки C/C++: math.h, float.h, stdio.h, stdlib.h, string.h, conio.h.
Связь с другими библиотеками TMC Suite:
- Библиотеку complex EXPRINT напрямую не использует — задействован лишь скалярный тип
_real. - Прямых
#includeиз SFILE95, TMCLibError, PREPR, TMCIndan в исходниках EXPRINT не обнаружено.
The EXPRINT library — API documentation
TMC Suite package. A static interpreter library for string mathematical expressions (parsing and evaluation of formulas). All signatures are taken from the sources in
src/libs/Expr/,src/libs/Inter/and the shared headers fromsrc/Include/.
1. Purpose of the library
EXPRINT is a static library that implements an interpreter of string mathematical expressions (a formula evaluator).
The library takes as input a formula as a text string (for example, "sin(x)+2*y",
"return(A^2)", "if(x-1) y=5") and returns its numeric value of type _real.
Supported:
- arithmetic:
=(assignment),+,-,*,/,^(power); - grouping parentheses
( )and block braces{ }; - built-in elementary functions:
abs,exp,log,log10,sin,cos,tan,sqrt,sinh,cosh,tanh,asin,acos,atan; - variables — a single Latin letter
A–Z/a–z(an array of 256 cells, indexed by the character code); - interpreter control operators:
return(...),if(...) ...,while(...) ...; - a choice of angle units for trigonometry (radians or degrees).
The library is logically divided into two modules:
- The Expr module (
src/libs/Expr/) — the arithmetic core: lexical parsing, expression evaluation, functions, variables, error-code handling. - The Inter module (
src/libs/Inter/) — the interpreter add-on: thereturn/if/whileoperators, splitting a string into a sequence of operators, whitespace cleanup.
The library is used in the package's viewers (the CTMCGrExpression class — it is
not part of EXPRINT and is documented as part of the viewers) to build custom
graphs from entered formulas.
Origin: TAMIC_soft(R), 25.10.1991, v2.00 — historical code for DOS / win16, ported to TMC Suite.
About the
_far,fortranmacros. These are legacy memory-model and calling-convention attributes from 16-bit code (Microsoft C / early Visual C++). In the headerINTER.Ha number of prototypes are declared as_real _far fortran inte_atof(...). In the modern 32/64-bit build these macros usually expand to nothing and do not affect the semantics. For brevity they are omitted from the signatures below (a "clean" prototype is given). SeeEXPR.H/INTER.Hfor the full prototypes.About the
_realtype. The_realtype is defined in the external headertypedef.hand, depending on the build, corresponds tofloatordouble. All of the library's computations and return values are of type_real.
2. Location of the sources
Important: the directory
src/libs/exprint/contains only project files (exprint.vcxproj, etc.). There is no actual source code in it. Theexprint.vcxprojproject references the sources through the relative paths..\Expr\and..\Inter\.
The Expr module — src/libs/Expr/
| File | Functions |
|---|---|
Expr_com.cpp |
expr_comp, expr_set_angle |
Expr_err.cpp |
expr_set_error_cod, expr_get_error_cod |
Expr_in1.cpp |
expr_atof, expr_inter, expr_numbern |
Expr_per.cpp |
expr_get_per, expr_set_per, expr_is_per |
Expremsg.cpp |
expr_get_error |
Get_err.cpp |
get_expr_err |
The Inter module — src/libs/Inter/
| File | Functions |
|---|---|
Inte_in1.cpp |
inte_atof, inte_inter, i1nte_atof_1, expr_del_Blanks1 |
Inte_ope.cpp |
inte_oper, inte_select_blanck |
Inte_val.cpp |
inte_set_inter_value, inte_get_inter_value |
Headers — src/Include/
| Header | Contents |
|---|---|
EXPR.H |
The main API: function codes, error codes, angle-mode constants, prototypes of all public functions of both modules |
INTER.H |
The INTE_OPER structure, the inte_* prototypes (with the legacy _far fortran attributes), expr_del_Blanks1 |
M\INTE_FUN.H |
Extended prototypes inte_fun / inte_f / inte_logic_expr, etc. — no implementations found in EXPRINT |
Files outside the build (not documented)
DRV_EXPR.CPP,DRV_INTE.CPP— test console drivers (containmain, implement an interactive calculator). Not part of the EXPRINT build.Expr.rar— an archive, not unpacked; its contents are unknown.
3. Structures, types and constants
3.1. INTE_OPER (INTER.H)
The description of one interpreter-operator keyword (name + length).
typedef struct {
char lpszName[32]; // the operator keyword name, e.g. "return("
int nLenght; // the length of the keyword (number of characters)
} INTE_OPER;
| Field | Type | Meaning |
|---|---|---|
lpszName |
char[32] |
The operator name with the opening parenthesis: "return(", "if(", "while(" |
nLenght |
int |
The length of the lpszName string (for example, 7 for "return(", 3 for "if(", 6 for "while(") |
In Inte_ope.cpp a static array of these structures is defined:
INTE_OPER lpsOper[] = {
{ "return(", 7 },
{ "if(", 3 },
{ "while(", 6 },
};
3.2. Built-in function codes (EXPR.H)
The numeric codes of the functions passed into expr_comp (see section 4.1 and the
grammar in section 5).
| Constant | Value | Function |
|---|---|---|
ABS |
0 | fabs |
EXP |
1 | exp |
LOG |
2 | log (natural) |
SIN |
3 | sin |
COS |
4 | cos |
TAN |
5 | tan |
| (no name) | 6 | the "1111" stub, not used |
SQRT |
7 | sqrt |
SINH |
8 | sinh |
COSH |
9 | cosh |
TANH |
10 | tanh |
ASIN |
11 | asin |
ACOS |
12 | acos |
ATAN |
13 | atan |
LOG10 |
14 | log10 (decimal) |
3.3. Angle-mode constants (EXPR.H)
| Constant | Value | Meaning |
|---|---|---|
EXPR_RADIAN |
1 | Trigonometry in radians (the factor expr_angle = 1.0) |
EXPR_GRADUS |
0 | Trigonometry in degrees (the factor expr_angle = PI/180) — the default mode |
3.4. Other constants (EXPR.H)
| Constant | Value | Meaning |
|---|---|---|
FLT_MAX_SIN |
65536. |
The threshold of the argument magnitude for sin/cos/tan: when |x| > 65536 an error is recorded |
3.5. The internal state of the modules
The library stores several global static variables (not exported directly, accessible through functions):
| Variable | File | Type | Meaning | Default |
|---|---|---|---|---|
error_cod |
Expr_err.cpp |
int |
The current parse error code | 0 |
expr_angle |
Expr_com.cpp |
_real |
The angle factor (radians/degrees) | PI/180 (degrees) |
rExpr_per[256] |
Expr_per.cpp |
_real[256] |
The variable values (the index is the code of the name character) | zeros |
inter_value |
Inte_val.cpp |
_real |
The saved value of the return operator |
0 |
4. Public functions
Summary table
| Function | Module | File | Purpose |
|---|---|---|---|
expr_set_angle |
Expr | Expr_com.cpp |
Set the angle units (radians/degrees) |
expr_comp |
Expr | Expr_com.cpp |
Perform one operation/function on the operands |
expr_set_error_cod |
Expr | Expr_err.cpp |
Set the error code |
expr_get_error_cod |
Expr | Expr_err.cpp |
Get the error code |
expr_atof |
Expr | Expr_in1.cpp |
Evaluate a whole arithmetic expression |
expr_inter |
Expr | Expr_in1.cpp |
Recursive parsing/evaluation of a substring |
expr_numbern |
Expr | Expr_in1.cpp |
Check whether a string is a numeric literal |
expr_get_per |
Expr | Expr_per.cpp |
Get a variable value |
expr_set_per |
Expr | Expr_per.cpp |
Set a variable value |
expr_is_per |
Expr | Expr_per.cpp |
Check whether a string is a variable name |
expr_get_error |
Expr | Expremsg.cpp |
A text (English) description of the current error |
get_expr_err |
Expr | Get_err.cpp |
Convert an internal error code into a project code (2400+) |
inte_atof |
Inter | Inte_in1.cpp |
Evaluate an expression/sequence of operators |
inte_inter |
Inter | Inte_in1.cpp |
The top-level interpreter |
i1nte_atof_1 |
Inter | Inte_in1.cpp |
Clean whitespace + evaluate, the result via a pointer |
expr_del_Blanks1 |
Inter | Inte_in1.cpp |
Remove spaces/tabs/newlines (in-place) |
inte_oper |
Inter | Inte_ope.cpp |
Recognize and execute return/if/while |
inte_select_blanck |
Inter | Inte_ope.cpp |
Find the top-level closing ) |
inte_set_inter_value |
Inter | Inte_val.cpp |
Save the return result |
inte_get_inter_value |
Inter | Inte_val.cpp |
Get the saved return result |
4.1. The Expr module (arithmetic)
void expr_set_angle(int flag)
File: Expr_com.cpp.
Sets the angle units for the trigonometric functions.
- Parameters:
flag(int) —EXPR_GRADUS(0) → degrees (expr_angle = PI/180); any other value, in particularEXPR_RADIAN(1) → radians (expr_angle = 1.0).- Return: none.
- Effect: the
expr_anglefactor is applied insideexpr_comp: forsin/cos/tanthe argument is multiplied byexpr_angle; forasin/acos/atanthe result is divided byexpr_angle. - Default: degrees (
expr_angle = PI/180).
_real expr_comp(int cod, char *oper1, int n1, char *oper2, int n2)
File: Expr_com.cpp.
Performs one operation or function cod on the operands given as strings. The
operands are first recursively evaluated via expr_inter.
- Parameters:
cod(int) — the operation code. It can be the character of an arithmetic operator ('=','+','-','*','/','^'— in fact the ASCII code of the character) or a numeric function code (ABS…LOG10, see section 3.2).oper1(char*) — the string of the first operand (for functions — its argument);n1(int) — the length ofoper1; if0, thenop1 = 0;oper2(char*) — the string of the second operand (used only for binary operators, for whichcod > LOG10);n2(int) — the length ofoper2; if0for a binary operator,ERROR_EXPRESSIONis set.- Return: the result of the operation (
_real). - Features and errors (by
cod): - if a non-zero error code is already set on input — the function immediately
returns
0; '='— assignment:oper1must be a variable name (expr_is_per), otherwiseERROR_VARand a return of0; otherwise the valueop2is written into the variable and returned;'^'— power: requiresop1 > 0, otherwiseERROR_POW; whenop2 > |log(FLT_MAX)/log(op1)|→ERROR_OVERFLOW, returnFLT_MAX;'+','-','*'— arithmetic; when the result is> FLT_MAX→ERROR_OVERFLOW, returnFLT_MAX;'/'— division: whenop2 == 0→ERROR_DIV_0, returnFLT_MAX; on overflow →ERROR_OVERFLOW;- the functions
EXP,LOG,SIN,COS,TAN,ABS,SQRT,SINH,COSH,TANH,ASIN,ACOS,ATAN,LOG10— see the checks table in section 5.5; default(an unknown code) → the error code-codis set, return0.
void expr_set_error_cod(int n)
File: Expr_err.cpp.
Sets the global parse error code.
- Parameters:
n(int) — the error code (0— no error; negative values — see section 6). - Return: none.
int expr_get_error_cod(void)
File: Expr_err.cpp.
Returns the current global error code.
- Parameters: none.
- Return: the error code (
int).0— no errors.
_real expr_atof(char *string)
File: Expr_in1.cpp.
Evaluates a whole arithmetic expression. Resets the error code to 0 and
delegates the parsing to expr_inter.
- Parameters:
string(char*) — the expression string (without support for thereturn/if/whileoperators — for thoseinte_atofis used). - Return: the value of the expression (
_real). On error, seeexpr_get_error_cod(). - Note: the function name (
atof) is historical — it is a full expression parse, not just a number conversion.
_real expr_inter(char *lex, int n)
File: Expr_in1.cpp.
Recursive parsing and evaluation of a substring lex of length n. The core of
the arithmetic interpreter.
- Parameters:
lex(char*) — the buffer of the expression string (the function temporarily modifies the characterlex[n], substituting'\0', then restores it — the buffer must allow writing at indexn);n(int) — the length of the substring being parsed.- Return: the value of the substring (
_real). - Algorithm (briefly):
1. if there is already an error — return
0; 2. if the substring is a numeric literal (expr_numbern), it is computed viaatof(when> FLT_MAX→ERROR_OVERFLOW); 3. if the substring is a variable name (expr_is_per), its value is returned; 4. the search for a top-level binary operator in the priority order of the stringarif[] = "=+-*/^"(taking into account the nesting of()and{}); when found — a call ofexpr_comp; 5. if the string is entirely enclosed in( )— recursion over the inner part; 6. recognition of a function name (abs(…log10() and a call ofexpr_comp; 7. otherwise —ERROR_FUNCTION. - Errors:
ERROR_BRACKET(unbalanced parentheses),ERROR_FUNCTION(an unrecognized construct),ERROR_OVERFLOW.
int expr_numbern(char *lex, int n)
File: Expr_in1.cpp.
Checks whether the string lex (of length n) is a valid numeric literal.
- Parameters:
lex(char*) — the string;n(int) — the length.- Return:
0— the string is a number;1— it is not a number.- Supported format: a leading
-sign, digits, one decimal point, an exponent of the forme+/e-. The literal length is limited: whenn > 40,1is returned immediately.
_real expr_get_per(char *lpszName, int nLenghtName)
File: Expr_per.cpp.
Returns the value of a variable.
- Parameters:
lpszName(char*) — the variable name; only the first characterlpszName[0]is used as the index in the arrayrExpr_per[256];nLenghtName(int) — the name length (in fact ignored in the function body).- Return: the variable value (
_real).
void expr_set_per(char *lpszName, int nLenghtName, _real rValue)
File: Expr_per.cpp.
Sets the value of a variable.
- Parameters:
lpszName(char*) — the variable name; only the first character is used as the index inrExpr_per[256];nLenghtName(int) — the name length (ignored in the body);rValue(_real) — the value to write.- Return: none.
int expr_is_per(char *lpszName, int nLenghtName)
File: Expr_per.cpp.
Checks whether a string is a variable name (exactly one character — a Latin letter).
- Parameters:
lpszName(char*) — the string being checked;nLenghtName(int) — the string length; must equal 1.- Return:
0— it is a variable name (length 1 and a character fromA–Zora–z);-1— it is not a variable name.
char* expr_get_error(void)
File: Expremsg.cpp.
Returns a text (English) description of the current error.
- Parameters: none.
- Return: a pointer to a string from the static array
char_error[]. The index is computed as-expr_get_error_cod(). The array contains 23 elements (indices0…22), see section 6. - Caution: the function does not check the range. A correct result is obtained only
for the error codes
0and-1…-22. Other values will lead to an out-of-bounds access.
int get_expr_err(char *lpszExpr)
File: Get_err.cpp.
Converts an internal error code into a common project code (the range 2400+).
- Parameters:
lpszExpr(char*) — the expression string (passed for a possible message output; theput_error_messegecall is commented out in the current build). - Return:
0— if there are no errors (nTmp == 0);-nTmp, wherenTmp = -error_cod, whennTmp > 20it is capped at21, then+= 2400. The resulting project codes: 2401…2421 (returned with a minus sign, i.e.-2401…-2421).- The correspondence of the internal codes to the project codes — see section 6.
4.2. The Inter module (the return / if / while operators)
_real inte_atof(char *string)
File: Inte_in1.cpp.
Evaluates an expression or a sequence of operators of the interpreter. The entry
point for formulas with return/if/while.
- Parameters:
string(char*) — the string (the buffer must allow modification at the length index — seeinte_inter/expr_inter). - Return: the value (
_real). - Logic: resets the error code to
0, evaluates viainte_inter. If on completionERROR_RETURNis set — the saved valueinte_get_inter_value()is returned, and the error code is reset to0(that is,returnis treated as a normal completion).
_real inte_inter(char *lex, int n)
File: Inte_in1.cpp.
The top-level interpreter. Splits the string into a sequence of operators and evaluates them in order.
- Parameters:
lex(char*) — the string buffer;n(int) — the length.- Return: the value (
_real). - Algorithm:
1. if there is an error — return
0; an empty string or a single;— return0; 2. if the string is entirely in the block braces{ }— recursion over the inner part; 3. the search for the operator separator — a top-level;character (taking into account the nesting of{}and()); when found — the sequential evaluation of the left and right parts (the result of the right one is returned); 4. on unbalanced parentheses —ERROR_BRACKET; 5. an attempt to evaluate as an arithmetic expression viaexpr_inter; on success — return the result; if the error is notERROR_FUNCTION— return0; 6. otherwise an attempt to recognize an operator viainte_oper; with code0orERROR_RETURN— return the result; 7. otherwise —ERROR_FUNCTION. - The operator separator: the
;character (INTER_BLANCK) at the top nesting level.
int i1nte_atof_1(char *string, double *r)
File: Inte_in1.cpp.
Removes whitespace characters from the string and evaluates it; the result is returned through a pointer.
- Parameters:
string(char*) — the string (modified in-place by theexpr_del_Blanks1function);r(double*) — output: the computed value.- Return: the error code (
int) — the result ofexpr_get_error_cod()after evaluation (0— success). - Logic:
expr_del_Blanks1(string)→*r = inte_atof(string)→ return the error code.
int expr_del_Blanks1(char *ch)
File: Inte_in1.cpp.
Removes from the string (in-place) all spaces, tabs and newlines.
- Parameters:
ch(char*) — the string (modified in place; the terminating'\0'is kept). - Return: always
0. - Removed characters:
' '(space),'\t'(tab),'\n'(newline).
_real inte_oper(char *lex, int n)
File: Inte_ope.cpp.
Recognizes and executes one of the control operators: return(...), if(...) ...,
while(...) ....
- Parameters:
lex(char*) — the buffer of the operator string;n(int) — the length.- Return: the value (
_real). - Behavior by operator:
return(expr)— evaluatesexprviainte_inter; in the absence of an error it setsERROR_RETURN, saves the value viainte_set_inter_valueand returns it;if(cond) stmt— finds the end of the condition (inte_select_blanck), evaluatescond; ifcond < 0the operatorstmtis skipped (there is noelsebranch),condis returned; otherwisestmtis evaluated and returned;while(cond) stmt— whilecond >= 0: evaluatesstmt, then re-evaluatescond; ends whencond < 0; on an error at any step — return0;- if no operator is recognized —
ERROR_FUNCTION, return0.
int inte_select_blanck(char *lex, int n)
File: Inte_ope.cpp.
Finds the position of the top-level closing parenthesis ) (the end of the
operator condition), taking into account the nesting of () and {}.
- Parameters:
lex(char*) — the string (starting right after the operator keyword);n(int) — the length.- Return: the index of the top-level closing
)(ornif not found). - Nesting accounting: depth counters for round
()and curly{}brackets.
void inte_set_inter_value(_real r)
File: Inte_val.cpp.
Saves the value returned by the return operator.
- Parameters:
r(_real) — the value to save. - Return: none.
_real inte_get_inter_value(void)
File: Inte_val.cpp.
Returns the value previously saved by the return operator.
- Parameters: none.
- Return: the saved value (
_real);0by default.
5. Expression grammar
5.1. Numbers
- Numeric literals: integers and fractions (a decimal point
.), with an optional leading-sign. - Exponential notation:
e+/e-(for example,1.5e-3). - Recognized by the
expr_numbernfunction. The maximum literal length is 40 characters (beyond that — not treated as a number).
5.2. Variables
- A variable name is exactly one Latin character:
A–Zora–z. - The values are stored in an array of 256 cells
rExpr_per[256], indexed by the code of the first character of the name. Lowercase and uppercase letters are different variables (different codes). - Reading —
expr_get_per, writing — the=operator orexpr_set_per, name check —expr_is_per.
5.3. Operators (the string arif[] = "=+-*/^")
Binary operators are searched for in the expression string from right to left, in the
order of the elements of the arif string. The search is done only at the top
level of nesting (taking () and {} into account).
| Operator | Purpose | Checks and errors |
|---|---|---|
= |
Assignment var = expr |
The left operand must be a variable name, otherwise ERROR_VAR |
+ |
Addition | When the result is > FLT_MAX → ERROR_OVERFLOW |
- |
Subtraction | When the result is > FLT_MAX → ERROR_OVERFLOW |
* |
Multiplication | When the result is > FLT_MAX → ERROR_OVERFLOW |
/ |
Division | On a divisor of 0 → ERROR_DIV_0 (return FLT_MAX); on overflow → ERROR_OVERFLOW |
^ |
Exponentiation | Requires the base op1 > 0, otherwise ERROR_POW; when op2 > \|log(FLT_MAX)/log(op1)\| → ERROR_OVERFLOW |
5.4. Parentheses
( )— grouping of arithmetic subexpressions. They must be balanced, otherwiseERROR_BRACKET.{ }— block braces at the interpreter level (the body ofif/whileoperators, operator grouping). Taken into account when searching for separators and closing brackets.
5.5. Built-in functions
A function name is written with a parenthesis, for example sin(x). The argument is
evaluated recursively. The angle mode (see expr_set_angle) affects trigonometry.
| Name | Code | Action | Checks and errors |
|---|---|---|---|
abs( |
ABS (0) |
fabs(x) |
none |
exp( |
EXP (1) |
exp(x) |
when x > log(FLT_MAX) → error -EXP, return FLT_MAX |
log( |
LOG (2) |
natural logarithm | when x <= 0 → error -LOG, return 0 |
sin( |
SIN (3) |
sin(x * expr_angle) |
when \|x\| > 65536 → error -SIN, return 0 |
cos( |
COS (4) |
cos(x * expr_angle) |
when \|x\| > 65536 → error -COS, return 0 |
tan( |
TAN (5) |
tan(x * expr_angle) |
when \|x\| > 65536 → error -TAN, return 0 |
| — | (6) | the "1111" stub |
not used |
sqrt( |
SQRT (7) |
sqrt(x) |
when x < 0 → error -SQRT, return 0 |
sinh( |
SINH (8) |
sinh(x) |
when x > log(FLT_MAX) → error -SINH, return FLT_MAX |
cosh( |
COSH (9) |
cosh(x) |
when x > log(FLT_MAX) → error -COSH, return FLT_MAX |
tanh( |
TANH (10) |
tanh(x) |
no checks |
asin( |
ASIN (11) |
asin(x) / expr_angle |
when \|x\| > 1 → error -ASIN, return 0 |
acos( |
ACOS (12) |
acos(x) / expr_angle |
when \|x\| > 1 → error -ACOS, return 0 |
atan( |
ATAN (13) |
atan(x) / expr_angle |
no checks |
log10( |
LOG10 (14) |
decimal logarithm | when x <= 0 → error -LOG10, return 0 |
5.6. Interpreter operators (the Inter module)
| Operator | Syntax | Semantics |
|---|---|---|
return |
return(expr) |
Evaluates expr, saves the result (inte_set_inter_value), sets ERROR_RETURN. inte_atof treats this as a normal completion and returns the saved value. |
if |
if(cond) stmt |
If cond < 0 — stmt is skipped (there is no else branch), the result equals cond; otherwise stmt is executed. |
while |
while(cond) stmt |
While cond >= 0: executes stmt, then recomputes cond. |
The operator separator in a sequence is the ; character at the top level (see the
note in inte_inter).
5.7. The angle mode
The trigonometric functions and their inverses take into account the global factor
expr_angle, set by expr_set_angle:
- degrees (by default):
expr_angle = PI/180; - radians:
expr_angle = 1.0.
For the direct functions (sin/cos/tan) the argument is multiplied by
expr_angle; for the inverses (asin/acos/atan) the result is divided by
expr_angle.
6. Parse error codes
6.1. Internal codes (EXPR.H)
The internal error codes are negative integers. They are stored in error_cod
(Expr_err.cpp).
| Constant | Value | Meaning | Text char_error[-cod] (English) |
|---|---|---|---|
| (no error) | 0 |
All right | "all right" |
-EXP |
-1 |
Overflow in exp |
"overflow in function exp" |
-LOG |
-2 |
Argument log <= 0 |
"argument LOG <= 0 (bad)" |
-SIN |
-3 |
\|x\| > 65536 in sin |
"overflow in function sin (argument > 65536)" |
-COS |
-4 |
\|x\| > 65536 in cos |
"overflow in function cos (argument > 65536)" |
-TAN |
-5 |
\|x\| > 65536 in tan |
"overflow in function tan (argument > 65536 or = pi/2" |
| (code 6) | -6 |
(stub) | "overflow" |
-SQRT |
-7 |
Argument sqrt < 0 |
"argument SQRT < 0 (bad)" |
-SINH |
-8 |
Overflow in sinh |
"overflow in function sinh" |
-COSH |
-9 |
Overflow in cosh |
"overflow in function cosh" |
-TANH |
-10 |
(reserved) | "overflow in function tanh" |
-ASIN |
-11 |
Argument asin > 1 |
"argument ASIN > 1 (bad)" |
-ACOS |
-12 |
Argument acos > 1 |
"argument ACOS > 1 (bad)" |
| (code 13) | -13 |
(reserved) | "overflow" |
-LOG10 |
-14 |
Argument log10 <= 0 |
"argument LOG10 <=0 (bad)" |
ERROR_DIV_0 |
-15 |
Division by zero | "overflow x/y" |
ERROR_POW |
-16 |
x^y when x < 0 (base ≤ 0) |
"for x^y x<0" |
ERROR_BRACKET |
-17 |
Unbalanced parentheses | "abnormal bracket" |
ERROR_FUNCTION |
-18 |
Unrecognized function/construct | "abnormal function" |
ERROR_EXPRESSION |
-19 |
An incorrect expression | "abnormal expression" |
ERROR_OVERFLOW |
-20 |
float overflow |
"float overflow" |
ERROR_RETURN |
-21 |
The return operator fired |
"bad parameter in =" |
ERROR_VAR |
-22 |
The left operand of = is not a variable |
"bad return" |
Note the shift: the texts in
char_error[]for indices 21 and 22 are shifted relative to the meaning of the codes (ERROR_RETURN = -21corresponds to the text"bad parameter in =", andERROR_VAR = -22to the text"bad return"). This is a peculiarity of the source array inExpremsg.cpp(the array contains 23 elements, indices 0…22). The messages are in English.
6.2. Mapping to project codes (2401…2421) via get_expr_err
The get_expr_err function (Get_err.cpp) converts an internal code into a common
project code:
int nTmp = -expr_get_error_cod(); // 0..22
if (nTmp == 0) return 0; // no errors
if (nTmp > 20) nTmp = 21; // all codes > 20 collapse into 21
nTmp += 2400; // 2401..2421
return -nTmp; // returned with a minus sign
Internal code (error_cod) |
nTmp |
Project code | Return of get_expr_err |
|---|---|---|---|
0 |
0 | — | 0 |
-1…-20 |
1…20 | 2401…2420 | -2401…-2420 |
-21, -22 (ERROR_RETURN, ERROR_VAR) |
→ 21 | 2421 | -2421 |
The project codes ERROR_EXPR_* (2401…2420) are defined in Error1.h.
7. Dependencies
Shared headers (src/Include/):
| Header | Where used | Purpose |
|---|---|---|
typedef.h |
both modules | The definition of the _real type (float/double) and others |
expr.h (EXPR.H) |
the Expr module, INTER.H |
The main API, function/error codes |
inter.h (INTER.H) |
the Inter module | The INTE_OPER structure, the inte_* prototypes |
tmc_lib.h |
Expr_in1.cpp, Inte_*.cpp |
Purpose not investigated |
error1.h (Error1.h) |
only Get_err.cpp |
Project error codes (ERROR_EXPR_*) |
Standard C/C++ headers: math.h, float.h, stdio.h, stdlib.h, string.h,
conio.h.
Relation to other TMC Suite libraries:
- EXPRINT does not use the complex library directly — only the scalar
_realtype is involved. - No direct
#includes from SFILE95, TMCLibError, PREPR, TMCIndan were found in the EXPRINT sources.