[ngl] Création d'un langage de programmation générique

a marqué ce sujet comme résolu.

Neuroshok Generic Language

Le but de ce projet est de créer un langage de programmation orienté généricité.

Serveur discord du projet : https://discord.gg/8sB4rTF

Concept général

Le langage défini toute information en tant que data. Ces informations seront connectées entre elles de différentes façons afin de créer une logique.

Afin d’ajouter du sens à ces informations, elles doivent être décrites par une entité logique appelé descriptor. Une entité logique est une information concrète qui possède des concepts et une logique. La description d’une information se fait à partir d’un descripteur, qui devra donc se décrire lui même

Les data sont séparées en deux grandes parties, les concept ajoutant une logique à une information et les concrete représentant une concrétisation d’un concept dans l’environement du programme.

Voici un aperçu des spécificités prévues:

  • Syntaxe

    • Le code devra être facile à lire et à écrire (pas d’excès de symboles)
    • La syntaxe sera uniforme (pas de spécificité selon la sémantique)
  • Logique

    • Le langage utilisera des concepts pour la généricité des programmes

    • Une même entité logique (programme, IA ..) possèdera une seule version de ses concepts

    • Les concepts de différentes entités seront compatibles et substituables (dans le but d’éviter la redondance de concepts similaires au sein d’un programme utilisant plusieurs dépendances)

    • Chaque concept du langage sera parametrable

  • Concrétisation

    • Le code source d’un programme étant un concept, il sera concrétisé en passant par plusieurs phases
    • La concrétisation d’un concept doit permettre de pouvoir modifier le concept en cours de concrétisation (metaprog)
    • La librairie du langage fournira les concepts nécessaires à la création de programme/projets (un système de build externe ne sera pas nécessaire)

Objectif

Dans un premier temps, le but sera de définir le langage, écrire la documentation et quelques concepts de la librairie standard tout en écrivant du code de test pour vérifier la cohérence du langage.

Une fois les bases du langage bien définies, l’écriture du compilateur sera envisageable. Il sera codé en C++ avec LLVM.

Recrutement

Je cherche donc des personnes intéressées par

  • la définition du langage et de ses concepts
  • l’écriture de code ngl de test
  • l’implémentation expérimentale de fonctionnalités du compilateur

Et pour finir, voici un exemple simple de code :)

ngl:concept:container matrix
{
    ngl:concept:number <rows> // 1
    ngl:concept:number <columns> // 2
    ngl::concept:size ( rows * columns )
    
    <data_type> :data // 3, redescribe :data from ngl::container
}

// parameters order
matrix<4, 2, ngl::float> float_matrix;

: c’est une connexion logique entre 2 identifiers source:alpha:zeta:target

:: lorsque le symbole d’une connexion est dédoublé, le chemin est déduit source::target

<> c’est pour la paramétrisation

() c’est pour les expressions

{} pour les ensembles

J’ajouterai des symboles si il y a trop de code redondant, par exemple j’ai ajouté ^ récemment pour accéder au contexte top-level mais ça se fera au fur et à mesure en écrivant du code. Mais l’idée c’est de ne pas trop en avoir pour que ça reste lisible facilement et éviter les symboles avec plusieurs sens.

Ça a l’air plutôt intéressant ! Je participerais volontiers à la conception, voire au dev (par contre j’ai jamais fait de C++ :-° )

Par contre, est-ce que tu pourrais donner un exemple de programme en entier pour mieux saisir ? Genre tu fais la multiplication de deux matrices ?

Bon courage pour la suite !

Je vais faire un serveur discord pour faciliter les échanges et voir si ça intéresse assez de monde. https://discord.gg/8sB4rTF

Je n’en suis pas encore à l’écriture de programmes complets, il y a pas mal de choses à faire avant comme approfondir la définition de la concrétisation et des concepts de la librairie standard. C’est pas si facile car comme le but est d’avoir un langage générique, la définition des concepts est très importante.

D’ailleurs le discord serait pratique pour avoir des avis sur du code expérimental. J’en ajouterai régulièrement dessus.

Salut,

La doc avance doucement pour essayer de clarifier toutes les idées : https://github.com/ads00/ngl/blob/master/doc/index.md

J’ai ajouté plusieurs concepts :

  • les "rule" qui permettent de créer des règles logiques pour les informations
  • les "shape" qui permettent de définir une forme logique pour une donnée via l’utilisation des "rule"

Cela permet par exemple d’ajouter au langage le concept de constante

ngl constant
{
    <ngl:data>
    ngl:rule
    {
        ! ngl:edge // refuse all edges
        ngl:edge:read // allow read edge
    }
}

ngl:constant<4> my_int
my_int = 3 // ngl add the edge write from my_int to literal_3
           // ngl:edge<ngl, my_int, literal_3, write>
           // broken rule
an_int = my_int // ngl add the edge read from an_int to my_int
                // ngl:edge<ngl, an_int, my_int, read>
                // ok

On pourrait donc également créer une règle pour une division

ngl:rule no_zero
{
    ngc:number <value>
    ngl:rule (value != 0)
}
ngl:function divide
{
    ngc:int <x>
    ngc:int <y>
    
    ngl:rule:no_zero<y>

    .result (x / y)
}

Ce qui facilitera la généricité sur la gestion des erreurs.

Les "shape" permettront aussi de gérer tout ce qui est syntaxe, formats, langages de grammaire etc .. Pour par exemple ajouter la gestion du xml dans un code source, avoir un système de log avec une syntaxe plus pratique etc ..

ngl:concept digit
{
    ngl:data <value>
    ngl:rule
    {
        value == ('0' | '1' .. | '9')
    }
}

