Partage
  • Partager sur Facebook
  • Partager sur Twitter

[Langage] Petit langage impératif

... français et open-source

    8 juin 2013 à 20:40:09

    Bonjour,
    Je m'appelle Antoine (antoine1023 un peu partout), j'ai 17 ans, je suis en première S - Sciences de l'Ingénieur. Cela fait 2 - 3 ans que je développe vraiment ; aujourd'hui principalement en Python, un peu C++ et surtout en Java.
    Je m'intéresse à un peu tout dans l'informatique, que ce soit à bas ou à haut niveau...


    En savoir plus sur le projet

    J'ai essayé de le décrire précisément. J'espère que cela est satisfaisant.

    Genèse

    Tout d'abord, j'ai voulu programmer en Java un analyseur lexical pas trop mal sans utiliser d'outils de type lex ; par curiosité, par envie de faire. Je me suis donc un peu renseigné sur le sujet, et l'ai réalisé. Ensuite, m'intéressant au parsers, j'en ai profité pour en faire un petit, un descendant récursif, gérant les opérations mathématiques de base et les parenthèses.
    Puis, j'ai découvert Algoid, un autre projet d'un zéro. Je lui fais un peu de pub, mais allez-y faire tour, c'est vraiment un gros projet intéressant et bien fait. Algoid m'a pas mal motivé, je me suis dit que je pourrais essayer de faire mon langage à moi.... Alors j'ai voulu rajouter des variables. Puis j'ai rajouté des fonctions, des types...
    Et là je me retrouve ici :-)

    Généralités et avancement

    Le projet à désormais un nom, smallFrench, et se situe ici sur Google Code. Si vous souhaitez participer, n'hésitez pas à m'envoyer un message privé.
    Donc, en gros, il y a deux parties :

    • La partie interface, réalisée avec Swing, avec :
      • Une console pour les entrées/sorties ;
      • Un petit éditeur qui supporte la coloration syntaxique, le copier-coller, l'annulation des modifications (pas encore au point) ;
      • L'ouverture de programmes d'exemples ;
      • L'ouverture et l'enregistrement de scripts dans le système de fichiers (extension ".sfrench").
    • La partie interpréteur, décomposée en quatre packages :
      • Un premier pour l'analyse lexicale (tokenization) ;
      • Un second pour l'analyse syntaxique (parsing) ;
      • Un troisième pour l'exécution. Ne soyez pas déçus, pas de compilation en bytecode, ni de visiteurs :-D ;
      • Un dernier pour la bibliothèque standard, qui contient les types (Entier, Chaine, ...), la console, et l'objet Math.

    Derniers changements

    • Réécriture de la console, qui n'est plus un champ de texte Swing, mais un petit terminal ;
    • Gestion des erreurs encore améliorée, la ligne est désormais surlignée dans l'éditeur, y compris pour les erreurs de syntaxe ;
    • Ajout d'un système d'arborescence des exemples, pour les trier dans des dossiers ;
    • La portée du langage est désormais statique (lexicale), on peut utiliser des closures :-p ;
    • Maintenant, un bloc de parenthèses définit une portée (enfin, pas toujours : uniquement si le bloc contient des déclarations de variables, pour optimiser un peu)
    • Implémentation de l'arrêt forcé du script avec le bouton "stop", comme ça pas de souci avec les boucles infinies ;
    • Ajout numérotation des lignes (ça a l'air tout bête mais c'est l'un des trucs qui m'a pris le plus de temps) ;
    • Ajout instruction "finboucle", équivalent du "break" ;

    J'ai commencé à faire une mini référence sur le wiki du projet, mais elle est assez obsolète depuis le temps... Des exemples de programmes sont disponibles avec le JAR exécutable.

    Capture d'écran

    Un petit aperçu de l'ensemble

    Objectifs

    Mon rêve serait que ce projet aboutisse à un petit IDE, un peu comme celui d'Algobox, et à un petit langage d'initiation à la programmation en français, très simple et agréable à lire.
    A mon avis, privilégier la performance est une erreur. Les langages performant sont comme le C, ils se compilent, et ne sont pas interprétés sur un interpréteur sur une JVM...
    Il faudrait d'abord ajouter des instructions, compléter la bibliothèque, améliorer l'éditeur, ...


    Le projet et son originalité

    Alors je connais trois "concurrents" open-source, deux langages en Français. Je vais essayer de vous montrer que smallFrench est bien mieux :-)

    Algobox

    Algobox est basé sur Javascript (les scripts sont traduits avant leur exécution), et est actuellement très utilisé par l'Education Nationale. Il inclus un petit éditeur de l'arbre syntaxique.
    Par comparaison, smallFrench n'est pas basé sur un langage existant, mais smallFrench est moins performant. La syntaxe de smallFrench est plus lisible (les mots clés d'Algobox sont écrits en MAJUSCULES), et les bibliothèques de smallFrench sont entièrement en Français alors qu'Algobox utilise celle de JS.
    Avec Algobox, il y a aussi les mêmes opérateurs de comparaison qu'en JS. Confusion probable entre '=' et '=='.

    Scratch

    Développé par le MIT, Scratch est, selon Wikipedia, "une implémentation visuelle et dynamique du langage de programmation Smalltalk basé sur Squeak". Assez simple, il est très visuel et éloigné d'un langage de programmation "professionnel" : seul l'arbre syntaxique est éditable. De plus, il est utilisable uniquement via l'interface web. Il a la particularité d'être traduit dans plusieurs langues, dont le Français ; une grande communauté d'utilisateurs s'est formée autour de lui.
    smallFrench est distribué sous la forme d'un petit fichier JAR de quelques centaines de kilo-octets : il parfaitement utilisable hors-ligne. L'édition des scripts se fait par un éditeur texte classique, et non par un éditeur de l'arbre syntaxique ; c'est un peu moins convivial, mais plus proche d'un environnement professionnel.

    Linotte

    Linotte est un langage de programmation conçu pour être le plus proche possible du français naturel. Il inclus également l'"Atelier Linotte", un vrai petit IDE développé en Java. Orienté objet, pleins de plugins sont disponibles, dont un pour Java3D et un pour le protocole réseau TCP. A noter aussi, Webonotte, qui permet la génération de pages web dynamiques, comme en PHP.
    En fait, les syntaxes de smallFrench et Linotte sont très différentes : smallFrench cherche plus à rester un langage avec une syntaxe simple, proche de celle de langages comme le C ou le Python ; avec une interface légère et sobre.
    Et puis de toute façon, je ne peut pas trop le critiquer vu que son concepteur est venu poster :-)


    Télécharger le JAR

    Téléchargez le JAR de la version 0.1.3 ici Ce n'est pas encore au point. Vous pouvez reporter les bugs ici ou sur la page du projet.
    Requiert le JRE 6. Testé sous Ubuntu (OpenJDK 6) et sous Windows cette fois, avec la JVM Oracle !


    Et merci d'avance pour vos réponses ;-)

    -
    Edité par antoine1023 26 juin 2013 à 21:34:58

    • Partager sur Facebook
    • Partager sur Twitter
    Arius, vraiment le plus puissant de l'ancienne Ligue des Super Zéros !
      8 juin 2013 à 23:26:19

      Salut Antoine.
      Déjà, comme dit en PM, je suis ravi que mon projet t'ai donné envis de te lancer.
      Les analyseurs syntaxiques ne sont pas si simple, mais c'est passionnant.
      Cela dit, je dénote, à la lecture, quelques points sur lesquels tu vas nécéssairement buter.
      Mettre une ',' pour les décimales est une très bonne idée. Ca permetra à ton lexer de comprendre des syntaxes comme suit : 2,7.add(8)
      Cela étant. Quel séparateur vas tu définir pour les éléments d'un tableau ?
      Un analyseur syntaxique procédurale (mutuellement récursives).... beark.... regarde du coté du pattenr interpreter du GoF ;-)
      Ca fait chauffer la tête, mais le résultat sera plus sympa.
      Second point. Les fonctions retournent la dernière valeur. J'y avait pensé.... mais d'une part, c'est ambigue, cela peu renvoyer des valeurs que l'on ne souhaite pas.
      Et d'autre part si tu veux faire du "cascade" (le fameux tout est objet, ou y ressemble du moins) et bien un principe sympa est de retourner l'objet si rien n'est retourné par la méthode.
      Par exemple :
      myArray.add(5).add(7)
      Oui pour les testes il te manque les "not".
      Pour ce qui est des perfs.
      Et bien si, elles ont leur importante, mais pas au détriment de la sémantique, en effet.
      Un langage interpreté ne seras jamais aussi performant que le langage qui le contient... et pour cause. Un interpreteur cré un grand nombre d'appels imbriqués.
      Et ces appelles sont très gourmands. Le recursive descent parseur en est un, l'interpréteur (visitor) en est un autre.
      Qui dit appelle de fonction, dit changement de contexte.... portée.... tout ça....
      Voilà.
      Il me reste à te souhaiter bon courage.

      -
      Edité par CyaNn 8 juin 2013 à 23:26:44

      • Partager sur Facebook
      • Partager sur Twitter
      Découvrez Algoid le langage pour apprendre à programmer.
        8 juin 2013 à 23:46:33

        Petit reproche au langage Linote toutefois, c'est que pour un langage qui ce veux simple, la notion de pointeur me géne un peu.

        *newx :: nombre

        Ca ne ressemble plus tout à fait au langage naturel.

        • Partager sur Facebook
        • Partager sur Twitter
        Découvrez Algoid le langage pour apprendre à programmer.
          9 juin 2013 à 16:26:12

          Salut, merci de ta réponse.
          Pour les tableaux, l'absence de virgule n'est pas un problème, puisque l'absence de points-virgules n'en est pas un non plus entre les lignes. Non ?
          Je pense utiliser les crochets ouvrants et fermants pour les définitions. Exemple :

           tablo = [elem0 elem1 elem2 2 3 "abc"]
          

          Je devrais aussi pouvoir me servir des crochets pour accéder aux éléments (Puisque j'arrive à utiliser les parenthèses pour les appels de fonctions).
          Je ne connaissait pas le nom "pattern interpreter". Mais c'est bien ce que j'ai utilisé :-) Le parser génère un arbre syntaxique qui est constitué d'objets , chacun héritant d'une classe abstraite représentant un nœud comprenant une méthode eval.
          Donc d'abord il parse et génère l'arbre, ensuite il exécute.
          Cette méthode eval retourne un objet de type RObject. Tous les types héritent de RObject, cette classe, abstraite comprends des méthodes pour chaque opérateur, comme en C++ (plus, moins, moins unitaire, multiplication, non, et, ouexcusif, ... mais pas l'opérateur point). Chaque type redéfinit un certain nombre d'opérateur.
          RObject inclut aussi une propriété get retournant on autre RObject et prenant une chaine en paramètre, pour accéder à un objet dans l'objet, avec l'opérateur point. Donc on pourra faire 2,3.factorielle() par exemple.
          Les nombres, les booléens, les fonctions natives et les fonctions définies par l'utilisateur héritent de cet RObject et sont référencables par des variables. Tout est objet, les appels en cascades sont possibles. Mais ce n'est pas un langage orienté objet, on ne peut pas définir de classe (en tout cas, pas pour l'instant) :-)
          Pour les histoires de portée des variables, j'ai une classe Scope avec une pile de HashMap<String, RObject> dedans. Quand on entre dans une fonction, j'empile une nouvelle HashMap, quand on en sort, je dépile. Une nouvelle variable est crée dans la dernière map empilée, et pour obtenir la valeur d'une variable, je recherche à partir du haut de la pile. La map en bas de la pile n'est jamais dépilée, elle contient l'objet Console notamment. Le problème, c'est qu'il me manque des mots clés pour bien gérer ça. A ma connaissance, il y a deux méthodes pour cette histoire de portée.
          La méthode Python, en déclarant qu'on utilise une globale à l'intérieur des fonctions :

          a = 1023 # variable globale
          def fonction():
              global a # on utilise a
              print a
              b = "test" # variable locale
          

          Ta méthode, ou la méthode C, en déclarant chaque variable. Ici avec Algoid :

          set a = 1023
          fonction = function () {
              text.output(a) // On utilise la var globale a, car on ne la déclare pas
              set = "test" // Nouvelle variable déclarée
          }
          

          Donc voilà, je devrais choisir. Actuellement, quand on utilise une variable dans une fonction, cette variable est globale si elle existait déjà en dehors de la fonction avant l'appel. Donc c'est vraiment pas terrible...

          Linotte, je le connais pas trop. Je ne savais pas qu'il permettait de manipuler des pointeurs. C'est sûr que ça peut être considéré comme un inconvénient :-) Merci de la précision.

          • Partager sur Facebook
          • Partager sur Twitter
          Arius, vraiment le plus puissant de l'ancienne Ligue des Super Zéros !
            9 juin 2013 à 17:34:58

            Ce que je n'aime pas avec cette écriture (variables implicites) c'est la possibilité suivante :

            for (i; i<10; i++) {
            
            }

            Jusque là, tout vas bien !

            Mais

            i = 15
            
            // plein de code qui font oublier que i est déjà assigné
            
            for (i; i<10; i++) { // boucle ignoré
            
            }
            

            C'est pour cela que j'ai mis des set partout. Pour créer explicitement les variables.

            Pour les scope, j'ai raisonné arbre plutôt que pile. Mais AL conserve beaucoup de chose en mémoire, pour optimiser au maximum les temps d'executions (un poil plus rapide que python sur mon mac... et pourtant c'est sur du Java).

            En utilisant ton RObject, du doit le caster systématiquement non ? Ou alors tu implémente des méthodes vides.

            Bon c'est moins pire que Rhino. J'ai regardé un peu le code. Il utilise directement Object et cast à tous vas.

            Pour l'absence de virgule, c'est un choix. Effectivement pourquoi pas. Après je ne suis pas sûr que ça ajoute de la lisibilité au code source.

            Ha et quand je lance ton appli, j'ai ce message d'erreur :

            Exception in thread "AWT-EventQueue-0" java.lang.NoSuchMethodError: java.lang.Character.isAlphabetic(I)Z
            	at lang.tokener.NameAutomaton.tokenize(NameAutomaton.java:16)
            	at lang.tokener.NameAutomaton.tokenize(NameAutomaton.java:1)
            	at lang.tokener.SuperAutomaton.tokenize(SuperAutomaton.java:20)
            	at lang.tokener.Tokener.tokenize2(Tokener.java:47)
            	at lang.tokener.Tokener.tokenize(Tokener.java:63)
            	at lang.tokener.Tokener.tokenizeAll(Tokener.java:84)
            	at lang.parser.TokenReader.<init>(TokenReader.java:17)
            	at ui.MainWindow.parseProgram(MainWindow.java:94)
            	at ui.MainWindow.access$0(MainWindow.java:87)
            	at ui.MainWindow$1.actionPerformed(MainWindow.java:70)
            	at javax.swing.AbstractButton.fireActionPerformed(AbstractButton.java:2028)
            	at javax.swing.AbstractButton$Handler.actionPerformed(AbstractButton.java:2351)
            	at javax.swing.DefaultButtonModel.fireActionPerformed(DefaultButtonModel.java:387)
            	at javax.swing.DefaultButtonModel.setPressed(DefaultButtonModel.java:242)
            	at javax.swing.plaf.basic.BasicButtonListener.mouseReleased(BasicButtonListener.java:236)
            	at java.awt.Component.processMouseEvent(Component.java:6382)
            	at javax.swing.JComponent.processMouseEvent(JComponent.java:3275)
            	at java.awt.Component.processEvent(Component.java:6147)
            	at java.awt.Container.processEvent(Container.java:2083)
            	at java.awt.Component.dispatchEventImpl(Component.java:4744)
            	at java.awt.Container.dispatchEventImpl(Container.java:2141)
            	at java.awt.Component.dispatchEvent(Component.java:4572)
            	at java.awt.LightweightDispatcher.retargetMouseEvent(Container.java:4619)
            	at java.awt.LightweightDispatcher.processMouseEvent(Container.java:4280)
            	at java.awt.LightweightDispatcher.dispatchEvent(Container.java:4210)
            	at java.awt.Container.dispatchEventImpl(Container.java:2127)
            	at java.awt.Window.dispatchEventImpl(Window.java:2489)
            	at java.awt.Component.dispatchEvent(Component.java:4572)
            	at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:710)
            	at java.awt.EventQueue.access$400(EventQueue.java:82)
            	at java.awt.EventQueue$2.run(EventQueue.java:669)
            	at java.awt.EventQueue$2.run(EventQueue.java:667)
            	at java.security.AccessController.doPrivileged(Native Method)
            	at java.security.AccessControlContext$1.doIntersectionPrivilege(AccessControlContext.java:87)
            	at java.security.AccessControlContext$1.doIntersectionPrivilege(AccessControlContext.java:98)
            	at java.awt.EventQueue$3.run(EventQueue.java:683)
            	at java.awt.EventQueue$3.run(EventQueue.java:681)
            	at java.security.AccessController.doPrivileged(Native Method)
            	at java.security.AccessControlContext$1.doIntersectionPrivilege(AccessControlContext.java:87)
            	at java.awt.EventQueue.dispatchEvent(EventQueue.java:680)
            	at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:296)
            	at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:211)
            	at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:201)
            	at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:196)
            	at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:188)
            	at java.awt.EventDispatchThread.run(EventDispatchThread.java:122)
            Exception in thread "AWT-EventQueue-0" java.lang.NoSuchMethodError: java.lang.Character.isAlphabetic(I)Z
            	at lang.tokener.NameAutomaton.tokenize(NameAutomaton.java:16)
            	at lang.tokener.NameAutomaton.tokenize(NameAutomaton.java:1)
            	at lang.tokener.SuperAutomaton.tokenize(SuperAutomaton.java:20)
            	at lang.tokener.Tokener.tokenize2(Tokener.java:47)
            	at lang.tokener.Tokener.tokenize(Tokener.java:63)
            	at lang.tokener.Tokener.tokenizeAll(Tokener.java:84)
            	at lang.parser.TokenReader.<init>(TokenReader.java:17)
            	at ui.MainWindow.parseProgram(MainWindow.java:94)
            	at ui.MainWindow.access$0(MainWindow.java:87)
            	at ui.MainWindow$1.actionPerformed(MainWindow.java:70)
            	at javax.swing.AbstractButton.fireActionPerformed(AbstractButton.java:2028)
            	at javax.swing.AbstractButton$Handler.actionPerformed(AbstractButton.java:2351)
            	at javax.swing.DefaultButtonModel.fireActionPerformed(DefaultButtonModel.java:387)
            	at javax.swing.DefaultButtonModel.setPressed(DefaultButtonModel.java:242)
            	at javax.swing.plaf.basic.BasicButtonListener.mouseReleased(BasicButtonListener.java:236)
            	at java.awt.Component.processMouseEvent(Component.java:6382)
            	at javax.swing.JComponent.processMouseEvent(JComponent.java:3275)
            	at java.awt.Component.processEvent(Component.java:6147)
            	at java.awt.Container.processEvent(Container.java:2083)
            	at java.awt.Component.dispatchEventImpl(Component.java:4744)
            	at java.awt.Container.dispatchEventImpl(Container.java:2141)
            	at java.awt.Component.dispatchEvent(Component.java:4572)
            	at java.awt.LightweightDispatcher.retargetMouseEvent(Container.java:4619)
            	at java.awt.LightweightDispatcher.processMouseEvent(Container.java:4280)
            	at java.awt.LightweightDispatcher.dispatchEvent(Container.java:4210)
            	at java.awt.Container.dispatchEventImpl(Container.java:2127)
            	at java.awt.Window.dispatchEventImpl(Window.java:2489)
            	at java.awt.Component.dispatchEvent(Component.java:4572)
            	at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:710)
            	at java.awt.EventQueue.access$400(EventQueue.java:82)
            	at java.awt.EventQueue$2.run(EventQueue.java:669)
            	at java.awt.EventQueue$2.run(EventQueue.java:667)
            	at java.security.AccessController.doPrivileged(Native Method)
            	at java.security.AccessControlContext$1.doIntersectionPrivilege(AccessControlContext.java:87)
            	at java.security.AccessControlContext$1.doIntersectionPrivilege(AccessControlContext.java:98)
            	at java.awt.EventQueue$3.run(EventQueue.java:683)
            	at java.awt.EventQueue$3.run(EventQueue.java:681)
            	at java.security.AccessController.doPrivileged(Native Method)
            	at java.security.AccessControlContext$1.doIntersectionPrivilege(AccessControlContext.java:87)
            	at java.awt.EventQueue.dispatchEvent(EventQueue.java:680)
            	at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:296)
            	at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:211)
            	at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:201)
            	at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:196)
            	at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:188)
            	at java.awt.EventDispatchThread.run(EventDispatchThread.java:122)
            

            Ha! Et un un lexer s'appelle un tokenizer, par un tokener (quoi que je ne soit pas un as des langages naturels.... lol)

            Bonne suite ;-)

            -
            Edité par CyaNn 9 juin 2013 à 17:38:47

            • Partager sur Facebook
            • Partager sur Twitter
            Découvrez Algoid le langage pour apprendre à programmer.
              9 juin 2013 à 18:39:39

              Ah mince... Ca marche en tout cas sur ma config : Ubuntu 13.04 OpenJDK 6 et 7... Merci !
              Pour le RObject, ya pas mal de instanceof et de cast, c'est vrai. C'est mieux que des méthodes vides, non ? Je regarderais comment Rhino fait, ca doit être intéressant.
              Quand au Tokener, ben en voilà un : http://www.JSON.org/javadoc/org/json/JSONTokener.html
              Les deux orthographes doivent exister :-)

              • Partager sur Facebook
              • Partager sur Twitter
              Arius, vraiment le plus puissant de l'ancienne Ligue des Super Zéros !
                9 juin 2013 à 21:03:26

                C'est marrant, le parser de Rhino est récursif descendant. Comme quoi c'est pas si mal, même si c'est ce qu'il y a de plus simple. Par contre, le lexer est optimisé à mort. Horrible :-) https://github.com/mozilla/rhino/blob/master/src/org/mozilla/javascript/TokenStream.java

                • Partager sur Facebook
                • Partager sur Twitter
                Arius, vraiment le plus puissant de l'ancienne Ligue des Super Zéros !
                  10 juin 2013 à 9:18:26

                  Ouep c'est parce qu'ils trichent : Ils ne font par de l'interprétation mais de la génération de bytecode à la volée.

                  C'est ce qui explique qu'il soit très rapide sur PC (à peine moins que python) et que leurs perf tombent en chute libre sur Android (parce que DalvikVM et non JVM).

                  JS/Rhino est 10x moins rapide sur Dalvik selon mes petit benchmarks à moi ^_^

                  Pour ce qui est du tokener, je pense que c'est une mauvaise contraction. Mais on c'en fiche, on est pas là pour faire de la littérature.

                  Dans mon langage à moi. Je n'ai ni cast, ni méthode vide.... je te laisse réfléchir comment je m'en suis sorti. ^_^

                  -
                  Edité par CyaNn 10 juin 2013 à 9:18:44

                  • Partager sur Facebook
                  • Partager sur Twitter
                  Découvrez Algoid le langage pour apprendre à programmer.
                    10 juin 2013 à 10:00:16

                    Bonjour et bravo pour ton projet.

                    Petite précision, Linotte n'utilise pas les pointeurs...

                    Il utilise le symbole Astérisque mais il n'a pas la même définition qu'en C. (quoique)

                    En Linotte, tout est objet, une chaine est un objet , un nombre est un objet.

                    Ainsi ce code va vous paraitre étrange :

                    principale :
                    	a :: nombre 
                    	c :: casier de nombres
                    	début
                    		a vaut 1
                    		ajoute a dans c
                    		a vaut 2
                    		ajoute a dans c
                    		a vaut 3
                    		ajoute a dans c
                    		affiche c


                    le résultat est 3 3 3. D'autres langages "trichent", par exemple, en Java, les nombres et chaînes sont immuables.

                    J'en reviens à mon astérisque...

                    Lorsque j'ai ajouté la notion de fonction en Linotte, j'ai voulu garder le principe du tout objet et ne pas avoir d'objet immuable.

                    L'appel des fonctions est donc par référence ou par adresse : on se rapproche de la notion de pointeur mais le pointeur n'existe pas en tant que tel en Linotte car il n'est pas manipulable.

                    Bonne journée.

                    • Partager sur Facebook
                    • Partager sur Twitter
                      10 juin 2013 à 10:14:07

                      Ha ouep. En AL, j'ai justement voulu éviter ce genre de principe. Je trouve que cela induit trop d'erreur.

                      Par contre je ne qualifierais pas ça de "tout est objet" mais plutôt "tout est pointeur".

                      Objet, pour moi signifie que 7 possède des méthodes, par exemple.

                      Un petit exemple en AL :

                      set a = (7).addition(2).multiply(2);

                      D'ailleurs, en linotte, vue que tout est référence, cela induirait que 7 devienne 20 à la fin de l'opération !?!?!?!? non ?

                      Je voulais faire comme ça au début, mais cela créait beaucoup de comportement imprévisibles et du coup compliquait l'apprentissage du langage.

                      Dans ce cas, il aurait fallu écrire :

                      set a = (7).clone().addition(2).multiply(2)

                      Mais ce sont des choix. Bonne continuation à vous deux.

                      • Partager sur Facebook
                      • Partager sur Twitter
                      Découvrez Algoid le langage pour apprendre à programmer.
                        10 juin 2013 à 11:47:54

                        Nannnn mais c'est un truc de fou ! Le concepteur du langage Linotte en personne !
                        Je rectifie tout de suite cette erreur. Merci de vos visites ! C'est très encourageant.

                        • Partager sur Facebook
                        • Partager sur Twitter
                        Arius, vraiment le plus puissant de l'ancienne Ligue des Super Zéros !
                          10 juin 2013 à 13:23:21

                          Voilà, problème du NoSuchMethodError rectifié, on peut maintenant écrire n'importe quel caractère Unicode dans la console, gestion des erreurs un peu améliorée : JAR ici
                          Il faut le JRE 7. Testé sous Ubuntu 13.10 avec OpenJDK 7, et Windows XP avec la JVM Oracle cette fois :-)

                          -
                          Edité par antoine1023 10 juin 2013 à 13:44:33

                          • Partager sur Facebook
                          • Partager sur Twitter
                          Arius, vraiment le plus puissant de l'ancienne Ligue des Super Zéros !
                            10 juin 2013 à 20:59:04

                            Hop ! Mise à jour !

                            • Réécriture de l'analyseur lexical
                            • Ajout instruction si, assez proche du if de C, en pseudo-BNF : "si" "(" expressionTest ")" expression ["sinon" expression]
                            • Implémentations des opérateurs de comparaison "sup", "inf", "supegal", "infegal"
                            • Ca y est ! Ajout des fonctions absolue, carre, racineCarre (je m’aperçoit à l'instant qu'il manque un 'e'...), cos, sin, tan, acos, asin, atan au type flottant. 16,0.racineCarre() retourne 4,0.
                              Noter que si on stocke une de ces fonctions dans une variable, on ne peut pas l'appeler au moyen de cette variable. Ainsi :

                                fonction = 2,0.cos
                                cos()
                              

                              .... ne marche pas.

                            • Correction de bugs énormes, avant 2 * 3 retournait 5 ... Maintenant, la récursivité est possible.

                            J'ai mis un exemple de factorielle :p

                            factorielle = { x :
                            si (x infegal 1) (
                                    1
                                ) sinon (
                                    x * factorielle(x - 1)
                                )
                            }
                            
                            a = 5
                            
                            Console.ecrireLigne("Factorielle de " + 5 + " : " +
                                factorielle(a))
                            

                            EDIT : J'oubliais : on peu mettre plusieurs instructions entre deux parenthèses : (5 6 7)
                            Elles sont toutes évaluées, et seule la dernière est renvoyée (ici 7). Comme pour les fonctions.

                            -
                            Edité par antoine1023 10 juin 2013 à 21:01:40

                            • Partager sur Facebook
                            • Partager sur Twitter
                            Arius, vraiment le plus puissant de l'ancienne Ligue des Super Zéros !
                              10 juin 2013 à 22:48:58

                              En AL ça marche :

                              set f = (2).multiply
                              util.log(f(5))

                              donne

                              // donne 10

                              nananèreu.... :p:p:p:p:p:p:p

                              Sinon j'aime bien la notation (1 2 3 4) c'est sympa.

                              Par contre je ne suis pas très fan des comportements à la python qui consiste à prendre un "premier" ou un "dernier" si le traitement de la suite n'est pas permis.

                              Je ne suis pas très fan non plus des opérateur en text. J'ai du mal à les lire. Question d'habitude peu-t-être.

                              -
                              Edité par CyaNn 10 juin 2013 à 22:50:38

                              • Partager sur Facebook
                              • Partager sur Twitter
                              Découvrez Algoid le langage pour apprendre à programmer.
                              Anonyme
                                11 juin 2013 à 7:18:22

                                Bonjour,
                                Antoine1023, je te souhaite tout simplement bon courage. Moi j'ai en effet 19 ans, je passe en L3 et je ne sais toujours pas créer un langage de programmation. Mais tu viens d'allumer en moi la lumière de la motivation. Ce serait d'ailleurs très sypmathique si vous (toi y compris les autres initiés) pouvez m'indiquer ce que vous avez lu comme tutoriel. Je lis actuellement Compilateurs - Principes, Techniques et Outils. Les auteurs y mentionnent en effet les principes sur les langages de programmation, quitte à créer un compilateur digne de ce nom.
                                Quant à ton langage, disons le L, je le trouve intéressant même si je ne comprends pas pourquoi il autorise des opérations comme 2,3.factorielle(): la factorielle d'un nombre n'est-elle pas définie que pour des entiers naturels ? Bon courage !

                                • Partager sur Facebook
                                • Partager sur Twitter
                                Anonyme
                                  11 juin 2013 à 9:17:36

                                  leMédaillon> Sur internet on trouve pas mal de forums avec des gens qui connaissent bien le domaine. En cherchant un peu au hasard on peut tomber sur ce sujet, écrire un compilateur pour un langage impératif.

                                  • Partager sur Facebook
                                  • Partager sur Twitter
                                    11 juin 2013 à 9:52:35

                                    "2,3.factorielle()"... En effet, c'est une enorme gaffe de ma part !
                                    Sinon, je n'ai pas spécialement suivi de tuto à la lettre. C'est vrai qu'il en existe beaucoup pour Caml, mais je ne connais pas du tout ce langage. Il y a aussi des outils très puissants comme Lex, Yacc et JavaCC.
                                    Je me suis pas mal servi de Wikipedia, de sources et de documentations plus générales sur les parsers et les lexers.

                                    • Partager sur Facebook
                                    • Partager sur Twitter
                                    Arius, vraiment le plus puissant de l'ancienne Ligue des Super Zéros !
                                      11 juin 2013 à 12:32:10

                                      Voici les outils qui existent en java : http://java-source.net/open-source/parser-generators

                                      SableCC est celui qui ce rapproche les plus de mon parseur cousu main ;-) Quoi qu'il ne soit pas aussi orienté objet qu'il ne le prétend.

                                      • Partager sur Facebook
                                      • Partager sur Twitter
                                      Découvrez Algoid le langage pour apprendre à programmer.
                                        11 juin 2013 à 12:45:03

                                        Ah merci, je regarderais, je ne connaissait pas.
                                        Je crois que j'ai une idée de nom : smallFrench

                                        • Facilement mémorisable, je trouve que ça sonne bien ;
                                        • On voit tout de suite qu'il s'agit d'un langage ;
                                        • Fait référence à SmallTalk sans copier le nom en entier (contrairement à JavaScript et Java) ; en effet, je me suis inspiré des définition de fonction de SmallTalk ; autre rapport : le "tout objet" ;
                                        • Le nom est en Anglais et contient "French" : cela souligne la particularité de ce projet, un langage informatique français ;
                                        • Ça ne fait penser ni à Algobox, ni à Linotte ; On ne trouve pas grand chose sur Google et rien à l'INPI (bon je ne pense pas qu'il faut leur déposer les projets open-source...) ;
                                        • Small -> petit, donc "simple" d'une certaine manière ;

                                        A mon avis, ce n'est pas trop mal... De toute façon, ce qui compte, ce n'est pas tellement le nom, mais surtout ce qu'on fait avec.
                                        Qu'en pensez-vous ?

                                        • Partager sur Facebook
                                        • Partager sur Twitter
                                        Arius, vraiment le plus puissant de l'ancienne Ligue des Super Zéros !
                                        Anonyme
                                          11 juin 2013 à 12:53:25

                                          Pour les forums, on n'y trouve pas grand chose. Mais je vais encore chercher.
                                          Sinon, en ce qu'il concerne le nom que tu choisiras pour ton langage, je trouve que le L fait plus stylé mais smallFrench reste aussi un bon choix. Toutefois, je pense que cela devrait être le dernier soucis d'un codeur de langage ; l'essentiel est ce que propose le langage comme fonctionnalité. Bon courage !

                                          • Partager sur Facebook
                                          • Partager sur Twitter
                                          Anonyme
                                            11 juin 2013 à 13:29:11

                                            Pour les forums, on n'y trouve pas grand chose. Mais je vais encore chercher.

                                            Mais on peut aussi y poser des questions quand on en a.

                                            Sinon, je n'ai pas spécialement suivi de tuto à la lettre. C'est vrai qu'il en existe beaucoup pour Caml, mais je ne connais pas du tout ce langage. Il y a aussi des outils très puissants comme Lex, Yacc et JavaCC.

                                            L'analyse syntaxique ça n'est au final qu'une petite partie du travail de compilation. Oui, il y a beaucoup d'outils pour faire ça (dans tous les langages), mais le gros morceau d'un compilateur ou d'un interpréteur, ça reste à faire à la main.

                                            • Partager sur Facebook
                                            • Partager sur Twitter
                                              11 juin 2013 à 14:31:48

                                              Bien sûr ^^
                                              Je m'en rends compte surtout maintenant, en implémentant les fonctions et opérateurs des types primitifs... Il y a pas mal de boulot :-p

                                              • Partager sur Facebook
                                              • Partager sur Twitter
                                              Arius, vraiment le plus puissant de l'ancienne Ligue des Super Zéros !
                                                11 juin 2013 à 18:48:06

                                                C'est bon pour le nom : je prends smallFrench
                                                Voilà, j'ai réparé mon erreur : celle de m'être "amusé" à écrire l'interpréteur en Anglais. Maintenant, à peu près tout est en français. J'ai "javadocumenté" un peu, n'étant pas spécialiste absolu du Java non plus, j'èspère que vous lirez facilement mon code... Si vous avez des questions ou des remarques, n'hésitez pas à me demander.
                                                D'aileurs, pour les packages, il faudrait renommer en "org.smallFrench.*", non ?
                                                Voici la page du projet !
                                                Je vais écrire une petite référence dans le Wiki. Et bien sûr, pour participer, n'hésitez pas à MP.

                                                -
                                                Edité par antoine1023 11 juin 2013 à 18:49:15

                                                • Partager sur Facebook
                                                • Partager sur Twitter
                                                Arius, vraiment le plus puissant de l'ancienne Ligue des Super Zéros !
                                                  12 juin 2013 à 16:19:13

                                                  smallFrench, pourquoi pas... mais pourquoi pas petitFrançais ? ;)

                                                  C'est dommage de prendre un nom anglais pour un langage de programmation en français ?

                                                  -
                                                  Edité par metalm 12 juin 2013 à 16:46:18

                                                  • Partager sur Facebook
                                                  • Partager sur Twitter
                                                    12 juin 2013 à 19:51:41

                                                    C'est vrai qu'on peut trouver smallFrench étrange, mais "petitFrançais" ça me plait pas trop... Et puis ce nom ne risque pas d'être très disponible ^^.
                                                    "Algobox" ne fait pas très patriotique non plus :-)
                                                    Et puis, comme dit leMédaillon, "l'essentiel est ce que propose le langage comme fonctionnalité". Et puis, la flemme de chercher trop longtemps !
                                                    Sinon, je vais essayer de bien regarder les sources de Linotte, ça m'intéresse beaucoup. Je m'aperçoit que c'est vraiment un gros projet très complet en fait, je le croyais plus petit. Par comparaison, Algobox ne contient même pas de parser...

                                                    • Partager sur Facebook
                                                    • Partager sur Twitter
                                                    Arius, vraiment le plus puissant de l'ancienne Ligue des Super Zéros !
                                                      12 juin 2013 à 21:29:08

                                                      Oui, c'est un plutot gros projet... mais attention, parser lexer, etc... j'ai découvert ça bien après le début du projet... Ce n'est pas l'état de l'art mon code :-°
                                                      • Partager sur Facebook
                                                      • Partager sur Twitter
                                                        12 juin 2013 à 23:23:58

                                                        Parseur + lexer m'ont pris 6 mois de mise au point.

                                                        Langage 6 mois de plus, et 6 pour la doc, l'IDE et la "promo". Ce dernier point étant le plus chronophage et le moins satisfaisant.

                                                        • Partager sur Facebook
                                                        • Partager sur Twitter
                                                        Découvrez Algoid le langage pour apprendre à programmer.
                                                          13 juin 2013 à 7:53:10

                                                          Au fait, j'ai dans l'idée de passer mon parseur en open source. Ou du moins de filer le jar et un tuto en attendant.

                                                          Cela vous intéresserait-il ?

                                                          Ses features sont :

                                                          - Packrat (LL(k), backtracking + memorizer)

                                                          - Définition de la syntaxe par programmation (à l'aide de comportements composites, pas de langage tiers de type BNF)

                                                          - Syntaxe découplé de la sémantique (possibilité de langages multi-syntaxes)

                                                          - Possibilité de syntaxe / sémantique multi couches

                                                          - Une approche generique des différents modules (pas de transtypage nécéssaire au runtime)

                                                          Bon avant tout de fournir tout ça, il va falloir que je documente un poil le tout.... ^_^

                                                          • Partager sur Facebook
                                                          • Partager sur Twitter
                                                          Découvrez Algoid le langage pour apprendre à programmer.
                                                            13 juin 2013 à 9:07:36

                                                            Ca peut en interesser d'autres, mais moi je n'ai pas trop envie de changer smallFrench de parser tout de suite :-) Là je suis plutot sur l'interface, je vais voir pour la coloration syntaxique.
                                                            Mais si il est open-source, je regarderais.

                                                            -
                                                            Edité par antoine1023 13 juin 2013 à 9:11:05

                                                            • Partager sur Facebook
                                                            • Partager sur Twitter
                                                            Arius, vraiment le plus puissant de l'ancienne Ligue des Super Zéros !
                                                            Anonyme
                                                              13 juin 2013 à 10:19:52

                                                              Ah au fait tu parles de tuto. J'imagine que cela intéresserait beaucoup de personnes. Mais pour m'en rassurer, je voudrais savoir ce dont tu veux parler concrètement dans ton tuto. Clairement, quel est l'objectif de ton tuto ?

                                                              • Partager sur Facebook
                                                              • Partager sur Twitter

                                                              [Langage] Petit langage impératif

                                                              × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
                                                              × Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
                                                              • Editeur
                                                              • Markdown