Ikand (Attention: Obselète nouveau sujet quand projet sera bien avancé)

a marqué ce sujet comme résolu.

Obselète nouveau sujet quand projet sera bien avancé parce que j'ai ouvert un sujet trop tot

Bonjour,
Je m'appelle Adrien, j'ai 14 ans (13, mais bon, à moins de 2 mois près :p ), et vous me trouverez sur forums/jeux etc… sous le nom d'Ardakaniz. Je suis passionné d'électronique, de musique (j'essaye de faire des morceaux, en vain… :D ) et aussi et surtout, la programmation (celui qui va nous servir ici), mais je ne programme pas en beaucoup de langages , j'ai touché à du C, du JS, Haskell, mais mon préféré que j'utilise depuis 4 ans maintenant environ et que je connais les bonnes bases + certaines notions plus avancées (exceptions, itérateurs, templates variadiques, etc…) est le C++ !
Assez parlé de moi ! Je vais vous parler de mon projet aujourd'hui: Ikand (à prononcer I can't :p ).

Genèse

Depuis toujours, j'ai voulu faire un langage de programmation (parce que oui, je parle bien d'un langage de programmation, mon objectif n'est pas de faire une langue croisé de japonais et d'anglais hein :D), là preuve. N'en parlons pas, j'ai honte x) Bref, sur une discussion en privée sur Zds, ont échangeait des idées de syntaxe de langage, et j'en ai donné au moins quatre :D avant de tomber sur la bonne (enfin j'espère), et du coup, j'ai commencé à la coder, j'ai eu (et j'ai encore) plusieurs problèmes, d'ailleurs, merci @gbdivers, @Ksass`Peuk, @Lynix, @Dutiona pour m'avoir aidé. Et puis j'ai aussi vu le sujet de jejeleterrible58 et me suis dit, bon allez, je me lance.

Généralités et avancement

Je suis en train de me documenter sur LLVM, que je vais utiliser pour m'obliger à avoir une vrai structure d'interpréteur niveau code et avoir quelque chose d'opti. Sinon, le lexer est quasiment terminé si ce n'est complétement, je suis en train d'attaquer l'AST

Objectifs

M'améliorer en C++, apprendre de nouvelles notions, etc… et aussi avoir un projet concret, un partenaire (je vais développer la partie recrutement plus loin), et une petite communauté qui me suive ;)

Dépot Git TODO: Update le code et rajouter des exemples commentés

Merci de m'avoir lu,
Ardakaniz

+0 -0

Oh, mais oui bien-sûr, désolé ! Je posais ma question après avoir visité le GitHub du projet, et il m'a semblé voir un bon petit paquet de code déjà, mais n'ayant jamais rien compris au C++, je n'ai pas pu estimer l'avancement…

+1 -0

Ouais, c'est vrai que y a du code sur Git, mais ce que je fais, c'est que je pose les bases, et apres j'implente le truc ;) . Donc j'ai les bases pour les variables, je pourrais commencer à l'implanter, mais en ce moment je m'occupe du parsing plutôt.

J'ai fini de gérer les namespaces y'a 2 heures environ et le parsing des fonctions est presque complètement fonctionnel (on va dire 90%), il me reste donc à l'inter mon système de variables et les variables seront fonctionnel ! :)

EDIT: Mais voulant faire une pause parce que j'ai eu la sensation d'être deprimé ou je ne sais pas quoi, c'est la deuxième fois que ça m'arrive (trop de stress peut être), je suis donc en train de download Team Fortress 2 :)

EDIT2: je viens de regarder mon GitHub et je me suis rendu compte que j'ai pas fini un fichier: https://github.com/Ardakaniz/Ikand/blob/src/cpp/include/Class/Variable.hpp#L12 :lol: mais j'ai pas dû l'inclure dans VS parce qu'il m'a rien dit le compilo

+0 -0

Première fois que je vois un sujet de ce genre avec un peu plus de réflexion sur le sujet et le design du langage que "je veux faire du C mais en Français!". C'est un beau projet !

J'ai regardé plus en détail. En fait, c'est une lib qui permet de faire un compilo ?! Ça pourrait m'être super utile ! Mais j'arrive pas à comprendre comment ça marche, tu pourrais m'expliquer plus en détail ?

LLVM est une bibliothèque pour faire des compilateur/interpréteurs avec optimisations. En gros tu dois transformer ton code en LLVM IR (indermediate representation) qui est une sorte d'assembleur abstrait, et ensuite LLVM t'optimise le tout et te sort des exécutables. Il y a aussi plusieurs modules de JIT (compilation en temps réel) pour faire des interpréteur/compilateurs JIT, et je crois qu'il y a même un interpréteur.

L'avantage principal du truc, c'est que c'est LLVM qui te fournit les backend de compilation: tu écris du LLVM IR et LLVM te sort du code Windows, Linux, BSD, pour achitectures x86, x86_64, ARM, ASM.js, …

Petites remarques en passant: si tu as envie de faire un langage de script (un langage n'est pas interprété, une implémentation du langage l'est), forcer la présence d'une fonction Main n'est pas super ergonomique. Et pourquoi les opérateurs ne sont-ils pas simplement des fonctions ?

Je vois que tu as mis des classes dans ton exemple, tu prévois de faire de l'héritage dans ton système de types ?

+0 -0

Forcer la présence d'une fonction Main n'est pas super ergonomique. Et pourquoi les opérateurs ne sont-ils pas simplement des fonctions ?

Luthaf

Bah en fait j'ai choisi de faire un langage interprété parce que, pour moi, c'était plus simple et j'ai absolument aucune idée de comment faire à part transcrire le code en C++ mais ça limite les choses non ? Et j'oblige une fonction Main car c'est aussi plus simple à gérer. En fait, dans mon code, j'ai deux classes: GlobalEnvironment et LocalEnvironment. Dans GlobalEnvironment, j'autorise que les fonctions/opérateurs/classes/énumérations/flats et à la toute fin de l'interprétation de cet environnement, je fait un appel à une fonction Main. Ça plante si elle existe pas donc.

Pour les opérateurs, en fait ce sont des fonctions mais spéciales. Les fonctions ne peuvent avoir qu'un seul paramètre. Mais pour contourner ça, on peut utiliser un tuple. Elles sont appelle comme ça aussi: Func <- Arg ou Arg -> Func. Les opérateurs, eux, prennent deux valeurs et doivent en renvoyer une obligatoirement. Et sont appelé : Var op Var

Pour LLVM, il faut donc connaître le LLVM IR et transmettre son code en ça, comme il aurait fallu faire pour Ikand -> C++ donc encore une fois, ça peut être limité non ?

@Luthaf: Heu, j'ai 14 ans, donc bof à l'aise avec l'anglais mais je peux voir si je me débrouille. Et oui, un tuto ça pourrais être plus qu'intéressant :)

Les fonctions ne peuvent avoir qu'un seul paramètre. Mais pour contourner ça, on peut utiliser un tuple.

J'ai lu que tu avais touché un peu à Haskell. Donc, pour contourner ça tu peux y aller par les tuples oui, mais sinon t'aurais pas une autre idée pour faire plus consistant et propre ? Un peu comme Haskell le fait, peut-être ? :)

+0 -0

Le processus « canonique » d'une compilation c'est ça :

Mettons qu'on aie une expression mathématique, comme 2 + 5 * 8 - 4. On veut transcrire cette expression en langage machine.
Pour commencer, on va faire une analyse lexicale, c'est à dire une transformation du texte en une liste de lexèmes, qui sont les unités de base du langage (un peu comme les lettres d'un alphabet). A la fin, on se retrouve avec quelque chose comme Num(2) Plus Num(5) Mul Num(8) Moins Num(4).

Ensuite, on a l'analyse syntaxique. Ici, l'objectif va être la construction d'un arbre de syntaxe, pour définir les relations entre les lexèmes. Dans notre expression, ça va consister à appliquer les règles de priorité des opérateurs. L'arbre résultant est ceci :

1
2
3
4
5
6
7
          Moins
         /    \
       Plus  Num(4)
      /    \
    Mul   Num(2)
   /   \
Num(5) Num(8)

Après avoir vérifié la cohérence de l'arbre (analyse sémantique), on peut générer la représentation intermédiaire, qui ressemblera à ça :

1
2
3
%1 = mul 5, 8
%2 = add %1, 2
%3 = sub %2, 4

Puis, on passe par une phase d'optimisation. Ici, on aurait typiquement du constant folding, qui donnerait ça :

1
%1 = 38

On peut directement calculer le résultat vu qu'on travaille sur des constantes, donc autant le faire.

Enfin, on envoie la représentation intermédiaire au backend, qui peut la compiler vers du code machine, l'exécuter en JIT, etc.

Pour revenir à LLVM, tu ne génère pas le code toi même, tu as des outils pour. Par ex :

1
2
3
4
llvm::IRBuilder builder;
auto mul = builder.createFMul(llvm::Constant(5), llvm::Constant(8));
auto add = builder.createFAdd(mul, llvm::Constant(2));
auto sub = builder.createFSub(add, llvm::Constant(4));

J'ai simplifié la structure, mais c'est l'idée.

+2 -0

Pour la fonction Main, je pense que je vais la rendre facultative, mais si l'utilisateur veux avoir les arguments d'entré du programme, il devra l'utiliser.

Pour les paramètres d'une fonction par tuple, je pense que ça peux le faire: func (Arg1, Arg2, Arg3) -> Func, c'est clair non ?

Merci beaucoup Praetonus, je vais creuser dans cette direction (du coup, tout recommencer je pense :p ).
J'ai dirait des nouvelles demain, Dimanche, je vais pas pouvoir avancer, je vais aux Utopiales :)

Re,
Je suis en train d'essayer l'analyse lexicale et syntaxique sur Coliru, mais j'ai toujours le même problème qu'avant: Comment gérer la mémoire ? J'arrive vraiment pas à faire un système potable et propre :(

EDIT: Sachant que je voudrait des variables dynamiques, donc qui peuvent changer de types (si possible, genre pas une chaîne: "Bonjour" convertie en Int ou autre nombres…)

+0 -0
Connectez-vous pour pouvoir poster un message.
Connexion

Pas encore membre ?

Créez un compte en une minute pour profiter pleinement de toutes les fonctionnalités de Zeste de Savoir. Ici, tout est gratuit et sans publicité.
Créer un compte