Merge branch 'master' into wozniak_polish

This commit is contained in:
Denis Merigoux 2021-05-15 16:19:41 +02:00
commit d50710d533
No known key found for this signature in database
GPG Key ID: EE99DCFA365C3EE3
106 changed files with 3419 additions and 3704 deletions

Binary file not shown.

View File

@ -48,21 +48,6 @@ Heading&
\end{minted}
\vspace*{-1.75em}
\\
Article&
\vspace*{-1.75em}
\begin{minted}{catala_en}
## [Foo]
### [Bar]
\end{minted}
\vspace*{-1.75em}
&
\vspace*{-1.75em}
\begin{minted}{catala_fr}
## [Foo]
### [Bar]
\end{minted}
\vspace*{-1.75em}
\\
Code block&
\vspace*{-1.75em}
\begin{minted}{catala_en}
@ -106,19 +91,6 @@ File inclusion&
\end{minted}
\vspace*{-1.75em}
\\
Master file\newline (only inclusions)&
\vspace*{-1.75em}
\begin{minted}{catala_en}
> Master file
\end{minted}
\vspace*{-1.75em}
&
\vspace*{-1.75em}
\begin{minted}{catala_fr}
> Fichier maître
\end{minted}
\vspace*{-1.75em}
\\
\bottomrule
\end{tabular}
\end{center}

View File

@ -4,7 +4,7 @@
LATEXMK?=latexmk
CATALA=dune exec --no-print-director ../../src/catala/catala.exe -- \
CATALA=../../_build/default/src/catala/catala.exe \
$(CATALA_OPTS) --language=$(CATALA_LANG)
help : ../Makefile.common.mk

View File

@ -1,5 +1,3 @@
# Fichier maître
> Inclusion: prologue.catala_fr
> Inclusion: securite_sociale_L.catala_fr

View File

@ -1,8 +1,6 @@
## Montant de la base mensuelle des allocations familiales
### [INSTRUCTION INTERMINISTERIELLE N° DSS/SD2B/2019/65 du 25 mars 2019 relative
à la revalorisation au 1er avril 2019 des prestations familiales servies en
métropole]
### Instruction ministérielle N°DSS/SD2B/2019/65 du 25 mars 2019 relative à la revalorisation au 1er avril 2019 des prestations familiales servies en métropole
Conformément à larticle L. 551-1 du code de la sécurité sociale, le montant
des prestations familiales est déterminé d'après des bases mensuelles
@ -26,11 +24,7 @@ champ d'application PrestationsFamiliales :
conséquence égal à 413,16 €
```
### [Instruction interministérielle no DSS/SD2B/2020/33 du 18 février 2020
relative à la revalorisation au 1er avril 2020 des prestations
familiales servies en métropole, en Guadeloupe, en Guyane, en
Martinique, à La Réunion, à Saint-Barthélemy, à Saint-Martin et dans
le département de Mayotte]
### Instruction interministérielle no DSS/SD2B/2020/33 du 18 février 2020 relative à la revalorisation au 1er avril 2020 des prestations familiales servies en métropole, en Guadeloupe, en Guyane, en Martinique, à La Réunion, à Saint-Barthélemy, à Saint-Martin et dans le département de Mayotte
Au titre de lannée 2020, larticle 81 de la loi du 24 décembre 2019 de
financement de la sécurité sociale a prévu, par dérogation aux dispositions
@ -50,11 +44,7 @@ champ d'application PrestationsFamiliales :
conséquence égal à 414,4 €
```
### [Instruction interministérielle n°DSS/2B/2021/65 du 19 mars 2021
relative à la revalorisation au 1er avril 2021 des prestations
familiales servies en métropole, en Guadeloupe, en Guyane,
en Martinique, à la Réunion, à Saint-Barthélemy, à Saint-Martin
et dans le département de Mayotte]
### Instruction interministérielle n°DSS/2B/2021/65 du 19 mars 2021 relative à la revalorisation au 1er avril 2021 des prestations familiales servies en métropole, en Guadeloupe, en Guyane, en Martinique, à la Réunion, à Saint-Barthélemy, à Saint-Martin et dans le département de Mayotte
Au 1er avril 2021, le coefficient de revalorisation de la BMAF est ainsi fixé à
1,001 soit un taux de revalorisation de la BMAF de 0,1 %. Le montant de cette
@ -72,11 +62,7 @@ champ d'application PrestationsFamiliales :
## Montant des plafonds de ressources
### [CIRCULAIRE INTERMINISTERIELLE N° DSS/SD2B/2017/352 du 22 décembre 2017
relative à la revalorisation au 1er janvier 2018 des plafonds de ressources
dattribution de certaines prestations familiales servies en métropole, en
Guadeloupe, en Guyane, en Martinique, à la Réunion, à Saint-Barthélemy,
à Saint-Martin et à Mayotte]
### Circulaire interministérielle N° DSS/SD2B/2017/352 du 22 décembre 2017 relative à la revalorisation au 1er janvier 2018 des plafonds de ressources dattribution de certaines prestations familiales servies en métropole, en Guadeloupe, en Guyane, en Martinique, à la Réunion, à Saint-Barthélemy, à Saint-Martin et à Mayotte
Plafonds de ressources applicables pour lattribution du montant modulé
des allocations familiales, de la majoration pour âge et de lallocation
@ -109,11 +95,7 @@ champ d'application AllocationsFamiliales :
(nombre de enfants_à_charge_droit_ouvert_prestation_familiale))
```
### [Instruction interministérielle n° DSS/SD2B/2018/279 du 17 décembre 2018
relative à la revalorisation au 1er janvier 2019 des plafonds de ressources
dattribution de certaines prestations familiales servies en métropole, en
Guadeloupe, en Guyane, en Martinique, à la Réunion, à Saint-Barthélemy,
à Saint-Martin et à Mayotte]
### Instruction interministérielle n° DSS/SD2B/2018/279 du 17 décembre 2018 relative à la revalorisation au 1er janvier 2019 des plafonds de ressources dattribution de certaines prestations familiales servies en métropole, en Guadeloupe, en Guyane, en Martinique, à la Réunion, à Saint-Barthélemy, à Saint-Martin et à Mayotte
Plafonds de ressources applicables pour lattribution du montant
modulé des allocations familiales, de la majoration pour âge et
@ -146,11 +128,7 @@ champ d'application AllocationsFamiliales :
(nombre de enfants_à_charge_droit_ouvert_prestation_familiale))
```
### [Instruction interministerielle no DSS/SD2B/2019/261 du 18 décembre 2019
relative à la revalorisation au 1er janvier 2020 des plafonds de ressources
dattribution de certaines prestations familiales servies en métropole,
en Guadeloupe, en Guyane, en Martinique, à La Réunion, à Saint-Barthélemy,
à Saint-Martin et à Mayotte]
### Instruction interministerielle no DSS/SD2B/2019/261 du 18 décembre 2019 relative à la revalorisation au 1er janvier 2020 des plafonds de ressources dattribution de certaines prestations familiales servies en métropole, en Guadeloupe, en Guyane, en Martinique, à La Réunion, à Saint-Barthélemy, à Saint-Martin et à Mayotte
Plafonds de ressources applicables pour lattribution du montant modulé des
allocations familiales, de la majoration pour âge et de lallocation forfaitaire,
@ -185,7 +163,7 @@ champ d'application AllocationsFamiliales :
### Arrêté du 14 décembre 2020 relatif au montant des plafonds de ressources de certaines prestations familiales et aux tranches du barème applicable au recouvrement des indus et à la saisie des prestations
#### [Article 1|JORFARTI000042694985]
#### Article 1|JORFARTI000042694985
I. - Le plafond de ressources prévu au 1° du I des articles D. 521-1 et D. 521-2
du code de la sécurité sociale relatif aux allocations familiales, à la majoration
@ -223,7 +201,7 @@ champ d'application AllocationsFamiliales :
### Décret n° 2018-1173 du 19 décembre 2018 portant relèvement du salaire minimum de croissance
#### [Article 1|JORFARTI000037833214]
#### Article 1|JORFARTI000037833214
A compter du 1er janvier 2019, pour les catégories de travailleurs mentionnés à
l'article L. 2211-1 du code du travail, le montant du salaire minimum de
@ -262,7 +240,7 @@ champ d'application Smic :
### Décret n° 2019-1387 du 18 décembre 2019 portant relèvement du salaire minimum de croissance
#### [Article 1|LEGIARTI000039640195]
#### Article 1|LEGIARTI000039640195
A compter du 1er janvier 2020, pour les catégories de travailleurs mentionnés à
l' article L. 2211-1 du code du travail , le montant du salaire minimum de
@ -301,7 +279,7 @@ champ d'application Smic :
### Décret n° 2020-1598 du 16 décembre 2020 portant relèvement du salaire minimum de croissance
#### [Article 1|JORFARTI000042677367]
#### Article 1|JORFARTI000042677367
A compter du 1er janvier 2021, pour les catégories de travailleurs mentionnés à
l'article L. 2211-1 du code du travail, le montant du salaire minimum de

View File

@ -103,7 +103,7 @@ champ d'application InterfaceAllocationsFamiliales:
#### Code de l'éducation
#### [Article L131-1|LEGIARTI000038901859]
#### Article L131-1|LEGIARTI000038901859
L'instruction est obligatoire pour chaque enfant dès l'âge de trois ans et
jusqu'à l'âge de seize ans.

View File

@ -6,7 +6,7 @@
###### Chapitre 1er : Allocations familiales
#### [Article D521-1|LEGIARTI000030680318]
####### Article D521-1|LEGIARTI000030680318
I.-Pour l'application de l'article L. 521-1 , le montant des allocations
familiales et de la majoration pour âge prévue à l'article L. 521-3
@ -185,7 +185,7 @@ champ d'application AllocationsFamiliales :
montant_versé_base +€ montant_versé_majoration
```
#### [Article D521-2|LEGIARTI000030680324]
####### Article D521-2|LEGIARTI000030680324
```catala
# L'allocation forfaitaire totale est la somme de toutes les allocations
@ -288,7 +288,7 @@ champ d'application AllocationsFamiliales :
définition nombre_enfants_l521_1 égal à 3
```
#### [Article D521-3|LEGIARTI000030678079]
####### Article D521-3|LEGIARTI000030678079
I.-Le plafond prévu au 1° du I des articles D. 521-1 et D. 521-2 est fixé à
55 950 euros. Il est majoré de 5 595 euros par enfant à charge.
@ -327,7 +327,7 @@ sociale, du budget et de l'agriculture.
###### Chapitre 5 : Prestations familiales et prestations assimilées
#### [Article D755-5|LEGIARTI000006738575]
####### Article D755-5|LEGIARTI000006738575
I. - Les taux servant au calcul des allocations familiales et de la majoration
prévue à l'article L. 755-11 sont identiques à ceux mentionnés à l'article

View File

@ -8,7 +8,7 @@
###### Chapitre 1er : Liste des prestations
#### [Article L511-1|LEGIARTI000038834530]
####### Article L511-1|LEGIARTI000038834530
Les prestations familiales comprennent :
@ -36,7 +36,7 @@ Les prestations familiales comprennent :
###### Chapitre 2 : Champ d'application
#### [Article L512-3|LEGIARTI000038834523]
####### Article L512-3|LEGIARTI000038834523
Sous réserve des règles particulières à chaque prestation,
ouvre droit aux prestations familiales :
@ -91,7 +91,7 @@ peut être différent de celui mentionné au 2° du présent article.
###### Chapitre 1er : Allocations familiales
#### [Article L521-1|LEGIARTI000029963006]
####### Article L521-1|LEGIARTI000029963006
Les allocations familiales sont dues à partir du deuxième enfant à charge.
@ -173,7 +173,7 @@ champ d'application AllocationsFamiliales :
assertion fixé montant_versé_complément par décret
```
#### [Article L521-2|LEGIARTI000006743210]
####### Article L521-2|LEGIARTI000006743210
Les allocations sont versées à la personne qui assume, dans quelques conditions
que ce soit, la charge effective et permanente de l'enfant.
@ -287,7 +287,7 @@ d) enfants confiés à un service public, à une institution privée, à un part
# est confié à un service social.
```
#### [Article L521-3|LEGIARTI000006743289]
####### Article L521-3|LEGIARTI000006743289
Chacun des enfants à charge, à l'exception du plus âgé, ouvre droit à partir
d'un âge minimum à une majoration des allocations familiales.
@ -320,7 +320,7 @@ champ d'application AllocationsFamiliales :
###### Chapitre 1er : Etablissement du salaire de base
#### [Article L551-1|LEGIARTI000031688371]
####### Article L551-1|LEGIARTI000031688371
Le montant des prestations familiales est déterminé d'après des bases
mensuelles de calcul revalorisées au 1er avril de chaque année par application
@ -338,7 +338,7 @@ champ d'application PrestationsFamiliales :
###### Chapitre 1er : Généralités
#### [Article L751-1|LEGIARTI000031323778]
####### Article L751-1|LEGIARTI000031323778
Les dispositions du présent titre s'appliquent en Guadeloupe, en Guyane,
en Martinique, à La Réunion, à Saint-Barthélemy et à Saint-Martin à
@ -362,7 +362,7 @@ champ d'application PrestationsFamiliales :
###### Chapitre 5 : Prestations familiales et prestations assimilées
#### [Article L755-3|LEGIARTI000033728786]
####### Article L755-3|LEGIARTI000033728786
Les dispositions des articles L. 512-1 à L. 512-4 , L. 513-1 , L. 521-2 ,
L. 552-1 , L. 553-1 , L. 553-2 , L. 553-4 , L. 582-1 , L. 582-2 , L. 583-3
@ -375,7 +375,7 @@ fixée en application de l'article L. 551-1 .
# Aucun changement dans le code, puisque les articles restent applicables
```
#### [Article L755-11|LEGIARTI000031323803]
####### Article L755-11|LEGIARTI000031323803
Les conditions d'attribution des allocations familiales et de leurs majorations
fixées par les articles L. 521-1 et L. 521-3 sont applicables dans les
@ -388,7 +388,7 @@ collectivités mentionnées à l'article L. 751-1.
Toutefois, les dispositions de l'article L. 755-12 restent en vigueur aussi
longtemps que le présent chapitre V est applicable.
#### [Article L755-12|LEGIARTI000029962999]
####### Article L755-12|LEGIARTI000029962999
Les allocations familiales sont dues, pour tout enfant, à la personne qui a
effectivement la charge de celui-ci.

View File

@ -6,7 +6,7 @@
###### Chapitre 2 : Champ d'application.
#### [Article R512-2|LEGIARTI000006750602]
####### Article R512-2|LEGIARTI000006750602
Les enfants ouvrent droit aux prestations familiales jusqu'à l'âge de vingt
ans sous réserve que leur rémunération n'excède pas le plafond fixé au deuxième
@ -46,7 +46,7 @@ législation sur les assurances sociales.
###### Chapitre 1er : Allocations familiales
#### [Article R521-1|LEGIARTI000018735853]
####### Article R521-1|LEGIARTI000018735853
L'âge mentionné au premier alinéa de l'article L. 521-3 à partir duquel les
enfants ouvrent droit à la majoration des allocations familiales est fixé à
14 ans.
@ -85,7 +85,7 @@ champ d'application AllocationsFamiliales :
version_avril_2008.âge_minimum_alinéa_1_l521_3
```
#### [Article R521-2|LEGIARTI000006750608]
####### Article R521-2|LEGIARTI000006750608
Dans les situations visées au deuxième alinéa de l'article L. 521-2 ,
l'allocataire est celui des deux parents qu'ils désignent d'un commun accord.
@ -112,7 +112,7 @@ ou des enfants.
# ce programme.
```
#### [Article R521-3|LEGIARTI000006750610]
####### Article R521-3|LEGIARTI000006750610
Sous réserve de l'article R. 521-4, dans les situations visées aux 1° et 2° de
l'article R. 521-2 , la prestation due à chacun des parents est égale au
@ -164,7 +164,7 @@ champ d'application AllocationsFamiliales :
enfants_à_charge_droit_ouvert_prestation_familiale)
```
#### [Article R521-4|LEGIARTI000006750613]
####### Article R521-4|LEGIARTI000006750613
Pour l'ouverture du droit à la majoration prévue à l'article L. 521-3 , le
nombre d'enfants à charge est évalué dans les conditions prévues au premier
@ -202,7 +202,7 @@ champ d'application AllocationsFamiliales :
###### Chapitre 5 : Prestations familiales et prestations assimilées
#### [Article R755-0-2|LEGIARTI000006752633]
####### Article R755-0-2|LEGIARTI000006752633
Le plafond de rémunération des enfants à charge mentionnés à l'article
L. 512-3 est égal, pour un mois, à 55 % du salaire minimum de croissance en

View File

@ -2,7 +2,7 @@
## Tests
### [Tests]
### Tests
```catala
déclaration champ d'application Données:

