2019-02-20 10:57:35 +00:00
// This should be the new way to implement mecanisms
// In a specific file
// TODO import them automatically
// TODO convert the legacy functions to new files
2019-12-05 23:15:15 +00:00
import { formatValue } from 'Engine/format'
2019-07-22 10:36:50 +00:00
import barème from 'Engine/mecanisms/barème'
import barèmeContinu from 'Engine/mecanisms/barème-continu'
import barèmeLinéaire from 'Engine/mecanisms/barème-linéaire'
2019-12-16 17:47:15 +00:00
import durée from 'Engine/mecanisms/durée'
2019-12-05 23:15:15 +00:00
import encadrement from 'Engine/mecanisms/encadrement'
2019-07-23 12:33:35 +00:00
import operation from 'Engine/mecanisms/operation'
2019-09-10 16:24:05 +00:00
import variations from 'Engine/mecanisms/variations'
import { Grammar , Parser } from 'nearley'
2019-04-03 15:40:51 +00:00
import {
add ,
2019-09-10 16:24:05 +00:00
cond ,
2019-04-03 15:40:51 +00:00
divide ,
equals ,
2019-09-10 16:24:05 +00:00
fromPairs ,
2019-04-03 15:40:51 +00:00
gt ,
gte ,
2019-09-10 16:24:05 +00:00
is ,
2019-04-03 15:40:51 +00:00
keys ,
lt ,
lte ,
multiply ,
propOr ,
2019-06-11 10:03:45 +00:00
subtract ,
2019-09-10 16:24:05 +00:00
T ,
without
2019-04-03 15:40:51 +00:00
} from 'ramda'
import React from 'react'
2019-11-28 11:03:23 +00:00
import { syntaxError } from './error.ts'
2019-09-10 16:24:05 +00:00
import grammar from './grammar.ne'
2019-04-03 15:40:51 +00:00
import {
mecanismAllOf ,
mecanismComplement ,
mecanismError ,
mecanismInversion ,
mecanismMax ,
mecanismMin ,
mecanismOneOf ,
2019-09-10 16:24:05 +00:00
mecanismOnePossibility ,
2019-04-03 15:40:51 +00:00
mecanismProduct ,
mecanismReduction ,
mecanismSum ,
2019-09-10 16:24:05 +00:00
mecanismSynchronisation
2019-04-03 15:40:51 +00:00
} from './mecanisms'
2019-07-11 16:25:08 +00:00
import { parseReferenceTransforms } from './parseReference'
2019-06-13 16:01:49 +00:00
2019-06-13 16:17:22 +00:00
export let parse = ( rules , rule , parsedRules ) => rawNode => {
2019-06-13 16:01:49 +00:00
let onNodeType = cond ( [
2019-06-13 16:17:22 +00:00
[ is ( String ) , parseString ( rules , rule , parsedRules ) ] ,
2019-06-13 16:01:49 +00:00
[ is ( Number ) , parseNumber ] ,
2019-06-13 16:17:22 +00:00
[ is ( Object ) , parseObject ( rules , rule , parsedRules ) ] ,
2019-06-13 16:01:49 +00:00
[ T , parseOther ]
] )
let defaultEvaluate = ( cache , situationGate , parsedRules , node ) => node
let parsedNode = onNodeType ( rawNode )
return parsedNode . evaluate
? parsedNode
: { ... parsedNode , evaluate : defaultEvaluate }
}
2019-02-20 10:57:35 +00:00
2019-09-10 16:24:05 +00:00
const compiledGrammar = Grammar . fromCompiled ( grammar )
2018-06-29 09:13:05 +00:00
2019-06-13 16:17:22 +00:00
export let parseString = ( rules , rule , parsedRules ) => rawNode => {
2019-05-14 17:40:47 +00:00
/ * S t r i n g s c o r r e s p o n d t o i n f i x e x p r e s s i o n s .
* Indeed , a subset of expressions like simple arithmetic operations ` 3 + (quantity * 2) ` or like ` salary [month] ` are more explicit that their prefixed counterparts .
* This function makes them prefixed operations . * /
2019-11-26 18:14:57 +00:00
try {
let [ parseResult ] = new Parser ( compiledGrammar ) . feed ( rawNode ) . results
return parseObject ( rules , rule , parsedRules ) ( parseResult )
} catch ( e ) {
2019-11-28 11:03:23 +00:00
syntaxError (
rule . dottedName ,
` \` ${ rawNode } \` n'est pas une formule valide ` ,
e
)
2019-11-26 18:14:57 +00:00
}
2018-06-29 09:13:05 +00:00
}
2019-06-13 16:01:49 +00:00
export let parseNumber = rawNode => ( {
2018-07-27 16:50:11 +00:00
text : '' + rawNode ,
category : 'number' ,
nodeValue : rawNode ,
type : 'numeric' ,
jsx : < span className = "number" > { rawNode } < / s p a n >
} )
2019-06-13 16:01:49 +00:00
export let parseOther = rawNode => {
2018-06-29 09:13:05 +00:00
throw new Error (
'Cette donnée : ' + rawNode + ' doit être un Number, String ou Object'
)
}
2019-05-02 14:24:22 +00:00
2019-06-13 16:17:22 +00:00
export let parseObject = ( rules , rule , parsedRules ) => rawNode => {
2019-05-15 08:52:20 +00:00
/ * T O D O i n s t e a d o f d e s c r i b i n g m e c a n i s m s i n k n o w n M e c a n i s m s . y a m l , e x t e r n a l i z e t h e m e c a n i s m s t h e m s e l v e s i n a n i n d i v i d u a l f i l e a n d d e s c r i b e i t
2018-06-29 09:13:05 +00:00
let mecanisms = intersection ( keys ( rawNode ) , keys ( knownMecanisms ) )
if ( mecanisms . length != 1 ) {
2019-09-10 16:24:05 +00:00
}
2019-05-15 08:52:20 +00:00
* /
let attributes = keys ( rawNode ) ,
descriptiveAttributes = [ 'description' , 'note' , 'référence' ] ,
relevantAttributes = without ( descriptiveAttributes , attributes )
if ( relevantAttributes . length !== 1 )
throw new Error ( ` OUPS : On ne devrait reconnaître que un et un seul mécanisme dans cet objet (au-delà des attributs descriptifs tels que "description", "commentaire", etc.)
2018-07-09 12:13:38 +00:00
Objet YAML : $ { JSON . stringify ( rawNode ) }
Cette liste doit avoir un et un seul élément .
2019-06-13 16:01:49 +00:00
Si vous venez tout juste d 'ajouter un nouveau mécanisme, vérifier qu' il est bien intégré dans le dispatch de parse . js
2018-07-09 12:13:38 +00:00
` )
2019-05-15 08:52:20 +00:00
let k = relevantAttributes [ 0 ] ,
2018-06-29 09:13:05 +00:00
v = rawNode [ k ]
2019-05-15 08:52:20 +00:00
let knownOperations = {
2019-09-25 13:00:03 +00:00
'*' : [ multiply , '× ' ] ,
2019-05-15 08:52:20 +00:00
'/' : [ divide , '∕ ' ] ,
'+' : [ add ] ,
'-' : [ subtract , '− ' ] ,
'<' : [ lt ] ,
'<=' : [ lte , '≤' ] ,
'>' : [ gt ] ,
'>=' : [ gte , '≥' ] ,
'=' : [ equals ] ,
'!=' : [ ( a , b ) => ! equals ( a , b ) , '≠' ]
} ,
2019-06-11 10:03:45 +00:00
operationDispatch = fromPairs (
Object . entries ( knownOperations ) . map ( ( [ k , [ f , symbol ] ] ) => [
k ,
2019-07-23 12:33:35 +00:00
operation ( k , f , symbol )
2019-06-11 10:03:45 +00:00
] )
2019-05-15 08:52:20 +00:00
)
2018-06-29 09:13:05 +00:00
let dispatch = {
'une de ces conditions' : mecanismOneOf ,
'toutes ces conditions' : mecanismAllOf ,
somme : mecanismSum ,
multiplication : mecanismProduct ,
2019-02-20 10:57:35 +00:00
barème ,
2019-07-11 16:25:08 +00:00
'barème linéaire' : barèmeLinéaire ,
'barème continu' : barèmeContinu ,
2019-11-28 11:03:23 +00:00
encadrement ,
2019-12-16 17:47:15 +00:00
durée ,
2018-06-29 09:13:05 +00:00
'le maximum de' : mecanismMax ,
'le minimum de' : mecanismMin ,
complément : mecanismComplement ,
2019-05-15 14:31:33 +00:00
'une possibilité' : mecanismOnePossibility ( rule . dottedName ) ,
2019-01-30 17:53:57 +00:00
'inversion numérique' : mecanismInversion ( rule . dottedName ) ,
2018-08-07 16:20:08 +00:00
allègement : mecanismReduction ,
2019-07-22 10:36:50 +00:00
variations ,
2019-05-15 08:52:20 +00:00
synchronisation : mecanismSynchronisation ,
... operationDispatch ,
filter : ( ) =>
2019-12-05 23:15:15 +00:00
parseReferenceTransforms (
rules ,
rule ,
parsedRules
) ( {
2019-05-15 14:31:33 +00:00
filter : v . filter ,
2019-05-15 08:52:20 +00:00
variable : v . explanation
} ) ,
2019-06-13 16:17:22 +00:00
variable : ( ) =>
parseReferenceTransforms ( rules , rule , parsedRules ) ( { variable : v } ) ,
2019-11-28 11:03:23 +00:00
unitConversion : ( ) =>
2019-12-05 23:15:15 +00:00
parseReferenceTransforms (
rules ,
rule ,
parsedRules
) ( {
2019-05-15 08:52:20 +00:00
variable : v . explanation ,
2019-11-28 11:03:23 +00:00
unit : v . unit
2019-05-15 08:52:20 +00:00
} ) ,
constant : ( ) => ( {
type : v . type ,
nodeValue : v . nodeValue ,
2019-07-11 15:07:34 +00:00
unit : v . unit ,
2019-05-15 08:52:20 +00:00
// eslint-disable-next-line
2019-09-23 18:04:34 +00:00
jsx : ( ) => (
< span className = { v . type } >
2019-10-10 09:46:04 +00:00
{ formatValue ( {
unit : v . unit ,
value : v . nodeValue ,
2019-11-28 11:03:23 +00:00
// TODO : handle localization here
language : 'fr' ,
2019-10-10 09:46:04 +00:00
// We want to display constants with full precision,
// espacilly for percentages like APEC 0,036 %
maximumFractionDigits : 5
} ) }
2019-09-23 18:04:34 +00:00
< / s p a n >
)
2019-05-15 08:52:20 +00:00
} )
2018-06-29 09:13:05 +00:00
} ,
action = propOr ( mecanismError , k , dispatch )
2019-06-13 16:17:22 +00:00
return action ( parse ( rules , rule , parsedRules ) , k , v )
2018-06-29 09:13:05 +00:00
}