ConceptPortal-public/rsconcept/frontend/src/hooks/useCheckExpression.ts

101 lines
3.0 KiB
TypeScript
Raw Normal View History

'use client';
import { useCallback, useState } from 'react';
2023-07-25 20:27:29 +03:00
import { type ErrorData } from '@/components/InfoError';
import { CstType, IConstituenta, type IRSForm } from '@/models/rsform';
2024-01-04 14:35:46 +03:00
import { getDefinitionPrefix } from '@/models/rsformAPI';
2023-12-28 14:04:44 +03:00
import { IArgumentInfo, IExpressionParse } from '@/models/rslang';
import { RSErrorType } from '@/models/rslang';
import { DataCallback, postCheckExpression } from '@/utils/backendAPI';
2023-12-27 19:34:39 +03:00
const LOGIC_TYPIFICATION = 'LOGIC';
2023-08-26 21:37:57 +03:00
function useCheckExpression({ schema }: { schema?: IRSForm }) {
const [loading, setLoading] = useState(false);
const [error, setError] = useState<ErrorData>(undefined);
const [parseData, setParseData] = useState<IExpressionParse | undefined>(undefined);
const resetParse = useCallback(() => setParseData(undefined), []);
2023-12-28 14:04:44 +03:00
function checkExpression(expression: string, activeCst?: IConstituenta, onSuccess?: DataCallback<IExpressionParse>) {
setError(undefined);
postCheckExpression(String(schema!.id), {
data: { expression: expression },
showError: true,
setLoading,
2024-01-04 22:10:57 +03:00
onError: setError,
onSuccess: parse => {
if (activeCst) {
2024-01-04 14:35:46 +03:00
adjustResults(parse, expression.trim() === getDefinitionPrefix(activeCst), activeCst.cst_type);
}
setParseData(parse);
if (onSuccess) onSuccess(parse);
}
});
}
return { parseData, checkExpression, resetParse, error, setError, loading };
}
export default useCheckExpression;
// ===== Internals ========
2023-11-06 02:20:16 +03:00
function checkTypeConsistency(type: CstType, typification: string, args: IArgumentInfo[]): boolean {
switch (type) {
2023-12-28 14:04:44 +03:00
case CstType.BASE:
case CstType.CONSTANT:
case CstType.STRUCTURED:
case CstType.TERM:
return typification !== LOGIC_TYPIFICATION && args.length === 0;
2023-12-28 14:04:44 +03:00
case CstType.AXIOM:
case CstType.THEOREM:
return typification === LOGIC_TYPIFICATION && args.length === 0;
2023-12-28 14:04:44 +03:00
case CstType.FUNCTION:
return typification !== LOGIC_TYPIFICATION && args.length !== 0;
2023-12-28 14:04:44 +03:00
case CstType.PREDICATE:
return typification === LOGIC_TYPIFICATION && args.length !== 0;
}
}
2023-07-20 17:11:03 +03:00
2023-08-27 15:39:49 +03:00
function adjustResults(parse: IExpressionParse, emptyExpression: boolean, cstType: CstType) {
2023-10-23 18:22:55 +03:00
if (!parse.parseResult && parse.errors.length > 0) {
2023-08-27 15:39:49 +03:00
return;
}
if (cstType === CstType.BASE || cstType === CstType.CONSTANT) {
if (!emptyExpression) {
parse.parseResult = false;
parse.errors.push({
errorType: RSErrorType.globalNonemptyBase,
isCritical: true,
params: [],
position: 0
});
2023-12-27 19:34:39 +03:00
return;
2023-08-27 15:39:49 +03:00
}
} else {
if (emptyExpression) {
parse.parseResult = false;
parse.errors.push({
errorType: RSErrorType.globalEmptyDerived,
isCritical: true,
params: [],
position: 0
});
2023-12-27 19:34:39 +03:00
return;
}
2023-08-27 15:39:49 +03:00
}
if (!checkTypeConsistency(cstType, parse.typification, parse.args)) {
parse.parseResult = false;
parse.errors.push({
errorType: RSErrorType.globalUnexpectedType,
isCritical: true,
params: [],
position: 0
});
}
2023-12-28 14:04:44 +03:00
}