View File

@ -2,7 +2,7 @@
## Tests
### [Tests]
### Tests
```catala
déclaration champ d'application Données:

View File

@ -12,7 +12,7 @@
######## 0I : Définition du revenu net global
######### [Article 1 A]
######### Article 1 A
Il est établi un impôt annuel unique sur le revenu des personnes physiques
désigné sous le nom d'impôt sur le revenu. Cet impôt frappe le revenu net
@ -66,7 +66,7 @@ champ d'application CalculImpotSurLeRevenu:
######## 0I : Définition du revenu net global
######### [Article 4 A]
######### Article 4 A
Les personnes qui ont en France leur domicile fiscal sont passibles de l'impôt sur le revenu en raison de l'ensemble de leurs revenus.

View File

@ -53,7 +53,7 @@ declaration scope Penalty286_83_135:
```
> End metadata
## [286-136 Penalty]
## 286-136 Penalty
```catala
scope Penalty286_83_135:

View File

@ -1,6 +1,6 @@
> Include: ../tutorial_en.catala_en
## [Test]
## Test
```catala
declaration scope UnitTest1:

View File

@ -27,7 +27,7 @@ importance by adding increasing numbers of "+" after the title of the heading.
The fundamental division unit is the article, introduced by a single "at".
Let's analyse a fictional example that defines an income tax.
#### [Article 1]
#### Article 1
The income tax for an individual is defined as a fixed percentage of the
individual's income over a year.
@ -58,7 +58,6 @@ Let's start our metadata section by declaring the type information for the
individual:
> Begin metadata
```catala
declaration structure Individual:
# The name of the structure "Individual", must start with an
@ -72,7 +71,6 @@ declaration structure Individual:
# "income" and "number_of_children" start by a lowercase letter,
# they follow the snake_case convention
```
> End metadata
This structure contains two data fields, "income" and "number_of_children". Structures are
@ -85,7 +83,6 @@ Sometimes, the law gives an enumeration of different situations. These
enumerations are modeled in Catala using an enumeration type, like:
> Begin metadata
```catala
declaration enumeration TaxCredit:
# The name "TaxCredit" is also written in CamelCase
@ -98,7 +95,6 @@ declaration enumeration TaxCredit:
# by the tax credit. This means that if you're in the "ChildrenTaxCredit"
# situation, you will also have access to this number of children
```
> End metadata
In computer science terms, such an enumeration is called a "sum type" or simply
@ -112,7 +108,6 @@ Catala using "scopes". Scopes are close to functions in terms of traditional
programming. Scopes also have to be declared in metadata, so here we go:
> Begin metadata
```catala
declaration scope IncomeTaxComputation:
# Scope names use CamelCase
@ -123,13 +118,12 @@ declaration scope IncomeTaxComputation:
context fixed_percentage content decimal
context income_tax content money
```
> End metadata
We now have everything to annotate the contents of article 1, which is copied
over below.
#### [Article 1]
#### Article 1
The income tax for an individual is defined as a fixed percentage of the
individual's income over a year.
@ -161,7 +155,7 @@ But inside article 1, one question remains unknown: what is the value of
of the fixed percentage? Often, precise values are defined elsewhere in the
legislative source. Here, let's suppose we have:
#### [Article 2]
#### Article 2
The fixed percentage mentionned at article 1 is equal to 20 %.
@ -180,7 +174,7 @@ definition is as close as possible to its location in the text.
So far so good, but now the legislative text introduces some trickiness. Let us
suppose the third article says:
#### [Article 3]
#### Article 3
If the individual is in charge of 2 or more children, then the fixed
percentage mentionned at article 1 is equal to 15 %.
@ -215,7 +209,6 @@ like in the metadata definition when we want to define a two-brackets tax
computation:
> Begin metadata
```catala
declaration structure TwoBrackets:
data breakpoint content money
@ -226,12 +219,11 @@ declaration scope TwoBracketsTaxComputation :
context brackets content TwoBrackets
context tax_formula content money depends on money
```
> End metadata
And in the code:
#### [Article4]
#### Article4
The tax amount for a two-brackets computation is equal to the amount
of income in each bracket multiplied by the rate of each bracket.
@ -252,7 +244,7 @@ scope TwoBracketsTaxComputation :
Now that we've defined our helper scope for computing a two-brackets tax, we
want to use it in our main tax computation scope.
#### [Article 5]
#### Article 5
For individuals whose income is greater than $100,000, the income
tax of article 1 is 40% of the income above $100,000. Below $100,000, the
@ -276,7 +268,7 @@ scope NewIncomeTaxComputation :
definition income_tax equals two_brackets.tax_formula of individual.income
```
#### [Article 6]
#### Article 6
Individuals earning less than $10,000 are exempted of the income tax mentionned
at article 1.
@ -304,7 +296,7 @@ cases for each Catala scope that you define is a good practice called
"unit testing" in the software engineering community. A test case is defined
as another scope:
#### [Testing NewIncomeTaxComputation]
#### Testing NewIncomeTaxComputation
```catala
declaration scope Test1:
@ -357,7 +349,7 @@ definition of income tax in article 5. But actually, article 6 is just an
exception of article 5. In the law, it is implicit that if article 6 is
applicable, then it takes precedence over article 5.
#### [Fixing the computation]
#### Fixing the computation
This implicit precedence has to be explicitely declared in Catala. Here is a
fixed version of the NewIncomeTaxComputation scope:

View File

@ -1,6 +1,6 @@
> Inclusion: ../tutoriel_fr.catala_fr
#### [Test]
#### Test
```catala
déclaration champ d'application TestUnitaire1:

View File

@ -29,7 +29,7 @@ l'entête.
L'unité de division fondamentale est l'article, encadré par un simple arobase.
Étudions un exemple ficitif qui définit un impôt sur le revenu.
#### [Article 1]
#### Article 1
L'impôt sur le revenu d'un individu est calculé en tant qu'un pourcentage
fixe des revenus d'une personne pour une année.
@ -60,7 +60,6 @@ Commençons notre section métadonnées en déclarant l'information sur le type
personne :
> Début métadonnées
```catala
déclaration structure Personne:
# Le nom de la structure "Personne", doit commencer
@ -75,7 +74,6 @@ déclaration structure Personne:
# "revenu" and "nombre_enfants" commençent par une lettre minuscule,
# ils adhèrent à la convention snake_case
```
> Fin métadonnées
Cette structure contient deux champs de de données, "revenu" et "nombre_enfants".
@ -88,7 +86,6 @@ Parfois, la loi donne une énumération de différentes situations. Ces énumér
sont modélisés en Catala par le type énumération, comme suit :
> Début métadonnées
```catala
déclaration énumération CréditImpôt:
# Le nom "CréditImpôt" s'écrit aussi en CamelCase
@ -102,7 +99,6 @@ déclaration énumération CréditImpôt:
# d'impôt. Cela signifie que si vous êtes dans la situation
# "CréditImpôtEnfants", vous aurez aussi accès à ce nombre d'enfants.
```
> Fin métadonnées
En informatique, une telle énumération est appelée "type somme" ou simplement
@ -118,7 +114,6 @@ traditionnelle. Les champs d'application doivent avoir été déclarés
préalablement dans les métadonnées, de la manière suivante:
> Début métadonnées
```catala
déclaration champ d'application CalculImpôtRevenu:
# Les champs d'application utilisent le CamelCase
@ -129,13 +124,12 @@ déclaration champ d'application CalculImpôtRevenu:
contexte pourcentage_fixe contenu décimal
contexte impôt_revenu contenu argent
```
> Fin métadonnées
Nous avons maintenant tout ce dont nous avons besoin pour annoter le contenu
de l'article 1 qui a été copié ci-dessous.
#### [Article 1]
#### Article 1
L'impôt sur le revenu pour une personne est défini comme un pourcentage fixe
des revenus de la personne pour une année.
@ -169,7 +163,7 @@ Mais dans l'article 1, une question reste sans réponse: quelle est la valeur
de la pourcentage fixe? Souvent, des valeurs précises sont définis ailleurs
dans les sources législatives. Ici, supposons que nous avons:
#### [Article 2]
#### Article 2
Le pourcentage fixe mentionné à l'article 1 est égal à 20%.
@ -188,7 +182,7 @@ proche possible de sa localisation dans le texte.
Jusqu'à là tout va bien mais maintenant le texte législatif présente quelques
difficultés. Supposons que le troisième article dispose :
#### [Article 3]
#### Article 3
Si l'individu a à sa charge deux ou plus enfants alors
le pourcentage fixe mentionné à l'article 1 vaut 15 %.
@ -224,7 +218,6 @@ Catala vous permet de définir des fonctions partout dans vos données. Voici
définir un calcul de l'impôt sur le revenu à deux tranches :
> Début métadonnées
```catala
déclaration structure DeuxTranches:
donnée seuil contenu argent
@ -235,12 +228,11 @@ déclaration champ d'application CalculImpôtDeuxTranches :
contexte tranches contenu DeuxTranches
contexte formule_imposition contenu argent dépend de argent
```
> Fin métadonnées
Et dans le code :
#### [Article4]
#### Article4
Le montant d'impôt pour le calcul à deux tranches
est égal au montant d'impôt dans chaque tranche multiplié
@ -263,7 +255,7 @@ Maintenant que nous avons défini notre champ d'application utilitaire pour
calculer un impôt à deux tranches, nous voulons l'utiliser dans notre champ
d'application principal de calcul de l'impôt.
#### [Article 5]
#### Article 5
Pour les individus dont le revenu est supérieur à 100 000€,
l'impôt sur le revenu de l'article 1 est de 40% du revenu au-dessus de
@ -289,7 +281,7 @@ champ d'application NouveauCalculImpôtRevenu :
deux_tranches.formule_imposition de personne.revenu
```
#### [Article 6]
#### Article 6
Les personnes ayant moins de 10 000€ de revenus sont exemptés de l'impôt
sur le revenu prévu à l'article 1.
@ -319,7 +311,7 @@ définissez est une bonne pratique appelée "tests unitaires" dans la
communauté du génie logicielle. Les cas de test sont définis dans des
champ d'application :
#### [Tester NouveauCalculImpotRevenu]
#### Tester NouveauCalculImpotRevenu
```catala
déclaration champ d'application Test1:
@ -375,7 +367,7 @@ est une simple exception à l'article 5. Dans la loi, il est implicite que
si l'article 6 est applicable, alors son application est prioritaire
sur l'article 5.
#### [Régler correctement le calcul]
#### Régler correctement le calcul
Cette priorité implicite doit être explicitement déclaré en Catala. Voici une
version correcte du champ d'application NouveauCalculImpotRevenu :

View File

@ -33,7 +33,7 @@ declaration scope BasisOfGift:
```
> End metadata
### [(a) Gifts after December 31, 1920]
### (a) Gifts after December 31, 1920
If the property was acquired by gift after December 31, 1920, the basis shall be
the same as it would be in the hands of the donor or the last preceding owner by
@ -77,7 +77,7 @@ scope BasisOfGift under condition
-- None : value.fair_market of transferor.acquisition.moment
```
### [(b) Transfer in trust after December 31, 1920]
### (b) Transfer in trust after December 31, 1920
If the property was acquired after December 31, 1920, by a transfer in trust
(other than by a transfer in trust by a gift, bequest, or devise), the basis
@ -95,7 +95,7 @@ scope BasisOfGift under condition
transferor.basis + transferor.gain_or_loss of acquisition.moment
```
### [(c) Gift or transfer in trust before January 1, 1921]
### (c) Gift or transfer in trust before January 1, 1921
If the property was acquired by gift or transfer in trust on or before December
31, 1920, the basis shall be the fair market value of such property at the time
@ -109,7 +109,7 @@ scope BasisOfGift under condition acquisition.moment <= |1920-01-31|:
### (d) Increased basis for gift tax paid
#### [(1) In general]
#### (1) In general
If— (A) the property is acquired by gift on or after September 2, 1958, the
basis shall be the basis determined under subsection (a), increased (but not
above the fair market value of the property at the time of the gift) by the
@ -155,7 +155,7 @@ scope BasisOfGift under condition
)
```
#### [(2) Amount of tax paid with respect to gift]
#### (2) Amount of tax paid with respect to gift
For purposes of paragraph (1), the amount of gift tax paid with respect to any
gift is an amount which bears the same ratio to the amount of gift tax paid under
@ -175,7 +175,7 @@ under section 2523 (relating to marital deduction).
#formalizing other sections of the code
```
#### [(3) Gifts treated as made one-half by each spouse]
#### (3) Gifts treated as made one-half by each spouse
For purposes of paragraph (1), where the donor and his spouse elected, under
section 2513 to have the gift considered as made one-half by each, the amount
@ -187,7 +187,7 @@ the manner provided in paragraph (2)).
# Same here
```
#### [(4) Treatment as adjustment to basis]
#### (4) Treatment as adjustment to basis
For purposes of section 1016(b), an increase in basis under paragraph (1) shall
be treated as an adjustment under section 1016(a).
@ -196,7 +196,7 @@ be treated as an adjustment under section 1016(a).
# Same here
```
#### [(5) Application to gifts before 1955]
#### (5) Application to gifts before 1955
With respect to any property acquired by gift before 1955, references in this
subsection to any provision of this title shall be deemed to refer to the
@ -209,7 +209,7 @@ laws which was effective for the year in which such gift was made.
#### (6) Special rule for gifts made after December 31, 1976
##### [(A) In general]
##### (A) In general
In the case of any gift made after December 31, 1976, the increase in basis
provided by this subsection with respect to any gift for the gift tax paid under
@ -232,7 +232,7 @@ scope BasisOfGift under condition
)
```
##### [(B) Net appreciation]
##### (B) Net appreciation
For purposes of paragraph (1), the net appreciation in value of any gift is the
amount by which the fair market value of the gift exceeds the donors adjusted
@ -244,7 +244,7 @@ scope BasisOfGift:
value.fair_market_value of acquisition.moment - transferor.basis
```
##### [(e) Gifts between spouses]
##### (e) Gifts between spouses
In the case of any property acquired by gift in a transfer described in section
1041(a), the basis of such property in the hands of the transferee shall be

View File

@ -1,7 +1,6 @@
## Section 121
> Begin metadata
```catala
declaration structure Period:
data begin content date
@ -160,7 +159,7 @@ scope Section121TwoPasses:
```
> End metadata
## [(a) Exclusion]
### (a) Exclusion
Gross income shall not include gain from the sale or exchange of property if,
during the 5-year period ending on the date of the sale or exchange, such
@ -216,7 +215,7 @@ scope Section121TwoPersons:
### (b) Limitations
#### [(1) In general]
#### (1) In general
The amount of gain excluded from gross income under subsection (a) with
respect to any sale or exchange shall not exceed $250,000.
@ -244,7 +243,7 @@ scope Section121TwoPersons:
income_excluded_from_gross_income_uncapped
```
#### [(2) Special rules for joint returns]
#### (2) Special rules for joint returns
In the case of a husband and wife who make a joint return for the taxable year
of the sale or exchange of the property—
@ -256,7 +255,7 @@ of the sale or exchange of the property—
# Reasonably it should.
```
#### [(A) $500,000 Limitation for certain joint returns]
##### (A) $500,000 Limitation for certain joint returns
Paragraph (1) shall be applied by substituting “$500,000” for “$250,000” if—
@ -299,7 +298,7 @@ scope Section121TwoPersons:
consequence equals $500,000
```
#### [(B) Other joint returns]
##### (B) Other joint returns
If such spouses do not meet the requirements of subparagraph (A), the limitation
under paragraph (1) shall be the sum of the limitations under paragraph (1) to
@ -339,7 +338,7 @@ scope Section121TwoPasses under condition
}
```
#### [(3) Application to only 1 sale or exchange every 2 years]
#### (3) Application to only 1 sale or exchange every 2 years
Subsection (a) shall not apply to any sale or exchange by the taxpayer if,
@ -360,7 +359,7 @@ scope Section121SinglePerson:
consequence equals $0
```
#### [(4) Special rule for certain sales by surviving spouses]
#### (4) Special rule for certain sales by surviving spouses
```catala
# Sarah: the year when your spouse dies, do you file a joint return or
@ -402,12 +401,12 @@ scope Section121TwoPasses under condition
#### (5) Exclusion of gain allocated to nonqualified use
##### [(A) In general]
##### (A) In general
Subsection (a) shall not apply to so much of the gain from the sale or exchange
of property as is allocated to periods of nonqualified use.
##### [(B) Gain allocated to periods of nonqualified use]
##### (B) Gain allocated to periods of nonqualified use
For purposes of subparagraph (A), gain shall be allocated to periods of
nonqualified use based on the ratio which—
@ -421,14 +420,14 @@ was owned by the taxpayer, bears to
For purposes of this paragraph—
###### [(i) In general]
###### (i) In general
The term “period of nonqualified use” means any period (other than the portion
of any period preceding January 1, 2009) during which the property is not used
as the principal residence of the taxpayer or the taxpayers spouse or former
spouse.
###### [(ii) Exceptions]
###### (ii) Exceptions
The term “period of nonqualified use” does not include—
@ -445,7 +444,7 @@ subsection (d)(9)(A), and
of 2 years) due to change of employment, health conditions, or such other
unforeseen circumstances as may be specified by the Secretary.
###### [(D) Coordination with recognition of gain attributable to depreciation]
##### (D) Coordination with recognition of gain attributable to depreciation
For purposes of this paragraph—

