Библиотека 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;
  • переменные — одна латинская буква AZ / az (массив из 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-код символа) или числовым кодом функции (ABSLOG10, см. раздел 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_MAXERROR_OVERFLOW, возврат FLT_MAX;
  • '/' — деление: при op2 == 0ERROR_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_MAXERROR_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 и символ из AZ либо az);
  • -1 — не имя переменной.

char* expr_get_error(void)

Файл: Expremsg.cpp.

Возвращает текстовое (на английском) описание текущей ошибки.

  • Параметры: нет.
  • Возврат: указатель на строку из статического массива char_error[]. Индекс вычисляется как -expr_get_error_cod(). Массив содержит 23 элемента (индексы 022), см. раздел 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. Переменные

  • Имя переменной — ровно один латинский символ: AZ или az.
  • Значения хранятся в массиве из 256 ячеек rExpr_per[256], индексируемом кодом первого символа имени. Строчные и прописные буквы — разные переменные (разные коды).
  • Чтение — expr_get_per, запись — оператор = или expr_set_per, проверка имени — expr_is_per.

5.3. Операторы (строка arif[] = "=+-*/^")

Бинарные операторы ищутся в строке выражения справа налево, в порядке элементов строки arif. Поиск ведётся только на верхнем уровне вложенности (с учётом () и {}).

Оператор Назначение Проверки и ошибки
= Присваивание var = expr Левый операнд обязан быть именем переменной, иначе ERROR_VAR
+ Сложение При результате > FLT_MAXERROR_OVERFLOW
- Вычитание При результате > FLT_MAXERROR_OVERFLOW
* Умножение При результате > FLT_MAXERROR_OVERFLOW
/ Деление При делителе 0ERROR_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 < 0stmt пропускается (ветви 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 from src/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 AZ / az (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: the return/if/while operators, 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, fortran macros. These are legacy memory-model and calling-convention attributes from 16-bit code (Microsoft C / early Visual C++). In the header INTER.H a 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). See EXPR.H / INTER.H for the full prototypes.

About the _real type. The _real type is defined in the external header typedef.h and, depending on the build, corresponds to float or double. 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. The exprint.vcxproj project 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 (contain main, 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 particular EXPR_RADIAN (1) → radians (expr_angle = 1.0).
  • Return: none.
  • Effect: the expr_angle factor is applied inside expr_comp: for sin/cos/tan the argument is multiplied by expr_angle; for asin/acos/atan the result is divided by expr_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 (ABSLOG10, see section 3.2).
  • oper1 (char*) — the string of the first operand (for functions — its argument);
  • n1 (int) — the length of oper1; if 0, then op1 = 0;
  • oper2 (char*) — the string of the second operand (used only for binary operators, for which cod > LOG10);
  • n2 (int) — the length of oper2; if 0 for a binary operator, ERROR_EXPRESSION is 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: oper1 must be a variable name (expr_is_per), otherwise ERROR_VAR and a return of 0; otherwise the value op2 is written into the variable and returned;
  • '^' — power: requires op1 > 0, otherwise ERROR_POW; when op2 > |log(FLT_MAX)/log(op1)|ERROR_OVERFLOW, return FLT_MAX;
  • '+', '-', '*' — arithmetic; when the result is > FLT_MAXERROR_OVERFLOW, return FLT_MAX;
  • '/' — division: when op2 == 0ERROR_DIV_0, return FLT_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 -cod is set, return 0.

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 the return/if/while operators — for those inte_atof is used).
  • Return: the value of the expression (_real). On error, see expr_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 character lex[n], substituting '\0', then restores it — the buffer must allow writing at index n);
  • 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 via atof (when > FLT_MAXERROR_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 string arif[] = "=+-*/^" (taking into account the nesting of () and {}); when found — a call of expr_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 of expr_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 form e+/e-. The literal length is limited: when n > 40, 1 is 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 character lpszName[0] is used as the index in the array rExpr_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 in rExpr_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 from AZ or az);
  • -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 (indices 022), see section 6.
  • Caution: the function does not check the range. A correct result is obtained only for the error codes 0 and -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; the put_error_messege call is commented out in the current build).
  • Return:
  • 0 — if there are no errors (nTmp == 0);
  • -nTmp, where nTmp = -error_cod, when nTmp > 20 it is capped at 21, 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 — see inte_inter/expr_inter).
  • Return: the value (_real).
  • Logic: resets the error code to 0, evaluates via inte_inter. If on completion ERROR_RETURN is set — the saved value inte_get_inter_value() is returned, and the error code is reset to 0 (that is, return is 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 ; — return 0; 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 via expr_inter; on success — return the result; if the error is not ERROR_FUNCTION — return 0; 6. otherwise an attempt to recognize an operator via inte_oper; with code 0 or ERROR_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 the expr_del_Blanks1 function);
  • r (double*) — output: the computed value.
  • Return: the error code (int) — the result of expr_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) — evaluates expr via inte_inter; in the absence of an error it sets ERROR_RETURN, saves the value via inte_set_inter_value and returns it;
  • if(cond) stmt — finds the end of the condition (inte_select_blanck), evaluates cond; if cond < 0 the operator stmt is skipped (there is no else branch), cond is returned; otherwise stmt is evaluated and returned;
  • while(cond) stmt — while cond >= 0: evaluates stmt, then re-evaluates cond; ends when cond < 0; on an error at any step — return 0;
  • if no operator is recognized — ERROR_FUNCTION, return 0.

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 ) (or n if 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); 0 by 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_numbern function. 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: AZ or az.
  • 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 or expr_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_MAXERROR_OVERFLOW
- Subtraction When the result is > FLT_MAXERROR_OVERFLOW
* Multiplication When the result is > FLT_MAXERROR_OVERFLOW
/ Division On a divisor of 0ERROR_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, otherwise ERROR_BRACKET.
  • { }block braces at the interpreter level (the body of if/while operators, 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 < 0stmt 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 = -21 corresponds to the text "bad parameter in =", and ERROR_VAR = -22 to the text "bad return"). This is a peculiarity of the source array in Expremsg.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 _real type is involved.
  • No direct #includes from SFILE95, TMCLibError, PREPR, TMCIndan were found in the EXPRINT sources.