Je passerai ensuite à la gestion des "edge" puis on recommencera à faire des tests :)

Salut !

J’avais commencé des tests pour le compilateur avec antlr4 mais comme j’aimerais pouvoir ajouter des règles pour le lexer pendant la compilation, je vais plutôt partir sur un truc maison.

Le but du jeu est donc de définir la syntaxe du langage avec le langage en essayant de faire mieux qu’avec une lib (pegtl comme référence).

Pour ça on va juste utiliser le principe des rules, avec la forme la plus générique ça donne :

ngl:data bidule
{
    ngl:rule
    {
        expression_logique1
        expression_logique2
    }
}

Pour simplifier ça, on va utiliser les shapes, ce qui donnerait

ngl:shape:element comparison [==] // == doit exister 

ngl:shape comparison_expr // truc == bidule
{
    comparison_expr == [ngl:shape:identifier comparison ngl:shape:identifier]
}

Il faut bien sur des éléments primitifs pour ces descriptions, l’objectif est d’en avoir le moins possible et qu’ils puissent être redéfinis.

Salut,

Le lexer fonctionne pour plusieurs types de règles basiques, côté performance c’est assez variable en fonction du compilateur. Plus rapide que pegtl avec msvc, un peu moins rapide avec clang.

Un ensemble de règles pour une syntaxe est défini dans un shape_cluster, le lexer peut donc changer de shape_cluster ou les modifier pendant le lexing.

Pour les règles de parsing, il faut encore décider comment les lier au lexer.

La doc et le design du langage se peaufinent.

Le lien entre une shape et un concept sera fait via un edge.

ngl:shape add
{
     ngc:sequence< ngs:identifier ngs:plus ngs:identifier >
}

ngl:concept:math sum
{
    ngc:math:number n1
    ngc:math:number n2

    ngc:math:number .result
}

ngl:edge<ngl, ngl:shape:add, ngl:concept:math:sum>
// ngs:identifier[0] -> n1 
// ngs:identifier[1] -> n2 

Merci à Monax pour l’inspiration :p

Salut,

Voici un début de documentation http://dev.neuroshok.com/ pour aider à faire comprendre le langage avec le squelette prévu pour présenter tous les aspects d’un langage. La documentation plus technique sera dans doc/reference.

Côté langage il y a quelques nouveautés pour le compilateur et la gestion des projets, c’est dans la doc !

Salut,

J’ai réorganisé les repos github pour avoir une séparation entre le design du langage, les sites, le compilateur etc ..

Tout sera ici : https://github.com/neuroshok

La doc avance, côté design je réfléchis à la gestion du vcs et du build system. Pour le compilateur, qui en fait sera plus un outil de dev (compilateur + vcs + build + config) j’ai commencé un système de gestion de commandes afin de gérer tout ça plus facilement.

    ncs_node(project)
        ncs_command(add)
            ncs_parameter(std::string, name, "Project name")
            ncs_parameter(std::string, vcs, "Init VCS", "git"s)
        ncs_command_(add, [this](auto&& input){ std::cout << input[add.vcs];cli.compiler.process("test", 0);  }, "Add a new project")
    ncs_node_(project)

Voila voila, j’accepte toujours les contributions si il y a des intéressés :)

Un peu de code experimental pour les build system :

ngl:ecosystem:project raz
{
    .name [RaZ]

    .config: [release] //

    .option
    {
        link_type [static]
    }

    .compiler // require parameterization, later
    {
        .standard [cpp17]
        (.option ++ [ -DNOMINMAX])
    }

    .concept // use a specific shape
    {
        include/RaZ/*
        source/RaZ/*
    }

    .concrete // use a specific shape
    {
        assets
        shaders
    }

    .cluster // clusters (projects, concept clusters) required by this project
    {
        npc:catch<config: release> // ngl project cluster
        npc:imgui
    }

    ngc:cluster_entity raz_cluster
    {
        .name [razlib]
        .link_type option:link_type
    }

    ngc:project examples // subproject
    {
        .cluster raz_cluster // all examples require raz_cluster
        ngc:program fulldemo
    }

    ngc:install
    {
        .location "c:/raz"
    }
}

// parameterization
raz<compiler.name: [gcc]>
{
    (compiler.option ++ [ -DRAZ_COMPILER_GCC=ON]) // add sugar
    (compiler.option ++ [ -pedantic])
    ngl:branch<compiler.version>
    {
        (>= 6) (compiler.option ++ [-Wnull-dereference])
        (>= 7) (compiler.option ++ [-Waligned-new])
    }
}


raz<option: option.libpng>
{
    .cluster npc:libpng
}

// debug_info identifier is described as a concrete data using the markdown shape with $ as a delimiter
ngs<markdown> debug_info
{
    ############ raz debug
    *host system* : $ ngl:environment:host_name $
}
// nc raz print debug_info

Salut,

Quelques nouvelles idées :

  • La meta parameterization :
ngc array
{
    <ngc> type
    ngc:integer <size>
}

ngc resizer
{
    ngc <data> // data is ngc:array<ngc:integer, ?>
    
    ngc:integer interal_size [12]
    
    ngl:meta<data>.parameterize<internal_size>
}

// parameter <size> missing
ngc:resizer<ngc:array<ngc:integer, ?>>
{
    
}

ngc:resizer<ngc:array<ngc:integer>>

Cela permet à l’identifier paramétré par un identifier paramétré partiel de paramétrer ce dernier (J’ai pas trouvé comment le dire autrement :p)

  • Une autre façon de gérer les shapes
20 | ngs<html, 25>
21 | <p>this is</p>
22 | <b>html code</b>
23 | until
24 | line
25 | 25
26 | ngc ngl_code
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