View File

@ -32,7 +32,7 @@ scope QualifiedEmployeeDiscount:
### (c) Qualified employee discount defined
For purposes of this section—
#### [(1) Qualified employee discount]
#### (1) Qualified employee discount
The term “qualified employee discount” means any employee discount with respect
to qualified property or services to the extent such discount does not exceed—
@ -72,7 +72,7 @@ scope QualifiedEmployeeDiscount under condition is_services:
#### (2) Gross profit percentage
##### [(A) In general]
##### (A) In general
The term “gross profit percentage” means the percent which—
@ -89,7 +89,7 @@ scope QualifiedEmployeeDiscount under condition is_property:
(customer_price -$ aggregate_cost) /$ customer_price
```
##### [(B) Determination of gross profit percentage]
##### (B) Determination of gross profit percentage
Gross profit percentage shall be determined on the basis of—
@ -104,7 +104,7 @@ reasonable classification of property selected by the employer), and
# percentage ; we do not formalize them
```
##### [(3) Employee discount defined]
##### (3) Employee discount defined
The term “employee discount” means the amount by which—
@ -122,7 +122,7 @@ scope QualifiedEmployeeDiscount:
customer_price -$ employee_price
```
##### [(4) Qualified property or services]
##### (4) Qualified property or services
The term “qualified property or services” means any property (other than real
property and other than personal property of a kind held for investment) or

View File

@ -1,6 +1,6 @@
> Include: ../section_121.catala_en
## [Testing paragraph (a)]
## Testing paragraph (a)
```catala
declaration scope Data:

View File

@ -1,6 +1,6 @@
> Include: ../section_132.catala_en
### [Test]
### Test
```catala
declaration scope TestSection132_1:

File diff suppressed because one or more lines are too long

View File

@ -10,10 +10,9 @@
"license": "Apache-2.0",
"dependencies": {
"benchmark": "^2.1.4",
"lodash": "^4.17.20",
"lodash": "^4.17.21",
"platform": "^1.3.6"
},
"devDependencies": {}
}
},
"node_modules/benchmark": {
"version": "2.1.4",
@ -25,9 +24,9 @@
}
},
"node_modules/lodash": {
"version": "4.17.20",
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.20.tgz",
"integrity": "sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA=="
"version": "4.17.21",
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz",
"integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg=="
},
"node_modules/platform": {
"version": "1.3.6",
@ -46,9 +45,9 @@
}
},
"lodash": {
"version": "4.17.20",
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.20.tgz",
"integrity": "sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA=="
"version": "4.17.21",
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz",
"integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg=="
},
"platform": {
"version": "1.3.6",

View File

@ -5,7 +5,7 @@
"main": "french_law.js",
"dependencies": {
"benchmark": "^2.1.4",
"lodash": "^4.17.20",
"lodash": "^4.17.21",
"platform": "^1.3.6"
},
"devDependencies": {},

View File

@ -139,13 +139,13 @@ let pygmentize_code (c : string Pos.marked) (language : C.backend_lang) : string
(** {1 Weaving} *)
let law_article_item_to_html (language : C.backend_lang) (fmt : Format.formatter)
(i : A.law_article_item) : unit =
let rec law_structure_to_html (language : C.backend_lang) (fmt : Format.formatter)
(i : A.law_structure) : unit =
match i with
| A.LawText t ->
let t = pre_html t in
if t = "" then () else Format.fprintf fmt "<p class='law-text'>%s</p>" t
| A.CodeBlock (_, c) ->
| A.CodeBlock (_, c, _) ->
let date = "\\d\\d/\\d\\d/\\d\\d\\d\\d" in
let syms = R.regexp (date ^ "|!=|<=|>=|--|->|\\*|\\/") in
let syms_subst = function
@ -162,46 +162,25 @@ let law_article_item_to_html (language : C.backend_lang) (fmt : Format.formatter
Format.fprintf fmt "<div class='code-wrapper'>\n<div class='filename'>%s</div>\n%s\n</div>"
(Pos.get_file (Pos.get_position c))
(pygmentize_code (Pos.same_pos_as ("```catala" ^ pprinted_c ^ "```") c) language)
let rec law_structure_to_html (language : C.backend_lang) (fmt : Format.formatter)
(i : A.law_structure) : unit =
match i with
| A.LawHeading (heading, children) ->
let h_number = heading.law_heading_precedence + 2 in
Format.fprintf fmt "<h%d class='law-heading'>%s</h%d>\n" h_number
(pre_html heading.law_heading_name)
h_number;
Format.pp_print_list
~pp_sep:(fun fmt () -> Format.fprintf fmt "\n")
(law_structure_to_html language) fmt children
| A.LawInclude _ -> ()
| A.LawArticle (a, children) ->
Format.fprintf fmt
"<div class='article-container'>\n\n<div class='article-title'><a href='%s'>%s</a></div>\n"
(match (a.law_article_id, language) with
Format.fprintf fmt "<h%d class='law-heading'><a href='%s'>%s</a></h%d>\n" h_number
(match (heading.law_heading_id, language) with
| Some id, `Fr ->
let ltime = Unix.localtime (Unix.time ()) in
P.sprintf "https://legifrance.gouv.fr/codes/id/%s/%d-%02d-%02d" id
(1900 + ltime.Unix.tm_year) (ltime.Unix.tm_mon + 1) ltime.Unix.tm_mday
| _ -> "#")
(pre_html (Pos.unmark a.law_article_name));
(pre_html (Pos.unmark heading.law_heading_name))
h_number;
Format.pp_print_list
~pp_sep:(fun fmt () -> Format.fprintf fmt "\n")
(law_article_item_to_html language)
fmt children;
Format.fprintf fmt "\n</div>"
| A.MetadataBlock (b, c) -> law_article_item_to_html language fmt (A.CodeBlock (b, c))
| A.IntermediateText t ->
let t = pre_html t in
if t = "" then () else Format.fprintf fmt "<p class='law-text'>%s</p>" t
let program_item_to_html (language : C.backend_lang) (fmt : Format.formatter) (i : A.program_item) :
unit =
match i with A.LawStructure s -> law_structure_to_html language fmt s
(law_structure_to_html language) fmt children
| A.LawInclude _ -> ()
(** {1 API} *)
let ast_to_html (language : C.backend_lang) (fmt : Format.formatter) (program : A.program) : unit =
Format.pp_print_list
~pp_sep:(fun fmt () -> Format.fprintf fmt "\n\n")
(program_item_to_html language) fmt program.program_items
(law_structure_to_html language) fmt program.program_items

View File

@ -132,32 +132,19 @@ let math_syms_replace (c : string) : string =
(** {1 Weaving} *)
let law_article_item_to_latex (language : C.backend_lang) (fmt : Format.formatter)
(i : A.law_article_item) : unit =
match i with
| A.LawText t -> Format.fprintf fmt "%s" (pre_latexify t)
| A.CodeBlock (_, c) ->
Format.fprintf fmt
"\\begin{minted}[label={\\hspace*{\\fill}\\texttt{%s}},firstnumber=%d]{%s}\n\
```catala%s```\n\
\\end{minted}"
(pre_latexify (Filename.basename (Pos.get_file (Pos.get_position c))))
(Pos.get_start_line (Pos.get_position c) - 1)
(match language with `Fr -> "catala_fr" | `En -> "catala_en" | `Pl -> "catala_pl")
(math_syms_replace (Pos.unmark c))
let rec law_structure_to_latex (language : C.backend_lang) (fmt : Format.formatter)
(i : A.law_structure) : unit =
match i with
| A.LawHeading (heading, children) ->
Format.fprintf fmt "\\%ssection*{%s}\n\n"
Format.fprintf fmt "\\%s*{%s}\n\n"
(match heading.law_heading_precedence with
| 0 -> ""
| 1 -> ""
| 2 -> "sub"
| 3 -> "sub"
| _ -> "subsub")
(pre_latexify heading.law_heading_name);
| 0 -> "chapter"
| 1 -> "section"
| 2 -> "subsection"
| 4 -> "subsubsection"
| 5 -> "paragraph"
| _ -> "subparagraph")
(pre_latexify (Pos.unmark heading.law_heading_name));
Format.pp_print_list
~pp_sep:(fun fmt () -> Format.fprintf fmt "\n\n")
(law_structure_to_latex language) fmt children
@ -170,13 +157,17 @@ let rec law_structure_to_latex (language : C.backend_lang) (fmt : Format.formatt
(match page with None -> "" | Some p -> Format.sprintf "page=%d," p)
file label
| A.LawInclude (A.CatalaFile _ | A.LegislativeText _) -> ()
| A.LawArticle (article, children) ->
Format.fprintf fmt "\\paragraph{%s}\n\n" (pre_latexify (Pos.unmark article.law_article_name));
Format.pp_print_list
~pp_sep:(fun fmt () -> Format.fprintf fmt "\n")
(law_article_item_to_latex language)
fmt children
| A.MetadataBlock (_, c) ->
| A.LawText t -> Format.fprintf fmt "%s" (pre_latexify t)
| A.CodeBlock (_, c, false) ->
Format.fprintf fmt
"\\begin{minted}[label={\\hspace*{\\fill}\\texttt{%s}},firstnumber=%d]{%s}\n\
```catala%s```\n\
\\end{minted}"
(pre_latexify (Filename.basename (Pos.get_file (Pos.get_position c))))
(Pos.get_start_line (Pos.get_position c) - 1)
(match language with `Fr -> "catala_fr" | `En -> "catala_en" | `Pl -> "catala_pl")
(math_syms_replace (Pos.unmark c))
| A.CodeBlock (_, c, true) ->
let metadata_title =
match language with `Fr -> "Métadonnées" | `En -> "Metadata" | `Pl -> "Metadane"
in
@ -193,15 +184,10 @@ let rec law_structure_to_latex (language : C.backend_lang) (fmt : Format.formatt
(pre_latexify (Filename.basename (Pos.get_file (Pos.get_position c))))
(match language with `Fr -> "catala_fr" | `En -> "catala_en" | `Pl -> "catala_pl")
(math_syms_replace (Pos.unmark c))
| A.IntermediateText t -> Format.fprintf fmt "%s" (pre_latexify t)
let program_item_to_latex (language : C.backend_lang) (fmt : Format.formatter) (i : A.program_item)
: unit =
match i with A.LawStructure law_s -> law_structure_to_latex language fmt law_s
(** {1 API} *)
let ast_to_latex (language : C.backend_lang) (fmt : Format.formatter) (program : A.program) : unit =
Format.pp_print_list
~pp_sep:(fun fmt () -> Format.fprintf fmt "\n\n")
(program_item_to_latex language) fmt program.program_items
(law_structure_to_latex language) fmt program.program_items

View File

@ -520,15 +520,15 @@ type source_repr = (string[@opaque]) Pos.marked
visitors { variety = "map"; ancestors = [ "Pos.marked_map" ]; name = "source_repr_map" },
visitors { variety = "iter"; ancestors = [ "Pos.marked_iter" ]; name = "source_repr_iter" }]
type law_article = {
law_article_name : (string[@opaque]) Pos.marked;
law_article_id : (string[@opaque]) option;
law_article_expiration_date : (string[@opaque]) option;
law_article_precedence : (int[@opaque]);
type law_heading = {
law_heading_name : (string[@opaque]) Pos.marked;
law_heading_id : (string[@opaque]) option;
law_heading_expiration_date : (string[@opaque]) option;
law_heading_precedence : (int[@opaque]);
}
[@@deriving
visitors { variety = "map"; ancestors = [ "Pos.marked_map" ]; name = "law_article_map" },
visitors { variety = "iter"; ancestors = [ "Pos.marked_iter" ]; name = "law_article_iter" }]
visitors { variety = "map"; ancestors = [ "Pos.marked_map" ]; name = "law_heading_map" },
visitors { variety = "iter"; ancestors = [ "Pos.marked_iter" ]; name = "law_heading_iter" }]
type law_include =
| PdfFile of (string[@opaque]) Pos.marked * (int[@opaque]) option
@ -538,72 +538,29 @@ type law_include =
visitors { variety = "map"; ancestors = [ "Pos.marked_map" ]; name = "law_include_map" },
visitors { variety = "iter"; ancestors = [ "Pos.marked_iter" ]; name = "law_include_iter" }]
type law_article_item = LawText of (string[@opaque]) | CodeBlock of code_block * source_repr
[@@deriving
visitors
{
variety = "map";
ancestors = [ "code_block_map"; "source_repr_map" ];
name = "law_article_item_map";
},
visitors
{
variety = "iter";
ancestors = [ "code_block_iter"; "source_repr_iter" ];
name = "law_article_item_iter";
}]
type law_heading = { law_heading_name : (string[@opaque]); law_heading_precedence : (int[@opaque]) }
[@@deriving
visitors { variety = "map"; name = "law_heading_map" },
visitors { variety = "iter"; name = "law_heading_iter" }]
type law_structure =
| LawInclude of law_include
| LawHeading of law_heading * law_structure list
| LawArticle of law_article * law_article_item list
| MetadataBlock of code_block * source_repr
| IntermediateText of (string[@opaque])
| LawText of (string[@opaque])
| CodeBlock of code_block * source_repr * bool (* Metadata if true *)
[@@deriving
visitors
{
variety = "map";
ancestors =
[
"law_include_map";
"law_article_map";
"law_article_item_map";
"code_block_map";
"source_repr_map";
"law_heading_map";
];
ancestors = [ "law_include_map"; "code_block_map"; "source_repr_map"; "law_heading_map" ];
name = "law_structure_map";
},
visitors
{
variety = "iter";
ancestors =
[
"law_include_iter";
"law_article_iter";
"law_article_item_iter";
"code_block_iter";
"source_repr_iter";
"law_heading_iter";
];
[ "law_include_iter"; "code_block_iter"; "source_repr_iter"; "law_heading_iter" ];
name = "law_structure_iter";
}]
type program_item = LawStructure of law_structure
type program = { program_items : law_structure list; program_source_files : (string[@opaque]) list }
[@@deriving
visitors { variety = "map"; ancestors = [ "law_structure_map" ]; name = "program_item_map" },
visitors { variety = "iter"; ancestors = [ "law_structure_iter" ]; name = "program_item_iter" }]
visitors { variety = "map"; ancestors = [ "law_structure_map" ]; name = "program_map" },
visitors { variety = "iter"; ancestors = [ "law_structure_iter" ]; name = "program_iter" }]
type program = { program_items : program_item list; program_source_files : (string[@opaque]) list }
[@@deriving
visitors { variety = "map"; ancestors = [ "program_item_map" ]; name = "program_map" },
visitors { variety = "iter"; ancestors = [ "program_item_iter" ]; name = "program_iter" }]
type source_file_or_master =
| SourceFile of program_item list
| MasterFile of string Pos.marked list
type source_file = law_structure list

View File

@ -1084,32 +1084,18 @@ let desugar_program (ctxt : Name_resolution.context) (prgm : Ast.program) : Desu
ctxt.Name_resolution.scopes;
}
in
let processer_article_item (prgm : Desugared.Ast.program) (item : Ast.law_article_item) :
let rec processer_structure (prgm : Desugared.Ast.program) (item : Ast.law_structure) :
Desugared.Ast.program =
match item with
| CodeBlock (block, _) ->
| LawHeading (_, children) ->
List.fold_left (fun prgm child -> processer_structure prgm child) prgm children
| CodeBlock (block, _, _) ->
List.fold_left
(fun prgm item ->
match Pos.unmark item with
| Ast.ScopeUse use -> process_scope_use ctxt prgm use
| _ -> prgm)
prgm block
| _ -> prgm
| LawInclude _ | LawText _ -> prgm
in
let rec processer_structure (prgm : Desugared.Ast.program) (item : Ast.law_structure) :
Desugared.Ast.program =
match item with
| LawHeading (_, children) ->
List.fold_left (fun prgm child -> processer_structure prgm child) prgm children
| LawArticle (_, children) ->
List.fold_left (fun prgm child -> processer_article_item prgm child) prgm children
| MetadataBlock (b, c) -> processer_article_item prgm (CodeBlock (b, c))
| IntermediateText _ | LawInclude _ -> prgm
in
let processer_item (prgm : Desugared.Ast.program) (item : Ast.program_item) :
Desugared.Ast.program =
match item with LawStructure s -> processer_structure prgm s
in
List.fold_left processer_item empty_prgm prgm.program_items
List.fold_left processer_structure empty_prgm prgm.program_items

View File

@ -24,17 +24,10 @@ let fill_pos_with_legislative_info (p : Ast.program) : Ast.program =
method! visit_LawHeading (env : string list) (heading : Ast.law_heading)
(children : Ast.law_structure list) =
let env = heading.law_heading_name :: env in
let env = Pos.unmark heading.law_heading_name :: env in
Ast.LawHeading
( super#visit_law_heading env heading,
List.map (fun child -> super#visit_law_structure env child) children )
method! visit_LawArticle (env : string list) (heading : Ast.law_article)
(children : Ast.law_article_item list) =
let env = Pos.unmark heading.law_article_name :: env in
Ast.LawArticle
( super#visit_law_article env heading,
List.map (fun child -> super#visit_law_article_item env child) children )
end
in
visitor#visit_program [] p

View File

@ -533,7 +533,6 @@ let lex_law (lexbuf : lexbuf) : token =
code_string_acc := "";
BEGIN_CODE
| eof -> EOF
| '#', Star white_space, "Master file" -> MASTER_FILE
| '>', Star white_space, "Begin metadata" -> BEGIN_METADATA
| '>', Star white_space, "End metadata" -> END_METADATA
| ( '>',
@ -554,34 +553,8 @@ let lex_law (lexbuf : lexbuf) : token =
if Filename.extension name = ".pdf" then
LAW_INCLUDE (Ast.PdfFile ((name, Pos.from_lpos pos), pages))
else LAW_INCLUDE (Ast.CatalaFile (name, Pos.from_lpos pos))
| '#', Plus '#', Star white_space, Plus (Compl ('[' | ']' | '\n')), Star white_space, '\n' ->
get_law_heading lexbuf
| ( '#',
Plus '#',
Star white_space,
'[',
Star white_space,
Plus (Compl ']'),
Star white_space,
']',
'\n' ) ->
let extract_article_title = R.regexp "([#]+)\\s*\\[([^@]+)\\]" in
let get_substring =
R.get_substring (R.exec ~rex:extract_article_title (Utf8.lexeme lexbuf))
in
let title = get_substring 2 in
let get_new_lines = R.regexp "\n" in
let new_lines_count =
try Array.length (R.extract ~rex:get_new_lines (Utf8.lexeme lexbuf)) with Not_found -> 0
in
(* the -1 is here to compensate for Sedlex's automatic newline detection around token *)
for _i = 1 to new_lines_count - 1 do
new_line lexbuf
done;
let precedence = calc_precedence (get_substring 1) in
LAW_ARTICLE (title, None, None, precedence)
| Plus (Compl ('/' | '#' | '`' | '>')) -> LAW_TEXT (Utf8.lexeme lexbuf)
| Plus '#', Star white_space, Plus (Compl '\n'), Star white_space, '\n' -> get_law_heading lexbuf
| Plus (Compl ('#' | '`' | '>')) -> LAW_TEXT (Utf8.lexeme lexbuf)
| _ -> raise_lexer_error (Pos.from_lpos prev_pos) prev_lexeme
(** Entry point of the lexer, distributes to {!val: lex_code} or {!val: lex_law} depending of {!val:

View File

@ -18,23 +18,18 @@ module R = Re.Pcre
(* Calculates the precedence according a {!val: matched_regex} of the form : '[#]+'.
@note -2 because both [LAW_ARTICLE] and [LAW_HEADING] start with at least "##" and the number of
'#' remaining corresponds to the precedence. *)
let calc_precedence (matched_regex : string) : int = String.length matched_regex - 2
@note -2 because [LAW_HEADING] start with at least "#" and the number of '#' remaining
corresponds to the precedence. *)
let calc_precedence (matched_regex : string) : int = String.length matched_regex - 1
(* Gets the [LAW_HEADING] token from the current {!val: lexbuf} *)
let get_law_heading (lexbuf : lexbuf) : token =
let extract_code_title = R.regexp "([#]+)\\s*([^#\n]+)\n" in
let get_match = R.get_substring (R.exec ~rex:extract_code_title (Utf8.lexeme lexbuf)) in
let get_new_lines = R.regexp "\n" in
let new_lines_count =
try Array.length (R.extract ~rex:get_new_lines (Utf8.lexeme lexbuf)) with Not_found -> 0
let extract_article_title =
R.regexp "([#]+)\\s*([^\\|]+)(\\|([^\\|]+)|)(\\|\\s*([0-9]{4}\\-[0-9]{2}\\-[0-9]{2})|)"
in
(* the -1 is here to compensate for Sedlex's automatic newline detection around token *)
for _i = 1 to new_lines_count - 1 do
new_line lexbuf
done;
let law_title = get_match 2 in
let precedence = calc_precedence (get_match 1) in
LAW_HEADING (law_title, precedence)
let get_substring = R.get_substring (R.exec ~rex:extract_article_title (Utf8.lexeme lexbuf)) in
let title = String.trim (get_substring 2) in
let article_id = try Some (get_substring 4) with Not_found -> None in
let article_expiration_date = try Some (get_substring 6) with Not_found -> None in
let precedence = calc_precedence (get_substring 1) in
LAW_HEADING (title, article_id, article_expiration_date, precedence)

View File

@ -494,7 +494,6 @@ let lex_law (lexbuf : lexbuf) : token =
BEGIN_CODE
| eof -> EOF
| '#', Star white_space, "Master file" -> MASTER_FILE
| '>', Star white_space, "Begin metadata" -> BEGIN_METADATA
| '>', Star white_space, "End metadata" -> END_METADATA
| ( '>',
@ -515,34 +514,8 @@ let lex_law (lexbuf : lexbuf) : token =
if Filename.extension name = ".pdf" then
LAW_INCLUDE (Ast.PdfFile ((name, Pos.from_lpos pos), pages))
else LAW_INCLUDE (Ast.CatalaFile (name, Pos.from_lpos pos))
| '#', Plus '#', Star white_space, Plus (Compl ('[' | ']' | '\n')), Star white_space, '\n' ->
get_law_heading lexbuf
| ( '#',
Plus '#',
Star white_space,
'[',
Star white_space,
Plus (Compl ']'),
Star white_space,
']',
'\n' ) ->
let extract_article_title = R.regexp "([#]+)\\s*\\[([^\\]]+)\\]" in
let get_substring =
R.get_substring (R.exec ~rex:extract_article_title (Utf8.lexeme lexbuf))
in
let title = get_substring 2 in
let get_new_lines = R.regexp "\n" in
let new_lines_count =
try Array.length (R.extract ~rex:get_new_lines (Utf8.lexeme lexbuf)) with Not_found -> 0
in
(* the -1 is here to compensate for Sedlex's automatic newline detection around token *)
for _i = 1 to new_lines_count - 1 do
new_line lexbuf
done;
let precedence = calc_precedence (get_substring 1) in
LAW_ARTICLE (title, None, None, precedence)
| Plus (Compl ('/' | '#' | '`' | '>')) -> LAW_TEXT (Utf8.lexeme lexbuf)
| Plus '#', Star white_space, Plus (Compl '\n'), Star white_space, '\n' -> get_law_heading lexbuf
| Plus (Compl ('#' | '`' | '>')) -> LAW_TEXT (Utf8.lexeme lexbuf)
| _ -> L.raise_lexer_error (Pos.from_lpos prev_pos) prev_lexeme
(** Entry point of the lexer, distributes to {!val: lex_code} or {!val: lex_law} depending of {!val:

View File

@ -500,9 +500,6 @@ let lex_law (lexbuf : lexbuf) : token =
BEGIN_CODE
| eof -> EOF
| '#', Star white_space, "Fichier ma", 0x00EE, "tre" ->
(* 0x00EE is î *)
MASTER_FILE
| '>', Star white_space, 'D', 0xE9, "but m", 0xE9, "tadonn", 0xE9, "es" -> BEGIN_METADATA
| '>', Star white_space, "Fin m", 0xE9, "tadonn", 0xE9, "es" -> END_METADATA
| ( '>',
@ -526,38 +523,8 @@ let lex_law (lexbuf : lexbuf) : token =
else if Filename.extension name = ".pdf" then
LAW_INCLUDE (Ast.PdfFile ((name, Pos.from_lpos pos), pages))
else LAW_INCLUDE (Ast.CatalaFile (name, Pos.from_lpos pos))
| ( '#',
Plus '#',
Star white_space,
'[',
Star white_space,
Plus (Compl ']'),
Star white_space,
']',
'\n' ) ->
let extract_article_title =
R.regexp
"([#]+)\\s*\\[\\s*(([^\\|]+)\\|(((LEGIARTI|JORFARTI)[0-9]{12})(\\|([0-2]{2}\\/[0-2]{2}\\/[0-2]{4})|))|[^\\@]+)\\]"
in
let get_substring =
R.get_substring (R.exec ~rex:extract_article_title (Utf8.lexeme lexbuf))
in
let title = try get_substring 3 with Not_found -> get_substring 2 in
let article_id = try Some (get_substring 5) with Not_found -> None in
let article_expiration_date = try Some (get_substring 8) with Not_found -> None in
let precedence = calc_precedence (get_substring 1) in
let get_new_lines = R.regexp "\n" in
let new_lines_count =
try Array.length (R.extract ~rex:get_new_lines (Utf8.lexeme lexbuf)) with Not_found -> 0
in
(* the -1 is here to compensate for Sedlex's automatic newline detection around token *)
for _i = 1 to new_lines_count - 1 do
new_line lexbuf
done;
LAW_ARTICLE (title, article_id, article_expiration_date, precedence)
| '#', Plus '#', Star white_space, Plus (Compl ('[' | ']' | '\n')), Star white_space, '\n' ->
get_law_heading lexbuf
| Plus (Compl ('/' | '#' | '`' | '>')) -> LAW_TEXT (Utf8.lexeme lexbuf)
| Plus '#', Star white_space, Plus (Compl '\n'), Star white_space, '\n' -> get_law_heading lexbuf
| Plus (Compl ('#' | '`' | '>')) -> LAW_TEXT (Utf8.lexeme lexbuf)
| _ -> L.raise_lexer_error (Pos.from_lpos prev_pos) prev_lexeme
(** Entry point of the lexer, distributes to {!val: lex_code} or {!val: lex_law} depending of {!val:

View File

@ -498,7 +498,6 @@ let lex_law (lexbuf : lexbuf) : token =
BEGIN_CODE
| eof -> EOF
| '#', Star white_space, "Plik glowny" -> MASTER_FILE
| '>', Star white_space, "Poczatek metadanych" -> BEGIN_METADATA
| '>', Star white_space, "Koniec metadanych" -> END_METADATA
| ( '>',
@ -519,34 +518,8 @@ let lex_law (lexbuf : lexbuf) : token =
if Filename.extension name = ".pdf" then
LAW_INCLUDE (Ast.PdfFile ((name, Pos.from_lpos pos), pages))
else LAW_INCLUDE (Ast.CatalaFile (name, Pos.from_lpos pos))
| '#', Plus '#', Star white_space, Plus (Compl ('[' | ']' | '\n')), Star white_space, '\n' ->
get_law_heading lexbuf
| ( '#',
Plus '#',
Star white_space,
'[',
Star white_space,
Plus (Compl ']'),
Star white_space,
']',
'\n' ) ->
let extract_article_title = R.regexp "([#]+)\\s*\\[([^\\]]+)\\]" in
let get_substring =
R.get_substring (R.exec ~rex:extract_article_title (Utf8.lexeme lexbuf))
in
let title = get_substring 2 in
let get_new_lines = R.regexp "\n" in
let new_lines_count =
try Array.length (R.extract ~rex:get_new_lines (Utf8.lexeme lexbuf)) with Not_found -> 0
in
(* the -1 is here to compensate for Sedlex's automatic newline detection around token *)
for _i = 1 to new_lines_count - 1 do
new_line lexbuf
done;
let precedence = calc_precedence (get_substring 1) in
LAW_ARTICLE (title, None, None, precedence)
| Plus (Compl ('/' | '#' | '`' | '>')) -> LAW_TEXT (Utf8.lexeme lexbuf)
| Plus '#', Star white_space, Plus (Compl '\n'), Star white_space, '\n' -> get_law_heading lexbuf
| Plus (Compl ('#' | '`' | '>')) -> LAW_TEXT (Utf8.lexeme lexbuf)
| _ -> L.raise_lexer_error (Pos.from_lpos prev_pos) prev_lexeme
(** Entry point of the lexer, distributes to {!val: lex_code} or {!val: lex_law} depending of {!val:

View File

@ -415,28 +415,14 @@ let process_code_block (ctxt : context) (block : Ast.code_block)
(process_item : context -> Ast.code_item Pos.marked -> context) : context =
List.fold_left (fun ctxt decl -> process_item ctxt decl) ctxt block
(** Process a law article item, only considering the code blocks *)
let process_law_article_item (ctxt : context) (item : Ast.law_article_item)
(process_item : context -> Ast.code_item Pos.marked -> context) : context =
match item with CodeBlock (block, _) -> process_code_block ctxt block process_item | _ -> ctxt
(** Process a law structure, only considering the code blocks *)
let rec process_law_structure (ctxt : context) (s : Ast.law_structure)
(process_item : context -> Ast.code_item Pos.marked -> context) : context =
match s with
| Ast.LawHeading (_, children) ->
List.fold_left (fun ctxt child -> process_law_structure ctxt child process_item) ctxt children
| Ast.LawArticle (_, children) ->
List.fold_left
(fun ctxt child -> process_law_article_item ctxt child process_item)
ctxt children
| Ast.MetadataBlock (b, c) -> process_law_article_item ctxt (Ast.CodeBlock (b, c)) process_item
| Ast.IntermediateText _ | Ast.LawInclude _ -> ctxt
(** Process a program item, only considering the code blocks *)
let process_program_item (ctxt : context) (item : Ast.program_item)
(process_item : context -> Ast.code_item Pos.marked -> context) : context =
match item with Ast.LawStructure s -> process_law_structure ctxt s process_item
| Ast.CodeBlock (block, _, _) -> process_code_block ctxt block process_item
| Ast.LawInclude _ | Ast.LawText _ -> ctxt
(** {1 Scope uses pass} *)
@ -647,17 +633,17 @@ let form_context (prgm : Ast.program) : context =
in
let ctxt =
List.fold_left
(fun ctxt item -> process_program_item ctxt item process_name_item)
(fun ctxt item -> process_law_structure ctxt item process_name_item)
empty_ctxt prgm.program_items
in
let ctxt =
List.fold_left
(fun ctxt item -> process_program_item ctxt item process_decl_item)
(fun ctxt item -> process_law_structure ctxt item process_decl_item)
ctxt prgm.program_items
in
let ctxt =
List.fold_left
(fun ctxt item -> process_program_item ctxt item process_use_item)
(fun ctxt item -> process_law_structure ctxt item process_use_item)
ctxt prgm.program_items
in
ctxt

File diff suppressed because it is too large Load Diff

View File

@ -18,15 +18,15 @@
%{
open Utils
%}
%}
%parameter<Localisation: sig
val builtins: (string * Ast.builtin_expression) list
end>
%type <Ast.source_file_or_master> source_file_or_master
%type <Ast.source_file> source_file
%start source_file_or_master
%start source_file
%%
@ -92,265 +92,265 @@ struct_or_enum_inject:
| None -> (EnumInject(None, enum, data), Pos.from_lpos $sloc)
| Some c -> (EnumInject(Some enum, c, data), Pos.from_lpos $sloc)
}
| c = constructor fields = struct_inject_content { (StructLit(c, fields), Pos.from_lpos $sloc) }
| c = constructor fields = struct_inject_content { (StructLit(c, fields), Pos.from_lpos $sloc) }
primitive_expression:
| e = small_expression { e }
| CARDINAL {
(Builtin Cardinal, Pos.from_lpos $sloc)
}
primitive_expression:
| e = small_expression { e }
| CARDINAL {
(Builtin Cardinal, Pos.from_lpos $sloc)
}
| e = struct_or_enum_inject {
e
}
| LSQUARE l = separated_list(SEMICOLON, expression) RSQUARE {
(ArrayLit l, Pos.from_lpos $sloc)
}
| e = struct_or_enum_inject {
e
}
| LSQUARE l = separated_list(SEMICOLON, expression) RSQUARE {
(ArrayLit l, Pos.from_lpos $sloc)
}
num_literal:
| d = INT_LITERAL { (Int d, Pos.from_lpos $sloc) }
| d = DECIMAL_LITERAL {
let (d1, d2) = d in
(Dec (d1, d2), Pos.from_lpos $sloc)
}
num_literal:
| d = INT_LITERAL { (Int d, Pos.from_lpos $sloc) }
| d = DECIMAL_LITERAL {
let (d1, d2) = d in
(Dec (d1, d2), Pos.from_lpos $sloc)
}
unit_literal:
| PERCENT { (Percent, Pos.from_lpos $sloc) }
| YEAR { (Year, Pos.from_lpos $sloc)}
| MONTH { (Month, Pos.from_lpos $sloc) }
| DAY { (Day, Pos.from_lpos $sloc) }
unit_literal:
| PERCENT { (Percent, Pos.from_lpos $sloc) }
| YEAR { (Year, Pos.from_lpos $sloc)}
| MONTH { (Month, Pos.from_lpos $sloc) }
| DAY { (Day, Pos.from_lpos $sloc) }
date_int:
| d = INT_LITERAL { (Runtime.integer_to_int d, Pos.from_lpos $sloc) }
date_int:
| d = INT_LITERAL { (Runtime.integer_to_int d, Pos.from_lpos $sloc) }
literal:
| l = num_literal u = option(unit_literal) {
(LNumber (l, u), Pos.from_lpos $sloc)
}
| money = MONEY_AMOUNT {
literal:
| l = num_literal u = option(unit_literal) {
(LNumber (l, u), Pos.from_lpos $sloc)
}
| money = MONEY_AMOUNT {
let (units, cents) = money in
(LMoneyAmount {
money_amount_units = units;
money_amount_cents = cents;
}, Pos.from_lpos $sloc)
}
| VERTICAL y = date_int MINUS m = date_int MINUS d = date_int VERTICAL {
(LDate {
literal_date_year = y;
literal_date_month = m;
literal_date_day = d;
}
| VERTICAL y = date_int MINUS m = date_int MINUS d = date_int VERTICAL {
(LDate {
literal_date_year = y;
literal_date_month = m;
literal_date_day = d;
}, Pos.from_lpos $sloc)
}
| TRUE { (LBool true, Pos.from_lpos $sloc) }
| FALSE { (LBool false, Pos.from_lpos $sloc) }
}
| TRUE { (LBool true, Pos.from_lpos $sloc) }
| FALSE { (LBool false, Pos.from_lpos $sloc) }
compare_op:
| LESSER { (Lt KInt, Pos.from_lpos $sloc) }
| LESSER_EQUAL { (Lte KInt, Pos.from_lpos $sloc) }
| GREATER { (Gt KInt, Pos.from_lpos $sloc) }
| GREATER_EQUAL { (Gte KInt, Pos.from_lpos $sloc) }
| LESSER_DEC { (Lt KDec, Pos.from_lpos $sloc) }
| LESSER_EQUAL_DEC { (Lte KDec, Pos.from_lpos $sloc) }
| GREATER_DEC { (Gt KDec, Pos.from_lpos $sloc) }
| GREATER_EQUAL_DEC { (Gte KDec, Pos.from_lpos $sloc) }
| LESSER_MONEY { (Lt KMoney, Pos.from_lpos $sloc) }
| LESSER_EQUAL_MONEY { (Lte KMoney, Pos.from_lpos $sloc) }
| GREATER_MONEY { (Gt KMoney, Pos.from_lpos $sloc) }
| GREATER_EQUAL_MONEY { (Gte KMoney, Pos.from_lpos $sloc) }
| LESSER_DATE { (Lt KDate, Pos.from_lpos $sloc) }
| LESSER_EQUAL_DATE { (Lte KDate, Pos.from_lpos $sloc) }
| GREATER_DATE { (Gt KDate, Pos.from_lpos $sloc) }
| GREATER_EQUAL_DATE { (Gte KDate, Pos.from_lpos $sloc) }
| LESSER_DURATION { (Lt KDuration, Pos.from_lpos $sloc) }
| LESSER_EQUAL_DURATION { (Lte KDuration, Pos.from_lpos $sloc) }
| GREATER_DURATION { (Gt KDuration, Pos.from_lpos $sloc) }
| GREATER_EQUAL_DURATION { (Gte KDuration, Pos.from_lpos $sloc) }
| EQUAL { (Eq, Pos.from_lpos $sloc) }
| NOT_EQUAL { (Neq, Pos.from_lpos $sloc) }
compare_op:
| LESSER { (Lt KInt, Pos.from_lpos $sloc) }
| LESSER_EQUAL { (Lte KInt, Pos.from_lpos $sloc) }
| GREATER { (Gt KInt, Pos.from_lpos $sloc) }
| GREATER_EQUAL { (Gte KInt, Pos.from_lpos $sloc) }
| LESSER_DEC { (Lt KDec, Pos.from_lpos $sloc) }
| LESSER_EQUAL_DEC { (Lte KDec, Pos.from_lpos $sloc) }
| GREATER_DEC { (Gt KDec, Pos.from_lpos $sloc) }
| GREATER_EQUAL_DEC { (Gte KDec, Pos.from_lpos $sloc) }
| LESSER_MONEY { (Lt KMoney, Pos.from_lpos $sloc) }
| LESSER_EQUAL_MONEY { (Lte KMoney, Pos.from_lpos $sloc) }
| GREATER_MONEY { (Gt KMoney, Pos.from_lpos $sloc) }
| GREATER_EQUAL_MONEY { (Gte KMoney, Pos.from_lpos $sloc) }
| LESSER_DATE { (Lt KDate, Pos.from_lpos $sloc) }
| LESSER_EQUAL_DATE { (Lte KDate, Pos.from_lpos $sloc) }
| GREATER_DATE { (Gt KDate, Pos.from_lpos $sloc) }
| GREATER_EQUAL_DATE { (Gte KDate, Pos.from_lpos $sloc) }
| LESSER_DURATION { (Lt KDuration, Pos.from_lpos $sloc) }
| LESSER_EQUAL_DURATION { (Lte KDuration, Pos.from_lpos $sloc) }
| GREATER_DURATION { (Gt KDuration, Pos.from_lpos $sloc) }
| GREATER_EQUAL_DURATION { (Gte KDuration, Pos.from_lpos $sloc) }
| EQUAL { (Eq, Pos.from_lpos $sloc) }
| NOT_EQUAL { (Neq, Pos.from_lpos $sloc) }
aggregate_func:
| CONTENT MAXIMUM t = typ_base INIT init = primitive_expression {
(Aggregate (AggregateArgExtremum (true, Pos.unmark t, init)), Pos.from_lpos $sloc)
}
| CONTENT MINIMUM t = typ_base INIT init = primitive_expression {
(Aggregate (AggregateArgExtremum (false, Pos.unmark t, init)), Pos.from_lpos $sloc)
}
| MAXIMUM t = typ_base INIT init = primitive_expression {
(Aggregate (AggregateExtremum (true, Pos.unmark t, init)), Pos.from_lpos $sloc)
}
| MINIMUM t = typ_base INIT init = primitive_expression {
(Aggregate (AggregateExtremum (false, Pos.unmark t, init)), Pos.from_lpos $sloc)
}
| SUM t = typ_base { (Aggregate (AggregateSum (Pos.unmark t)), Pos.from_lpos $sloc) }
| CARDINAL { (Aggregate AggregateCount, Pos.from_lpos $sloc) }
| FILTER { (Filter, Pos.from_lpos $sloc ) }
| MAP { (Map, Pos.from_lpos $sloc) }
aggregate_func:
| CONTENT MAXIMUM t = typ_base INIT init = primitive_expression {
(Aggregate (AggregateArgExtremum (true, Pos.unmark t, init)), Pos.from_lpos $sloc)
}
| CONTENT MINIMUM t = typ_base INIT init = primitive_expression {
(Aggregate (AggregateArgExtremum (false, Pos.unmark t, init)), Pos.from_lpos $sloc)
}
| MAXIMUM t = typ_base INIT init = primitive_expression {
(Aggregate (AggregateExtremum (true, Pos.unmark t, init)), Pos.from_lpos $sloc)
}
| MINIMUM t = typ_base INIT init = primitive_expression {
(Aggregate (AggregateExtremum (false, Pos.unmark t, init)), Pos.from_lpos $sloc)
}
| SUM t = typ_base { (Aggregate (AggregateSum (Pos.unmark t)), Pos.from_lpos $sloc) }
| CARDINAL { (Aggregate AggregateCount, Pos.from_lpos $sloc) }
| FILTER { (Filter, Pos.from_lpos $sloc ) }
| MAP { (Map, Pos.from_lpos $sloc) }
aggregate:
| func = aggregate_func FOR i = ident IN e1 = primitive_expression
aggregate:
| func = aggregate_func FOR i = ident IN e1 = primitive_expression
OF e2 = base_expression {
(CollectionOp (func, i, e1, e2), Pos.from_lpos $sloc)
}
(CollectionOp (func, i, e1, e2), Pos.from_lpos $sloc)
}
base_expression:
| e = primitive_expression { e }
| ag = aggregate { ag }
| e1 = primitive_expression OF e2 = base_expression {
(FunCall (e1, e2), Pos.from_lpos $sloc)
}
| e = primitive_expression WITH c = constructor_binding {
(TestMatchCase (e, (c, Pos.from_lpos $sloc)), Pos.from_lpos $sloc)
}
| e1 = primitive_expression IN e2 = base_expression {
(MemCollection (e1, e2), Pos.from_lpos $sloc)
}
base_expression:
| e = primitive_expression { e }
| ag = aggregate { ag }
| e1 = primitive_expression OF e2 = base_expression {
(FunCall (e1, e2), Pos.from_lpos $sloc)
}
| e = primitive_expression WITH c = constructor_binding {
(TestMatchCase (e, (c, Pos.from_lpos $sloc)), Pos.from_lpos $sloc)
}
| e1 = primitive_expression IN e2 = base_expression {
(MemCollection (e1, e2), Pos.from_lpos $sloc)
}
mult_op:
| MULT { (Mult KInt, Pos.from_lpos $sloc) }
| DIV { (Div KInt, Pos.from_lpos $sloc) }
| MULTDEC { (Mult KDec, Pos.from_lpos $sloc) }
| DIVDEC { (Div KDec, Pos.from_lpos $sloc) }
| MULTMONEY { (Mult KMoney, Pos.from_lpos $sloc) }
| DIVMONEY { (Div KMoney, Pos.from_lpos $sloc) }
mult_op:
| MULT { (Mult KInt, Pos.from_lpos $sloc) }
| DIV { (Div KInt, Pos.from_lpos $sloc) }
| MULTDEC { (Mult KDec, Pos.from_lpos $sloc) }
| DIVDEC { (Div KDec, Pos.from_lpos $sloc) }
| MULTMONEY { (Mult KMoney, Pos.from_lpos $sloc) }
| DIVMONEY { (Div KMoney, Pos.from_lpos $sloc) }
mult_expression:
| e = base_expression { e }
| e1 = base_expression binop = mult_op e2 = mult_expression {
(Binop (binop, e1, e2), Pos.from_lpos $sloc)
}
mult_expression:
| e = base_expression { e }
| e1 = base_expression binop = mult_op e2 = mult_expression {
(Binop (binop, e1, e2), Pos.from_lpos $sloc)
}
sum_op:
| PLUSDURATION { (Add KDuration, Pos.from_lpos $sloc) }
| MINUSDURATION { (Sub KDuration, Pos.from_lpos $sloc) }
| PLUSDATE { (Add KDate, Pos.from_lpos $sloc) }
| MINUSDATE { (Sub KDate, Pos.from_lpos $sloc) }
| PLUSMONEY { (Add KMoney, Pos.from_lpos $sloc) }
| MINUSMONEY { (Sub KMoney, Pos.from_lpos $sloc) }
| PLUSDEC { (Add KDec, Pos.from_lpos $sloc) }
| MINUSDEC { (Sub KDec, Pos.from_lpos $sloc) }
| PLUS { (Add KInt, Pos.from_lpos $sloc) }
| MINUS { (Sub KInt, Pos.from_lpos $sloc) }
sum_op:
| PLUSDURATION { (Add KDuration, Pos.from_lpos $sloc) }
| MINUSDURATION { (Sub KDuration, Pos.from_lpos $sloc) }
| PLUSDATE { (Add KDate, Pos.from_lpos $sloc) }
| MINUSDATE { (Sub KDate, Pos.from_lpos $sloc) }
| PLUSMONEY { (Add KMoney, Pos.from_lpos $sloc) }
| MINUSMONEY { (Sub KMoney, Pos.from_lpos $sloc) }
| PLUSDEC { (Add KDec, Pos.from_lpos $sloc) }
| MINUSDEC { (Sub KDec, Pos.from_lpos $sloc) }
| PLUS { (Add KInt, Pos.from_lpos $sloc) }
| MINUS { (Sub KInt, Pos.from_lpos $sloc) }
sum_unop:
| MINUS { (Minus KInt, Pos.from_lpos $sloc) }
| MINUSDEC { (Minus KDec, Pos.from_lpos $sloc) }
| MINUSMONEY { (Minus KMoney, Pos.from_lpos $sloc) }
| MINUSDURATION { (Minus KDuration, Pos.from_lpos $sloc) }
sum_unop:
| MINUS { (Minus KInt, Pos.from_lpos $sloc) }
| MINUSDEC { (Minus KDec, Pos.from_lpos $sloc) }
| MINUSMONEY { (Minus KMoney, Pos.from_lpos $sloc) }
| MINUSDURATION { (Minus KDuration, Pos.from_lpos $sloc) }
sum_expression:
| e = mult_expression { e }
| e1 = mult_expression binop = sum_op e2 = sum_expression {
(Binop (binop, e1, e2), Pos.from_lpos $sloc)
}
| unop = sum_unop e = sum_expression { (Unop (unop, e), Pos.from_lpos $sloc) }
sum_expression:
| e = mult_expression { e }
| e1 = mult_expression binop = sum_op e2 = sum_expression {
(Binop (binop, e1, e2), Pos.from_lpos $sloc)
}
| unop = sum_unop e = sum_expression { (Unop (unop, e), Pos.from_lpos $sloc) }
logical_op:
| AND { (And, Pos.from_lpos $sloc) }
| OR { (Or, Pos.from_lpos $sloc) }
| XOR { (Xor, Pos.from_lpos $sloc) }
logical_op:
| AND { (And, Pos.from_lpos $sloc) }
| OR { (Or, Pos.from_lpos $sloc) }
| XOR { (Xor, Pos.from_lpos $sloc) }
logical_unop:
| NOT { (Not, Pos.from_lpos $sloc) }
logical_unop:
| NOT { (Not, Pos.from_lpos $sloc) }
compare_expression:
| e = sum_expression { e }
| e1 = sum_expression binop = compare_op e2 = compare_expression {
(Binop (binop, e1, e2), Pos.from_lpos $sloc)
}
compare_expression:
| e = sum_expression { e }
| e1 = sum_expression binop = compare_op e2 = compare_expression {
(Binop (binop, e1, e2), Pos.from_lpos $sloc)
}
logical_expression:
| e = compare_expression { e }
| unop = logical_unop e = compare_expression { (Unop (unop, e), Pos.from_lpos $sloc) }
| e1 = compare_expression binop = logical_op e2 = logical_expression {
(Binop (binop, e1, e2), Pos.from_lpos $sloc)
}
logical_expression:
| e = compare_expression { e }
| unop = logical_unop e = compare_expression { (Unop (unop, e), Pos.from_lpos $sloc) }
| e1 = compare_expression binop = logical_op e2 = logical_expression {
(Binop (binop, e1, e2), Pos.from_lpos $sloc)
}
maybe_qualified_constructor:
| c_or_path = constructor c = option(preceded(DOT, constructor)) {
match c with
maybe_qualified_constructor:
| c_or_path = constructor c = option(preceded(DOT, constructor)) {
match c with
| None -> (None, c_or_path)
| Some c -> (Some c_or_path, c)
}
}
optional_binding:
| { ([], None)}
| OF i = ident {([], Some i)}
| OF c = maybe_qualified_constructor cs_and_i = constructor_binding {
optional_binding:
| { ([], None)}
| OF i = ident {([], Some i)}
| OF c = maybe_qualified_constructor cs_and_i = constructor_binding {
let (cs, i) = cs_and_i in
(c::cs, i)
}
}
constructor_binding:
| c = maybe_qualified_constructor cs_and_i = optional_binding {
let (cs, i) = cs_and_i in
(c::cs, i)
}
constructor_binding:
| c = maybe_qualified_constructor cs_and_i = optional_binding {
let (cs, i) = cs_and_i in
(c::cs, i)
}
match_arm:
| pat = constructor_binding COLON e = logical_expression {
({
(* DM 14/04/2020 : I can't have the $sloc in constructor_binding... *)
match_case_pattern = (pat, Pos.from_lpos $sloc);
match_case_expr = e;
match_arm:
| pat = constructor_binding COLON e = logical_expression {
({
(* DM 14/04/2020 : I can't have the $sloc in constructor_binding... *)
match_case_pattern = (pat, Pos.from_lpos $sloc);
match_case_expr = e;
}, Pos.from_lpos $sloc)
}
}
match_arms:
| ALT a = match_arm arms = match_arms {
let (arms, _) = arms in
(a::arms, Pos.from_lpos $sloc)
}
| { ([], Pos.from_lpos $sloc)}
match_arms:
| ALT a = match_arm arms = match_arms {
let (arms, _) = arms in
(a::arms, Pos.from_lpos $sloc)
}
| { ([], Pos.from_lpos $sloc)}
for_all_marked:
| FOR ALL { Pos.from_lpos $sloc }
for_all_marked:
| FOR ALL { Pos.from_lpos $sloc }
exists_marked:
| EXISTS { Pos.from_lpos $sloc }
exists_marked:
| EXISTS { Pos.from_lpos $sloc }
forall_prefix:
| pos = for_all_marked i = ident IN e = primitive_expression WE_HAVE {
(pos, i, e)
}
exists_prefix:
| pos = exists_marked i = ident IN e = primitive_expression SUCH THAT {
(pos, i, e)
}
forall_prefix:
| pos = for_all_marked i = ident IN e = primitive_expression WE_HAVE {
(pos, i, e)
}
expression:
| i_in_e1 = exists_prefix e2 = expression {
let (pos, i,e1) = i_in_e1 in
(CollectionOp ((Exists, pos), i, e1, e2), Pos.from_lpos $sloc)
}
| i_in_e1 = forall_prefix e2 = expression {
let (pos, i,e1) = i_in_e1 in
(CollectionOp ((Forall, pos), i, e1, e2), Pos.from_lpos $sloc)
}
| MATCH e = primitive_expression WITH arms = match_arms {
(MatchWith (e, arms), Pos.from_lpos $sloc)
}
| IF e1 = expression THEN e2 = expression ELSE e3 = base_expression {
(IfThenElse (e1, e2, e3), Pos.from_lpos $sloc)
}
| e = logical_expression { e }
exists_prefix:
| pos = exists_marked i = ident IN e = primitive_expression SUCH THAT {
(pos, i, e)
}
condition:
| UNDER_CONDITION e = expression { e }
expression:
| i_in_e1 = exists_prefix e2 = expression {
let (pos, i,e1) = i_in_e1 in
(CollectionOp ((Exists, pos), i, e1, e2), Pos.from_lpos $sloc)
}
| i_in_e1 = forall_prefix e2 = expression {
let (pos, i,e1) = i_in_e1 in
(CollectionOp ((Forall, pos), i, e1, e2), Pos.from_lpos $sloc)
}
| MATCH e = primitive_expression WITH arms = match_arms {
(MatchWith (e, arms), Pos.from_lpos $sloc)
}
| IF e1 = expression THEN e2 = expression ELSE e3 = base_expression {
(IfThenElse (e1, e2, e3), Pos.from_lpos $sloc)
}
| e = logical_expression { e }
condition_consequence:
| cond = condition CONSEQUENCE { cond }
condition:
| UNDER_CONDITION e = expression { e }
rule_expr:
| i = qident p = option(definition_parameters) { (i, p) }
condition_consequence:
| cond = condition CONSEQUENCE { cond }
rule_consequence:
| flag = option(NOT) FILLED {
rule_expr:
| i = qident p = option(definition_parameters) { (i, p) }
rule_consequence:
| flag = option(NOT) FILLED {
let b = match flag with Some _ -> false | None -> true in
(b, Pos.from_lpos $sloc)
}
}
rule:
| label = option(label)
rule:
| label = option(label)
except = option(exception_to)
RULE
name_and_param = rule_expr cond = option(condition_consequence)
@ -366,20 +366,21 @@ struct_or_enum_inject:
rule_name = name;
rule_consequence = cons;
}, $sloc)
}
}
definition_parameters:
| OF i = ident { i }
definition_parameters:
| OF i = ident { i }
label:
| LABEL i = ident { i }
label:
| LABEL i = ident { i }
exception_to:
| EXCEPTION i = option(ident) {
match i with | None -> UnlabeledException | Some x -> ExceptionToLabel x }
exception_to:
| EXCEPTION i = option(ident) {
match i with | None -> UnlabeledException | Some x -> ExceptionToLabel x
}
definition:
| label = option(label)
definition:
| label = option(label)
except = option(exception_to)
DEFINITION
name = qident param = option(definition_parameters)
@ -392,81 +393,81 @@ struct_or_enum_inject:
definition_parameter = param;
definition_condition = cond;
definition_expr = e;
}, $sloc)
}
}, $sloc)
}
variation_type:
| INCREASING { (Increasing, Pos.from_lpos $sloc) }
| DECREASING { (Decreasing, Pos.from_lpos $sloc) }
variation_type:
| INCREASING { (Increasing, Pos.from_lpos $sloc) }
| DECREASING { (Decreasing, Pos.from_lpos $sloc) }
assertion_base:
| e = expression { let (e, _) = e in (e, Pos.from_lpos $sloc) }
assertion_base:
| e = expression { let (e, _) = e in (e, Pos.from_lpos $sloc) }
assertion:
| cond = option(condition_consequence) base = assertion_base {
(Assertion {
assertion_condition = cond;
assertion:
| cond = option(condition_consequence) base = assertion_base {
(Assertion {
assertion_condition = cond;
assertion_content = base;
})
}
| FIXED q = qident BY i = ident { MetaAssertion (FixedBy (q, i)) }
| VARIES q = qident WITH_V e = base_expression t = option(variation_type) {
MetaAssertion (VariesWith (q, e, t))
}
}
| FIXED q = qident BY i = ident { MetaAssertion (FixedBy (q, i)) }
| VARIES q = qident WITH_V e = base_expression t = option(variation_type) {
MetaAssertion (VariesWith (q, e, t))
}
scope_item:
| r = rule {
let (r, _) = r in (Rule r, Pos.from_lpos $sloc)
}
| d = definition {
let (d, _) = d in (Definition d, Pos.from_lpos $sloc)
}
| ASSERTION contents = assertion {
(contents, Pos.from_lpos $sloc)
}
scope_item:
| r = rule {
let (r, _) = r in (Rule r, Pos.from_lpos $sloc)
}
| d = definition {
let (d, _) = d in (Definition d, Pos.from_lpos $sloc)
}
| ASSERTION contents = assertion {
(contents, Pos.from_lpos $sloc)
}
ident:
| i = IDENT {
if List.mem_assoc i Localisation.builtins then
Errors.raise_spanned_error
(Printf.sprintf "Reserved builtin name")
(Pos.from_lpos $sloc)
else (i, Pos.from_lpos $sloc)
}
ident:
| i = IDENT {
if List.mem_assoc i Localisation.builtins then
Errors.raise_spanned_error
(Printf.sprintf "Reserved builtin name")
(Pos.from_lpos $sloc)
else (i, Pos.from_lpos $sloc)
}
condition_pos:
| CONDITION { Pos.from_lpos $sloc }
condition_pos:
| CONDITION { Pos.from_lpos $sloc }
struct_scope_base:
| DATA i= ident CONTENT t = typ {
let t, pos = t in
(i, (Data t, pos))
}
| pos = condition_pos i = ident {
(i, (Condition, pos))
}
struct_scope_base:
| DATA i= ident CONTENT t = typ {
let t, pos = t in
(i, (Data t, pos))
}
| pos = condition_pos i = ident {
(i, (Condition, pos))
}
struct_scope_func:
| DEPENDS t = typ { t }
struct_scope_func:
| DEPENDS t = typ { t }
struct_scope:
| name_and_typ = struct_scope_base func_typ = option(struct_scope_func) {
let (name, typ) = name_and_typ in
let (typ, typ_pos) = typ in
({
struct_decl_field_name = name;
struct_scope:
| name_and_typ = struct_scope_base func_typ = option(struct_scope_func) {
let (name, typ) = name_and_typ in
let (typ, typ_pos) = typ in
({
struct_decl_field_name = name;
struct_decl_field_typ = match func_typ with
| None -> (Base typ, typ_pos)
| Some (arg_typ, arg_pos) -> (Func {
arg_typ = (Data arg_typ, arg_pos);
return_typ = (typ, typ_pos);
}, Pos.from_lpos $sloc) ;
}, Pos.from_lpos $sloc)
}
}, Pos.from_lpos $sloc) ;
}, Pos.from_lpos $sloc)
}
scope_decl_item:
| CONTEXT i = ident CONTENT t = typ func_typ = option(struct_scope_func) { (ContextData ({
scope_decl_context_item_name = i;
scope_decl_item:
| CONTEXT i = ident CONTENT t = typ func_typ = option(struct_scope_func) { (ContextData ({
scope_decl_context_item_name = i;
scope_decl_context_item_typ =
let (typ, typ_pos) = t in
match func_typ with
@ -474,153 +475,114 @@ struct_or_enum_inject:
| Some (arg_typ, arg_pos) -> (Func {
arg_typ = (Data arg_typ, arg_pos);
return_typ = (Data typ, typ_pos);
}, Pos.from_lpos $sloc);
}), Pos.from_lpos $sloc) }
| CONTEXT i = ident SCOPE c = constructor {
(ContextScope({
scope_decl_context_scope_name = i;
scope_decl_context_scope_sub_scope = c;
}), Pos.from_lpos $sloc)
}
| CONTEXT i = ident _condition = CONDITION func_typ = option(struct_scope_func) { (ContextData ({
scope_decl_context_item_name = i;
scope_decl_context_item_typ =
match func_typ with
| None -> (Base (Condition), Pos.from_lpos $loc(_condition))
| Some (arg_typ, arg_pos) -> (Func {
arg_typ = (Data arg_typ, arg_pos);
return_typ = (Condition, Pos.from_lpos $loc(_condition));
}, Pos.from_lpos $sloc);
}), Pos.from_lpos $sloc) }
}), Pos.from_lpos $sloc)
}
| CONTEXT i = ident SCOPE c = constructor {
(ContextScope({
scope_decl_context_scope_name = i;
scope_decl_context_scope_sub_scope = c;
}), Pos.from_lpos $sloc)
}
| CONTEXT i = ident _condition = CONDITION func_typ = option(struct_scope_func) {
(ContextData ({
scope_decl_context_item_name = i;
scope_decl_context_item_typ =
match func_typ with
| None -> (Base (Condition), Pos.from_lpos $loc(_condition))
| Some (arg_typ, arg_pos) -> (Func {
arg_typ = (Data arg_typ, arg_pos);
return_typ = (Condition, Pos.from_lpos $loc(_condition));
}, Pos.from_lpos $sloc);
}), Pos.from_lpos $sloc
)
}
enum_decl_line_payload:
| CONTENT t = typ { let (t, t_pos) = t in (Base (Data t), t_pos) }
enum_decl_line_payload:
| CONTENT t = typ { let (t, t_pos) = t in (Base (Data t), t_pos) }
enum_decl_line:
| ALT c = constructor t = option(enum_decl_line_payload) { ({
enum_decl_case_name = c;
enum_decl_line:
| ALT c = constructor t = option(enum_decl_line_payload) {
({
enum_decl_case_name = c;
enum_decl_case_typ = t;
}, Pos.from_lpos $sloc) }
}, Pos.from_lpos $sloc)
}
constructor:
| c = CONSTRUCTOR { (c, Pos.from_lpos $sloc) }
constructor:
| c = CONSTRUCTOR { (c, Pos.from_lpos $sloc) }
scope_use_condition:
| UNDER_CONDITION e = expression { e }
scope_use_condition:
| UNDER_CONDITION e = expression { e }
code_item:
| SCOPE c = constructor e = option(scope_use_condition) COLON items = nonempty_list(scope_item) {
(ScopeUse {
scope_use_name = c;
code_item:
| SCOPE c = constructor e = option(scope_use_condition) COLON items = nonempty_list(scope_item) {
(ScopeUse {
scope_use_name = c;
scope_use_condition = e;
scope_use_items = items;
}, Pos.from_lpos $sloc)
}
| DECLARATION STRUCT c = constructor COLON scopes = list(struct_scope) {
(StructDecl {
struct_decl_name = c;
}, Pos.from_lpos $sloc)
}
| DECLARATION STRUCT c = constructor COLON scopes = list(struct_scope) {
(StructDecl {
struct_decl_name = c;
struct_decl_fields = scopes;
}, Pos.from_lpos $sloc)
}
| DECLARATION SCOPE c = constructor COLON context = nonempty_list(scope_decl_item) {
(ScopeDecl {
scope_decl_name = c;
scope_decl_context = context;
}, Pos.from_lpos $sloc)
}
| DECLARATION ENUM c = constructor COLON cases = nonempty_list(enum_decl_line) {
(EnumDecl {
enum_decl_name = c;
}, Pos.from_lpos $sloc)
}
| DECLARATION SCOPE c = constructor COLON context = nonempty_list(scope_decl_item) {
(ScopeDecl {
scope_decl_name = c;
scope_decl_context = context;
}, Pos.from_lpos $sloc)
}
| DECLARATION ENUM c = constructor COLON cases = nonempty_list(enum_decl_line) {
(EnumDecl {
enum_decl_name = c;
enum_decl_cases = cases;
}, Pos.from_lpos $sloc)
}
}, Pos.from_lpos $sloc)
}
code:
| code = list(code_item) { (code, Pos.from_lpos $sloc) }
code:
| code = list(code_item) { (code, Pos.from_lpos $sloc) }
metadata_block:
| BEGIN_CODE option(law_text) code_and_pos = code text = END_CODE option(law_text) END_METADATA {
let (code, pos) = code_and_pos in
metadata_block:
| BEGIN_METADATA option(law_text) BEGIN_CODE code_and_pos = code text = END_CODE option(law_text) END_METADATA {
let (code, pos) = code_and_pos in
(code, (text, pos))
}
}
law_article_item:
| text = law_text { LawText text }
| BEGIN_CODE code_and_pos = code text = END_CODE {
let (code, pos) = code_and_pos in
CodeBlock (code, (text, pos))
}
law_article:
| title = LAW_ARTICLE {
let (title, id, exp_date, precedence) = title in {
law_article_name = (title, Pos.from_lpos $sloc);
law_article_id = id;
law_article_expiration_date = exp_date;
law_article_precedence = precedence;
}
}
law_heading:
| heading = LAW_HEADING { let (title, precedence) = heading in {
law_heading_name = title;
law_heading:
| title = LAW_HEADING {
let (title, id, exp_date, precedence) = title in {
law_heading_name = (title, Pos.from_lpos $sloc);
law_heading_id = id;
law_heading_expiration_date = exp_date;
law_heading_precedence = precedence;
}
}
}
}
law_articles_items:
| hd = law_article_item tl = law_articles_items{ hd::tl }
| { [] }
law_text:
| text = LAW_TEXT { String.trim text }
law_text:
| text = LAW_TEXT { String.trim text }
law_intermediate_text:
| text = law_text { LawStructure (IntermediateText text) }
source_file_item:
| text = law_text { LawText text }
| BEGIN_CODE code_and_pos = code text = END_CODE {
let (code, pos) = code_and_pos in
CodeBlock (code, (text, pos), false)
}
| heading = law_heading {
LawHeading (heading, [])
}
| code = metadata_block {
let (code, source_repr) = code in
CodeBlock (code, source_repr, true)
}
| includ = LAW_INCLUDE {
LawInclude includ
}
source_file_article:
| article = law_article items = law_articles_items {
LawStructure (LawArticle (article, items))
}
source_file_item:
| heading = law_heading {
LawStructure (LawHeading (heading, []))
}
| BEGIN_METADATA option(law_text) code = metadata_block {
let (code, source_repr) = code in
LawStructure (MetadataBlock (code, source_repr))
}
| includ = LAW_INCLUDE {
LawStructure (LawInclude includ)
}
source_file_after_text:
| i = source_file_article f = source_file_after_text {
i::f
}
| i = source_file_item l = list(law_intermediate_text) f = source_file_after_text {
i::l@f
}
| EOF { [] }
source_file:
| l = list(law_intermediate_text) f = source_file_after_text { l@f }
master_file_include:
| includ = LAW_INCLUDE {
match includ with
| CatalaFile (file, _) -> (file, Pos.from_lpos $sloc)
| _ -> Errors.raise_spanned_error
(Printf.sprintf "Include in master file must be .catala file!")
(Pos.from_lpos $sloc)
}
master_file_includes:
| i = master_file_include option(law_text) is = master_file_includes { i::is }
| EOF { [] }
source_file_or_master:
| MASTER_FILE option(law_text) is = master_file_includes { MasterFile is }
| f = source_file { SourceFile (f) }
source_file:
| hd = source_file_item tl = source_file { hd:: tl }
| EOF { [] }

View File

@ -53,7 +53,7 @@ let levenshtein_distance (s : string) (t : string) : int =
(** After parsing, heading structure is completely flat because of the [source_file_item] rule. We
need to tree-i-fy the flat structure, by looking at the precedence of the law headings. *)
let rec law_struct_list_to_tree (f : Ast.program_item list) : Ast.program_item list =
let rec law_struct_list_to_tree (f : Ast.law_structure list) : Ast.law_structure list =
match f with
| [] -> []
| [ item ] -> [ item ]
@ -63,28 +63,28 @@ let rec law_struct_list_to_tree (f : Ast.program_item list) : Ast.program_item l
| [] -> assert false (* there should be at least one rest element *)
| rest_head :: rest_tail -> (
match first_item with
| LawStructure (LawArticle _ | MetadataBlock _ | IntermediateText _ | LawInclude _) ->
(* if an article or an include is just before a new heading or a new article, then we
don't merge it with what comes next *)
| CodeBlock _ | LawText _ | LawInclude _ ->
(* if an article or an include is just before a new heading , then we don't merge it
with what comes next *)
first_item :: rest_head :: rest_tail
| LawStructure (LawHeading (heading, _)) ->
| LawHeading (heading, _) ->
(* here we have encountered a heading, which is going to "gobble" everything in the
[rest_tree] until it finds a heading of at least the same precedence *)
let rec split_rest_tree (rest_tree : Ast.program_item list) :
Ast.law_structure list * Ast.program_item list =
let rec split_rest_tree (rest_tree : Ast.law_structure list) :
Ast.law_structure list * Ast.law_structure list =
match rest_tree with
| [] -> ([], [])
| LawStructure (LawHeading (new_heading, _)) :: _
| LawHeading (new_heading, _) :: _
when new_heading.law_heading_precedence <= heading.law_heading_precedence ->
(* we stop gobbling *)
([], rest_tree)
| LawStructure first :: after ->
| first :: after ->
(* we continue gobbling *)
let after_gobbled, after_out = split_rest_tree after in
(first :: after_gobbled, after_out)
in
let gobbled, rest_out = split_rest_tree rest_tree in
LawStructure (LawHeading (heading, gobbled)) :: rest_out))
LawHeading (heading, gobbled) :: rest_out))
(** Style with which to display syntax hints in the terminal output *)
let syntax_hints_style = [ ANSITerminal.yellow ]
@ -190,7 +190,7 @@ module ParserAux (LocalisedLexer : Lexer.LocalisedLexer) = struct
let rec loop (next_token : unit -> Tokens.token * Lexing.position * Lexing.position)
(token_list : (string * Tokens.token) list) (lexbuf : lexbuf)
(last_input_needed : 'semantic_value I.env option) (checkpoint : 'semantic_value I.checkpoint)
: Ast.source_file_or_master =
: Ast.source_file =
match checkpoint with
| I.InputNeeded env ->
let token = next_token () in
@ -210,7 +210,7 @@ module ParserAux (LocalisedLexer : Lexer.LocalisedLexer) = struct
let sedlex_with_menhir (lexer' : lexbuf -> Tokens.token)
(token_list : (string * Tokens.token) list)
(target_rule : Lexing.position -> 'semantic_value I.checkpoint) (lexbuf : lexbuf) :
Ast.source_file_or_master =
Ast.source_file =
let lexer : unit -> Tokens.token * Lexing.position * Lexing.position =
with_tokenizer lexer' lexbuf
in
@ -218,9 +218,8 @@ module ParserAux (LocalisedLexer : Lexer.LocalisedLexer) = struct
with Sedlexing.MalFormed | Sedlexing.InvalidCodepoint _ ->
Lexer.raise_lexer_error (Pos.from_lpos (lexing_positions lexbuf)) (Utf8.lexeme lexbuf)
let commands_or_includes (lexbuf : lexbuf) : Ast.source_file_or_master =
sedlex_with_menhir LocalisedLexer.lexer LocalisedLexer.token_list
Incremental.source_file_or_master lexbuf
let commands_or_includes (lexbuf : lexbuf) : Ast.source_file =
sedlex_with_menhir LocalisedLexer.lexer LocalisedLexer.token_list Incremental.source_file lexbuf
end
module Parser_NonVerbose = ParserAux (Lexer)
@ -228,7 +227,7 @@ module Parser_En = ParserAux (Lexer_en)
module Parser_Fr = ParserAux (Lexer_fr)
module Parser_Pl = ParserAux (Lexer_pl)
let localised_parser : Cli.frontend_lang -> lexbuf -> Ast.source_file_or_master = function
let localised_parser : Cli.frontend_lang -> lexbuf -> Ast.source_file = function
| `NonVerbose -> Parser_NonVerbose.commands_or_includes
| `En -> Parser_En.commands_or_includes
| `Fr -> Parser_Fr.commands_or_includes
@ -253,48 +252,21 @@ let rec parse_source_file (source_file : Pos.input_file) (language : Cli.fronten
let source_file_name = match source_file with FileName s -> s | Contents _ -> "stdin" in
Sedlexing.set_filename lexbuf source_file_name;
Parse_utils.current_file := source_file_name;
let commands_or_includes = localised_parser language lexbuf in
let commands = localised_parser language lexbuf in
(match input with Some input -> close_in input | None -> ());
match commands_or_includes with
| Ast.SourceFile commands ->
let program = expand_includes source_file_name commands language in
{
program_items = program.Ast.program_items;
program_source_files = source_file_name :: program.Ast.program_source_files;
}
| Ast.MasterFile includes ->
let current_source_file_dirname = Filename.dirname source_file_name in
let includes =
List.map
(fun includ ->
(if current_source_file_dirname = "./" then "" else current_source_file_dirname ^ "/")
^ Pos.unmark includ)
includes
in
let new_program =
List.fold_left
(fun acc includ_file ->
let includ_program = parse_source_file (FileName includ_file) language in
{
Ast.program_source_files =
acc.Ast.program_source_files @ includ_program.program_source_files;
Ast.program_items = acc.Ast.program_items @ includ_program.program_items;
})
{ Ast.program_source_files = []; Ast.program_items = [] }
includes
in
{
program_items = new_program.Ast.program_items;
program_source_files = source_file_name :: new_program.program_source_files;
}
let program = expand_includes source_file_name commands language in
{
program_items = program.Ast.program_items;
program_source_files = source_file_name :: program.Ast.program_source_files;
}
(** Expands the include directives in a parsing result, thus parsing new source files *)
and expand_includes (source_file : string) (commands : Ast.program_item list)
and expand_includes (source_file : string) (commands : Ast.law_structure list)
(language : Cli.frontend_lang) : Ast.program =
List.fold_left
(fun acc command ->
match command with
| Ast.LawStructure (LawInclude (Ast.CatalaFile sub_source)) ->
| Ast.LawInclude (Ast.CatalaFile sub_source) ->
let source_dir = Filename.dirname source_file in
let sub_source = Filename.concat source_dir (Pos.unmark sub_source) in
let includ_program = parse_source_file (FileName sub_source) language in
@ -303,18 +275,13 @@ and expand_includes (source_file : string) (commands : Ast.program_item list)
acc.Ast.program_source_files @ includ_program.program_source_files;
Ast.program_items = acc.Ast.program_items @ includ_program.program_items;
}
| Ast.LawStructure (Ast.LawHeading (heading, commands')) ->
| Ast.LawHeading (heading, commands') ->
let { Ast.program_items = commands'; Ast.program_source_files = new_sources } =
expand_includes source_file (List.map (fun x -> Ast.LawStructure x) commands') language
expand_includes source_file commands' language
in
{
Ast.program_source_files = acc.Ast.program_source_files @ new_sources;
Ast.program_items =
acc.Ast.program_items
@ [
Ast.LawStructure
(Ast.LawHeading (heading, List.map (fun (Ast.LawStructure x) -> x) commands'));
];
Ast.program_items = acc.Ast.program_items @ [ Ast.LawHeading (heading, commands') ];
}
| i -> { acc with Ast.program_items = acc.Ast.program_items @ [ i ] })
{ Ast.program_source_files = []; Ast.program_items = [] }

View File

@ -21,8 +21,7 @@
%}
%token EOF
%token<string * string option * string option * int> LAW_ARTICLE
%token<string * int> LAW_HEADING
%token<string * string option * string option * int> LAW_HEADING
%token<Ast.law_include> LAW_INCLUDE
%token<string> LAW_TEXT
%token<string> CONSTRUCTOR IDENT
@ -31,7 +30,7 @@
%token TRUE FALSE
%token<Runtime.integer * Runtime.integer> DECIMAL_LITERAL
%token<Runtime.integer * Runtime.integer> MONEY_AMOUNT
%token BEGIN_CODE TEXT MASTER_FILE
%token BEGIN_CODE TEXT
%token COLON ALT DATA VERTICAL
%token OF INTEGER COLLECTION
%token RULE CONDITION DEFINED_AS

View File

@ -541,9 +541,9 @@ let smic (smic_in : smic_in) =
log_decision_taken
{
filename = "./decrets_divers.catala_fr";
start_line = 335;
start_line = 313;
start_column = 5;
end_line = 337;
end_line = 315;
end_column = 6;
law_headings =
[
@ -563,9 +563,9 @@ let smic (smic_in : smic_in) =
log_decision_taken
{
filename = "./decrets_divers.catala_fr";
start_line = 317;
start_line = 295;
start_column = 5;
end_line = 326;
end_line = 304;
end_column = 6;
law_headings =
[
@ -589,9 +589,9 @@ let smic (smic_in : smic_in) =
log_decision_taken
{
filename = "./decrets_divers.catala_fr";
start_line = 296;
start_line = 274;
start_column = 5;
end_line = 298;
end_line = 276;
end_column = 6;
law_headings =
[
@ -611,9 +611,9 @@ let smic (smic_in : smic_in) =
log_decision_taken
{
filename = "./decrets_divers.catala_fr";
start_line = 278;
start_line = 256;
start_column = 5;
end_line = 287;
end_line = 265;
end_column = 6;
law_headings =
[
@ -637,9 +637,9 @@ let smic (smic_in : smic_in) =
log_decision_taken
{
filename = "./decrets_divers.catala_fr";
start_line = 257;
start_line = 235;
start_column = 5;
end_line = 259;
end_line = 237;
end_column = 6;
law_headings =
[
@ -659,9 +659,9 @@ let smic (smic_in : smic_in) =
log_decision_taken
{
filename = "./decrets_divers.catala_fr";
start_line = 239;
start_line = 217;
start_column = 5;
end_line = 248;
end_line = 226;
end_column = 6;
law_headings =
[
@ -804,17 +804,17 @@ let prestations_familiales (prestations_familiales_in : prestations_familiales_i
log_decision_taken
{
filename = "./decrets_divers.catala_fr";
start_line = 68;
start_line = 58;
start_column = 5;
end_line = 69;
end_line = 59;
end_column = 34;
law_headings =
[
"Instruction interministérielle n°DSS/2B/2021/65 du 19 mars 2021\n\
relative à la revalorisation au 1er avril 2021 des prestations\n\
familiales servies en métropole, en Guadeloupe, en Guyane,\n\
en Martinique, à la Réunion, à Saint-Barthélemy, à Saint-Martin\n\
et dans le département de Mayotte";
"Instruction interministérielle n°DSS/2B/2021/65 du 19 mars 2021 \
relative à la revalorisation au 1er avril 2021 des prestations \
familiales servies en métropole, en Guadeloupe, en Guyane, en \
Martinique, à la Réunion, à Saint-Barthélemy, à Saint-Martin et \
dans le département de Mayotte";
"Montant de la base mensuelle des allocations familiales";
];
}
@ -827,18 +827,17 @@ let prestations_familiales (prestations_familiales_in : prestations_familiales_i
log_decision_taken
{
filename = "./decrets_divers.catala_fr";
start_line = 48;
start_line = 42;
start_column = 5;
end_line = 49;
end_line = 43;
end_column = 34;
law_headings =
[
"Instruction interministérielle no DSS/SD2B/2020/33 du 18 février 2020\n\
relative à la revalorisation au 1er avril 2020 des prestations\n\
familiales servies en métropole, en Guadeloupe, en Guyane, en\n\
"Instruction interministérielle no DSS/SD2B/2020/33 du 18 février \
2020 relative à la revalorisation au 1er avril 2020 des prestations \
familiales servies en métropole, en Guadeloupe, en Guyane, en \
Martinique, à La Réunion, à Saint-Barthélemy, à Saint-Martin et \
dans\n\
le département de Mayotte";
dans le département de Mayotte";
"Montant de la base mensuelle des allocations familiales";
];
}
@ -851,17 +850,15 @@ let prestations_familiales (prestations_familiales_in : prestations_familiales_i
log_decision_taken
{
filename = "./decrets_divers.catala_fr";
start_line = 24;
start_line = 22;
start_column = 5;
end_line = 25;
end_line = 23;
end_column = 34;
law_headings =
[
"INSTRUCTION INTERMINISTERIELLE N° DSS/SD2B/2019/65 du 25 mars 2019 \
relative\n\
à la revalorisation au 1er avril 2019 des prestations familiales \
servies en\n\
métropole";
"Instruction ministérielle N°DSS/SD2B/2019/65 du 25 mars 2019 \
relative à la revalorisation au 1er avril 2019 des prestations \
familiales servies en métropole";
"Montant de la base mensuelle des allocations familiales";
];
}
@ -1758,9 +1755,9 @@ let allocations_familiales (allocations_familiales_in : allocations_familiales_i
log_decision_taken
{
filename = "./decrets_divers.catala_fr";
start_line = 216;
start_line = 194;
start_column = 5;
end_line = 216;
end_line = 194;
end_column = 69;
law_headings =
[
@ -1785,20 +1782,17 @@ let allocations_familiales (allocations_familiales_in : allocations_familiales_i
log_decision_taken
{
filename = "./decrets_divers.catala_fr";
start_line = 180;
start_line = 158;
start_column = 5;
end_line = 180;
end_line = 158;
end_column = 69;
law_headings =
[
"Instruction interministerielle no DSS/SD2B/2019/261 du 18 décembre 2019\n\
relative à la revalorisation au 1er janvier 2020 des plafonds de \
ressources\n\
dattribution de certaines prestations familiales servies en \
métropole,\n\
en Guadeloupe, en Guyane, en Martinique, à La Réunion, à \
Saint-Barthélemy,\n\
à Saint-Martin et à Mayotte";
"Instruction interministerielle no DSS/SD2B/2019/261 du 18 décembre \
2019 relative à la revalorisation au 1er janvier 2020 des plafonds de \
ressources dattribution de certaines prestations familiales servies \
en métropole, en Guadeloupe, en Guyane, en Martinique, à La \
Réunion, à Saint-Barthélemy, à Saint-Martin et à Mayotte";
"Montant des plafonds de ressources";
];
}
@ -1815,21 +1809,17 @@ let allocations_familiales (allocations_familiales_in : allocations_familiales_i
log_decision_taken
{
filename = "./decrets_divers.catala_fr";
start_line = 143;
start_line = 125;
start_column = 5;
end_line = 143;
end_line = 125;
end_column = 69;
law_headings =
[
"Instruction interministérielle n° DSS/SD2B/2018/279 du 17 décembre \
2018\n\
relative à la revalorisation au 1er janvier 2019 des plafonds de \
ressources\n\
dattribution de certaines prestations familiales servies en \
métropole, en\n\
Guadeloupe, en Guyane, en Martinique, à la Réunion, à \
Saint-Barthélemy,\n\
à Saint-Martin et à Mayotte";
2018 relative à la revalorisation au 1er janvier 2019 des plafonds de \
ressources dattribution de certaines prestations familiales servies \
en métropole, en Guadeloupe, en Guyane, en Martinique, à la \
Réunion, à Saint-Barthélemy, à Saint-Martin et à Mayotte";
"Montant des plafonds de ressources";
];
}
@ -1846,20 +1836,17 @@ let allocations_familiales (allocations_familiales_in : allocations_familiales_i
log_decision_taken
{
filename = "./decrets_divers.catala_fr";
start_line = 106;
start_line = 92;
start_column = 5;
end_line = 106;
end_line = 92;
end_column = 69;
law_headings =
[
"CIRCULAIRE INTERMINISTERIELLE N° DSS/SD2B/2017/352 du 22 décembre 2017\n\
relative à la revalorisation au 1er janvier 2018 des plafonds de \
ressources\n\
dattribution de certaines prestations familiales servies en \
métropole, en\n\
Guadeloupe, en Guyane, en Martinique, à la Réunion, à \
Saint-Barthélemy,\n\
à Saint-Martin et à Mayotte";
"Circulaire interministérielle N° DSS/SD2B/2017/352 du 22 décembre \
2017 relative à la revalorisation au 1er janvier 2018 des plafonds de \
ressources dattribution de certaines prestations familiales servies \
en métropole, en Guadeloupe, en Guyane, en Martinique, à la \
Réunion, à Saint-Barthélemy, à Saint-Martin et à Mayotte";
"Montant des plafonds de ressources";
];
}
@ -1911,9 +1898,9 @@ let allocations_familiales (allocations_familiales_in : allocations_familiales_i
log_decision_taken
{
filename = "./decrets_divers.catala_fr";
start_line = 200;
start_line = 178;
start_column = 5;
end_line = 200;
end_line = 178;
end_column = 69;
law_headings =
[
@ -1938,20 +1925,17 @@ let allocations_familiales (allocations_familiales_in : allocations_familiales_i
log_decision_taken
{
filename = "./decrets_divers.catala_fr";
start_line = 173;
start_line = 151;
start_column = 5;
end_line = 173;
end_line = 151;
end_column = 69;
law_headings =
[
"Instruction interministerielle no DSS/SD2B/2019/261 du 18 décembre 2019\n\
relative à la revalorisation au 1er janvier 2020 des plafonds de \
ressources\n\
dattribution de certaines prestations familiales servies en \
métropole,\n\
en Guadeloupe, en Guyane, en Martinique, à La Réunion, à \
Saint-Barthélemy,\n\
à Saint-Martin et à Mayotte";
"Instruction interministerielle no DSS/SD2B/2019/261 du 18 décembre \
2019 relative à la revalorisation au 1er janvier 2020 des plafonds de \
ressources dattribution de certaines prestations familiales servies \
en métropole, en Guadeloupe, en Guyane, en Martinique, à La \
Réunion, à Saint-Barthélemy, à Saint-Martin et à Mayotte";
"Montant des plafonds de ressources";
];
}
@ -1968,21 +1952,17 @@ let allocations_familiales (allocations_familiales_in : allocations_familiales_i
log_decision_taken
{
filename = "./decrets_divers.catala_fr";
start_line = 136;
start_line = 118;
start_column = 5;
end_line = 136;
end_line = 118;
end_column = 69;
law_headings =
[
"Instruction interministérielle n° DSS/SD2B/2018/279 du 17 décembre \
2018\n\
relative à la revalorisation au 1er janvier 2019 des plafonds de \
ressources\n\
dattribution de certaines prestations familiales servies en \
métropole, en\n\
Guadeloupe, en Guyane, en Martinique, à la Réunion, à \
Saint-Barthélemy,\n\
à Saint-Martin et à Mayotte";
2018 relative à la revalorisation au 1er janvier 2019 des plafonds de \
ressources dattribution de certaines prestations familiales servies \
en métropole, en Guadeloupe, en Guyane, en Martinique, à la \
Réunion, à Saint-Barthélemy, à Saint-Martin et à Mayotte";
"Montant des plafonds de ressources";
];
}
@ -1999,20 +1979,17 @@ let allocations_familiales (allocations_familiales_in : allocations_familiales_i
log_decision_taken
{
filename = "./decrets_divers.catala_fr";
start_line = 99;
start_line = 85;
start_column = 5;
end_line = 99;
end_line = 85;
end_column = 69;
law_headings =
[
"CIRCULAIRE INTERMINISTERIELLE N° DSS/SD2B/2017/352 du 22 décembre 2017\n\
relative à la revalorisation au 1er janvier 2018 des plafonds de \
ressources\n\
dattribution de certaines prestations familiales servies en \
métropole, en\n\
Guadeloupe, en Guyane, en Martinique, à la Réunion, à \
Saint-Barthélemy,\n\
à Saint-Martin et à Mayotte";
"Circulaire interministérielle N° DSS/SD2B/2017/352 du 22 décembre \
2017 relative à la revalorisation au 1er janvier 2018 des plafonds de \
ressources dattribution de certaines prestations familiales servies \
en métropole, en Guadeloupe, en Guyane, en Martinique, à la \
Réunion, à Saint-Barthélemy, à Saint-Martin et à Mayotte";
"Montant des plafonds de ressources";
];
}

View File

@ -15,7 +15,7 @@ RESET := $(shell tput -Txterm sgr0)
CATALA_OPTS?=
CATALA=dune exec --no-buffer --no-print-director ../src/catala/catala.exe -- Interpret $(CATALA_OPTS)
CATALA=../_build/default/src/catala/catala.exe Interpret $(CATALA_OPTS)
pass_tests: $(wildcard */*/output/*.out)
@ -25,12 +25,12 @@ reset_tests: $(subst output/,,$(subst .out,.in,$(wildcard */*/output/*.out)))
.FORCE:
%.run: .FORCE
$(CATALA) $(word 1,$(subst ., ,$*)).catala -s $(word 3,$(subst ., ,$*))
$(CATALA) $(word 1,$(subst ., ,$*)).catala -s $(word 3,$(subst ., ,$*))
# Usage: make <test_dir>/output/<test_name>.catala.<scope_name>.out
# This rule runs the test and compares against the expected output. If the
# This rule runs the test and compares against the expected output. If the
# Catala program is <test_dir>/<test_name>.catala
# and the scope to run is <scope_name>, then the expected output should be in the file
# and the scope to run is <scope_name>, then the expected output should be in the file
# <test_dir>/output/<test_name>.catala.<scope_name>.out
%.out: .FORCE
@$(CATALA) --unstyled \
@ -40,7 +40,7 @@ reset_tests: $(subst output/,,$(subst .out,.in,$(wildcard */*/output/*.out)))
@echo "${GREEN}PASS${RESET} ${PURPLE}$*${RESET}"
# Usage: make <test_dir>/<test_name>.catala.<scope_name>.in
# This rule runs the test <test_dir>/<test_name>.catala, prints its output and
# This rule runs the test <test_dir>/<test_name>.catala, prints its output and
# writes this output to the <test_dir>/output/<test_name>.catala.<scope_name>.out file
%.in: .FORCE
@-$(CATALA) $(word 1,$(subst ., ,$*)).catala -s $(word 3,$(subst ., ,$*))

View File

@ -1,4 +1,4 @@
## [Article]
## Article
```catala
new scope A:

View File

@ -1,4 +1,4 @@
## [Article]
## Article
```catala
new scope A:

View File

@ -1,4 +1,4 @@
## [Article]
## Article
```catala
new struct S:

View File

@ -1,4 +1,4 @@
## [Article]
## Article
```catala
new scope A:

View File

@ -1,4 +1,4 @@
## [Article]
## Article
```catala
new scope A:

View File

@ -1,4 +1,4 @@
## ['xor' should be a boolean operator]
## 'xor' should be a boolean operator
```catala
new scope TestXorWithInt :

View File

@ -1,4 +1,4 @@
## [Article]
## Article
```catala
new scope TestBool :

View File

@ -1,4 +1,4 @@
## [Test all 'xor' combinations]
## Test all 'xor' combinations
```catala
new scope TestXor :

View File

@ -1,4 +1,4 @@
## [Article]
## Article
```catala
new scope A:

View File

@ -1,4 +1,4 @@
## [Article]
## Article
```catala
new scope A:

View File

@ -1,4 +1,4 @@
## [Article]
## Article
```catala
new scope A:

View File

@ -1,4 +1,4 @@
## [Article]
## Article
```catala
new scope A:

View File

@ -1,4 +1,4 @@
## [Article]
## Article
```catala
new scope A:

View File

@ -1,4 +1,4 @@
## [Article]
## Article
```catala
new scope A:

View File

@ -1,4 +1,4 @@
## [Article]
## Article
```catala
new scope A:

View File

@ -1,4 +1,4 @@
## [Article]
## Article
```catala
new enum E:

View File

@ -1,4 +1,4 @@
## [Article]
## Article
```catala
new enum E:

View File

@ -1,4 +1,4 @@
## [Article]
## Article
```catala
new enum E:

View File

@ -1,4 +1,4 @@
## [Article]
## Article
```catala
new enum E:

View File

@ -1,4 +1,4 @@
## [Article]
## Article
```catala
new enum E:

View File

@ -1,4 +1,4 @@
## [Test]
## Test
```catala
new enum E:

View File

@ -1,4 +1,4 @@
## [Article]
## Article
```catala
new enum E:

View File

@ -1,4 +1,4 @@
## [Article]
## Article
```catala
new enum E:

View File

@ -1,4 +1,4 @@
## [Article]
## Article
```catala
new enum E:

View File

@ -1,4 +1,4 @@
## [Article]
## Article
```catala
new enum E:

View File

@ -1,4 +1,4 @@
## [Article]
## Article
```catala
new enum E:

View File

@ -1,4 +1,4 @@
## [Test]
## Test
```catala
new scope A:

View File

@ -1,4 +1,4 @@
## [Test]
## Test
```catala
new scope A:

View File

@ -1,4 +1,4 @@
## [Test]
## Test
```catala
new scope A:

View File

@ -1,4 +1,4 @@
## [Test]
## Test
```catala
new scope A:

View File

@ -1,4 +1,4 @@
## [Test]
## Test
```catala
new scope A:

View File

@ -1,4 +1,4 @@
## [Test]
## Test
```catala
new scope A:

View File

@ -1,4 +1,4 @@
## [Test]
## Test
```catala
new scope A:

View File

@ -1,4 +1,4 @@
## [Test]
## Test
```catala
new scope A:

View File

@ -1,4 +1,4 @@
## [Test]
## Test
```catala
new scope A:

View File

@ -1,4 +1,4 @@
## [Test]
## Test
```catala
new scope A:

View File

@ -1,4 +1,4 @@
## [Test]
## Test
```catala
new scope A:

View File

@ -1,4 +1,4 @@
## [Test]
## Test
```catala
new scope A:

View File

@ -1,4 +1,4 @@
## [Test]
## Test
```catala
new scope A:

View File

@ -1,4 +1,4 @@
## [Article]
## Article
```catala
new scope S:

View File

@ -1,4 +1,4 @@
## [ Article ]
## Article
```catala
new scope RecursiveFunc:

View File

@ -1,4 +1,4 @@
## [Article]
## Article
```catala
new scope S:

View File

@ -1,4 +1,4 @@
## [Article]
## Article
```catala
new scope A:

View File

@ -1,4 +1,4 @@
## [Article]
## Article
```catala
new scope A:

View File

@ -1,8 +1,8 @@
## [Article]
## Article
```catala
```catala
new scope S:
param a content A
param a content A
param b content B
new struct A:
@ -10,7 +10,7 @@ new struct A:
data y content B
new struct B:
data y content bool
data y content bool
data z content dec
scope S:

View File

@ -1,4 +1,4 @@
## [Article]
## Article
```catala
new scope A:

View File

@ -1,4 +1,4 @@
## [ Article ]
## Article
```catala
new scope A :

View File

@ -1,4 +1,4 @@
## [ Article ]
## Article
```catala
new scope A:

View File

@ -1,7 +0,0 @@
[ERROR] "B": unknown identifier for a scope
[ERROR]
[ERROR] --> test_scope/cyclic_scopes.catala
[ERROR] |
[ERROR] 5 | param b scope B
[ERROR] | ^
[ERROR] + Article

View File

@ -0,0 +1,29 @@
[ERROR] Cyclic dependency detected between scopes!
[ERROR]
[ERROR] Cycle variable B, declared:
[ERROR] --> test_scope/bad/cyclic_scopes.catala
[ERROR] |
[ERROR] 8 | new scope B:
[ERROR] | ^
[ERROR] + Article
[ERROR]
[ERROR] Used here in the definition of another cycle variable A:
[ERROR] --> test_scope/bad/cyclic_scopes.catala
[ERROR] |
[ERROR] 5 | param b scope B
[ERROR] | ^
[ERROR] + Article
[ERROR]
[ERROR] Cycle variable A, declared:
[ERROR] --> test_scope/bad/cyclic_scopes.catala
[ERROR] |
[ERROR] 4 | new scope A:
[ERROR] | ^
[ERROR] + Article
[ERROR]
[ERROR] Used here in the definition of another cycle variable B:
[ERROR] --> test_scope/bad/cyclic_scopes.catala
[ERROR] |
[ERROR] 9 | param a scope A
[ERROR] | ^
[ERROR] + Article

View File

@ -1,4 +1,4 @@
## [Article]
## Article
```catala
new scope A:

View File

@ -1,4 +1,4 @@
## [ Article ]
## Article
```catala
new scope A:

View File

@ -1,4 +1,4 @@
## [ Article ]
## Article
```catala
new scope A:

View File

@ -1,4 +1,4 @@
## [Article]
## Article
```catala
new scope A:

View File

@ -1,4 +1,4 @@
## [Article]
## Article
```catala
new scope A:

View File

@ -1,4 +1,4 @@
## [Article]
## Article
```catala
new struct Foo:

View File

@ -1,4 +1,4 @@
## [https://github.com/CatalaLang/catala/issues/107]
## https://github.com/CatalaLang/catala/issues/107
```catala
new struct S:

View File

@ -1,4 +1,4 @@
## [Article]
## Article
```catala
new struct S:

Some files were not shown because too many files have changed in this diff Show More