{"id":25393878,"url":"https://github.com/5cover/psdc","last_synced_at":"2026-02-22T21:03:04.742Z","repository":{"id":237272952,"uuid":"740921592","full_name":"5cover/psdc","owner":"5cover","description":"Pseudocode compiler","archived":false,"fork":false,"pushed_at":"2025-04-07T06:22:37.000Z","size":5513,"stargazers_count":2,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-04-07T07:27:17.313Z","etag":null,"topics":["but-informatique","compiler","iut-lannion","pseudocode","transpiler"],"latest_commit_sha":null,"homepage":"","language":"C#","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/5cover.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2024-01-09T10:47:09.000Z","updated_at":"2025-04-07T06:22:41.000Z","dependencies_parsed_at":"2024-05-12T19:48:05.512Z","dependency_job_id":"80ad3dab-25fa-429f-bfb6-674512abd564","html_url":"https://github.com/5cover/psdc","commit_stats":null,"previous_names":["5cover/psdc"],"tags_count":2,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/5cover%2Fpsdc","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/5cover%2Fpsdc/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/5cover%2Fpsdc/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/5cover%2Fpsdc/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/5cover","download_url":"https://codeload.github.com/5cover/psdc/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248157086,"owners_count":21056950,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["but-informatique","compiler","iut-lannion","pseudocode","transpiler"],"created_at":"2025-02-15T18:54:01.578Z","updated_at":"2026-02-22T21:03:04.737Z","avatar_url":"https://github.com/5cover.png","language":"C#","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Psdc\n\nIUT de Lannion Pseudocode compiler (transpiler).\n\n## Tools\n\n[ast-gen Python](https://github.com/5cover/ast-gen)\n\n[VSCode Pseudocode extension](https://marketplace.visualstudio.com/items?itemName=NoanPerrot.pseudocode)\n\n## Philosophy\n\nPsdc is a transpiler, designed to automate the painstaking task of rewriting Pseudocode programs to other languages.\n\nGiven any Pseudocode program (valid or invalid), Psdc produces an equivalent program in the target language to the best of its ability, providing helpful diagnostics along the way.\n\n\u003cq\u003eEquivalent\u003c/q\u003e here is defined as:\n\n- **Equivalence in validity**: a valid Pseudocode program transpiles to a valid program in the target language. An invalid program (with compiler errors) may be invalid in the target language.\n- **Equivalence in behavior**: a valid Pseudocode program exhibits the expected behavior in the target language. Since Pseudocode programs can't be executed, the expected behavior of a program is determined by the Standard (yet to be written).\n- **Equivalence in semantics**: a Pseudocode program and its transpiled counterpart must be semantically equivalent. This implies:\n  - same identifiers (except where target language keywords are used)\n  - same declaration order (as possible considering the rules of the target language)\n- **Equivalence in representation**: the generated code should be human-readable and easily modifiable, with a clear correspondence between the input pseudocode and the output code.\n\nMore information in [The Zen of Pseudocode](\u003chttps://github.com/5cover/psdc/wiki/The Zen of Pseudocode\u003e).\n\n## Example\n\n### 1. Input Pseudocode ([sudoku.psc](testPrograms/sudoku.psc))\n\nMy pitiful program for S1.01\n\n```psc\n/*\nAlgorithme programme principal Sudoku\n*/\nprogramme Sudoku c'est\n\n// Un jeu de Sudoku\nconstante entier N := 3;\nconstante entier NB_FICHIERS_GRILLES := 10;\nconstante entier LONGUEUR_MAX_COMMANDE := 64;\nconstante entier COTE_GRILLE := N * N;\n\ntype t_grilleEntier = tableau[COTE_GRILLE, COTE_GRILLE] de entier;\n\ndébut\n    grilleJeu : t_grilleEntier;\n    ligneCurseur, colonneCurseur : entier;\n    partieAbandonnée : booléen;\n    commandeRéussie : booléen;\n    commande : chaîne(LONGUEUR_MAX_COMMANDE);\n\n    partieAbandonnée := faux;\n    ligneCurseur := 1;\n    colonneCurseur := 1;\n\n    chargerGrille(entE entierAléatoire(entE 1, entE NB_FICHIERS_GRILLES), sortE grilleJeu);\n\n    // Boucle principale du jeu\n    faire\n        écrireGrille(entE grilleJeu);\n        faire\n            commande := entréeCommande();\n            commandeRéussie := exécuterCommande(entE commande,\n                                                entE/sortE grilleJeu,\n                                                entE/sortE ligneCurseur,\n                                                entE/sortE colonneCurseur,\n                                                sortE partieAbandonnée);\n        tant que (NON commandeRéussie)\n    tant que (NON partieAbandonnée ET NON estGrilleComplète(entE grilleJeu))\n\n    // La partie n'a pas été abandonnée, elle s'est donc terminée par une victoire\n    si (NON partieAbandonnée) alors\n        écrireEcran(\"Bravo, vous avez gagné !\");\n    finsi\nfin\n```\n\n### 2. Psdc invocation\n\nLet's translate it to C:\n\n\u003cpre\u003e\n\u003ccode\u003e$ psdc c sudoku.psc -o sudoku.c\u003c/code\u003e\n\u003csamp\u003e\ntestPrograms/sudoku.psc:25.24-39: \u003cspan style=\"color: #f14c4c\"\u003eP0002: error:\u003c/span\u003e undefined function or procedure `entierAléatoire`\n    25 |     chargerGrille(entE \u003cspan style=\"color: #f14c4c\"\u003eentierAléatoire\u003c/span\u003e(entE 1, entE NB_FICHIERS_GRILLES), sortE grilleJeu);\n       |                        \u003cspan style=\"color: #f14c4c\"\u003e^^^^^^^^^^^^^^^\u003c/span\u003e\n\ntestPrograms/sudoku.psc:25.5-18: \u003cspan style=\"color: #f14c4c\"\u003eP0002: error:\u003c/span\u003e undefined function or procedure `chargerGrille`\n    25 |     \u003cspan style=\"color: #f14c4c\"\u003echargerGrille\u003c/span\u003e(entE \u003cspan style=\"color: #f14c4c\"\u003eentierAléatoire\u003c/span\u003e(entE 1, entE NB_FICHIERS_GRILLES), sortE grilleJeu);\n       |     \u003cspan style=\"color: #f14c4c\"\u003e^^^^^^^^^^^^^\u003c/span\u003e\n\ntestPrograms/sudoku.psc:25.24-39: \u003cspan style=\"color: #f14c4c\"\u003eP0002: error:\u003c/span\u003e undefined function or procedure `entierAléatoire`\n    25 |     chargerGrille(entE \u003cspan style=\"color: #f14c4c\"\u003eentierAléatoire\u003c/span\u003e(entE 1, entE NB_FICHIERS_GRILLES), sortE grilleJeu);\n       |                        \u003cspan style=\"color: #f14c4c\"\u003e^^^^^^^^^^^^^^^\u003c/span\u003e\n\ntestPrograms/sudoku.psc:38.43-60: \u003cspan style=\"color: #f14c4c\"\u003eP0002: error:\u003c/span\u003e undefined function or procedure `estGrilleComplète`\n    38 |     tant que (NON partieAbandonnée ET NON \u003cspan style=\"color: #f14c4c\"\u003eestGrilleComplète\u003c/span\u003e(entE grilleJeu))\n       |                                           \u003cspan style=\"color: #f14c4c\"\u003e^^^^^^^^^^^^^^^^^\u003c/span\u003e\n\ntestPrograms/sudoku.psc:29.9-21: \u003cspan style=\"color: #f14c4c\"\u003eP0002: error:\u003c/span\u003e undefined function or procedure `écrireGrille`\n    29 |         \u003cspan style=\"color: #f14c4c\"\u003eécrireGrille\u003c/span\u003e(entE grilleJeu);\n       |         \u003cspan style=\"color: #f14c4c\"\u003e^^^^^^^^^^^^\u003c/span\u003e\n\ntestPrograms/sudoku.psc:31.25-39: \u003cspan style=\"color: #f14c4c\"\u003eP0002: error:\u003c/span\u003e undefined function or procedure `entréeCommande`\n    31 |             commande := \u003cspan style=\"color: #f14c4c\"\u003eentréeCommande\u003c/span\u003e();\n       |                         \u003cspan style=\"color: #f14c4c\"\u003e^^^^^^^^^^^^^^\u003c/span\u003e\n\ntestPrograms/sudoku.psc:32.32-48: \u003cspan style=\"color: #f14c4c\"\u003eP0002: error:\u003c/span\u003e undefined function or procedure `exécuterCommande`\n    32 |             commandeRéussie := \u003cspan style=\"color: #f14c4c\"\u003eexécuterCommande\u003c/span\u003e(entE commande,\n       |                                \u003cspan style=\"color: #f14c4c\"\u003e^^^^^^^^^^^^^^^^\u003c/span\u003e\n\nCompilation \u003cspan style=\"color: #f14c4c\"\u003efailed\u003c/span\u003e (7 errors, 0 warnings, 0 suggestions).\n\u003c/samp\u003e\u003c/pre\u003e\n\nOops. Looks like we got some errors. Psdc detected that the functions and procedures called aren't defined.\n\nThat doesn't prevent it from giving us meaningful output, though.\n\n### 3. C output (sudoku.c)\n\n```c\n/** @file\n * @brief Sudoku\n * @author raphael\n * @date 12/09/2024\n */\n\n#include \u003cstdbool.h\u003e\n#include \u003cstdio.h\u003e\n#include \u003cstdlib.h\u003e\n\n#define N 3\n#define NB_FICHIERS_GRILLES 10\n#define LONGUEUR_MAX_COMMANDE 64\n#define COTE_GRILLE (N * N)\n\ntypedef int t_grilleEntier[COTE_GRILLE][COTE_GRILLE];\n\nint main() {\n    t_grilleEntier grilleJeu;\n    int ligneCurseur, colonneCurseur;\n    bool partieAbandonnée;\n    bool commandeRéussie;\n    char commande[LONGUEUR_MAX_COMMANDE];\n    partieAbandonnée = false;\n    ligneCurseur = 1;\n    colonneCurseur = 1;\n    chargerGrille(entierAléatoire(1, NB_FICHIERS_GRILLES), grilleJeu);\n    do {\n        écrireGrille(grilleJeu);\n        do {\n            commande = entréeCommande();\n            commandeRéussie = exécuterCommande(commande, grilleJeu, \u0026ligneCurseur, \u0026colonneCurseur, \u0026partieAbandonnée);\n        } while (!commandeRéussie);\n    } while (!partieAbandonnée \u0026\u0026 !estGrilleComplète(grilleJeu));\n    if (!partieAbandonnée) {\n        printf(\"Bravo, vous avez gagné !\\n\");\n    }\n\n    return EXIT_SUCCESS;\n}\n```\n\nAnd there you have it. Automated translation between Pseudocode and C.\n\n## Roadmap\n\n### Target languages\n\n- [x] C\n- [ ] LLVM\n- [ ] C#\n- [ ] CimPU\n- [ ] Java\n- [ ] JavaScript\n- [ ] Pascal\n- [ ] Perl\n- [ ] PHP\n- [ ] Python\n- [ ] Shell\n- [ ] SQL\n\n### Language features\n\n- [x] Formal grammar\n- [x] Alternatives\n- [x] Loops\n  - [x] For\n  - [x] While\n  - [x] Do..While\n  - [x] Repeat..Until\n- [x] Procedures\n- [x] Functions\n- [x] Structures\n- [x] `selon`\n- [x] Fix syntax error handling\n- [x] Lvalues\n- [x] Constant folding for type checking and division by zero\n- [x] Optional brackets in control structures\n- [x] Benchmarks\n- [x] Brace initialization (see TD14 ex 1)\n- [x] Compiler directives\n- [x] Contextual keywords\n- [x] `finPour` keyword (equivalent to `fin` but only for loops)\n- [x] Escape sequences in string and character literals\n- [x] Case-insensitive boolean operators\n- [ ] `,` (comma) operator and `` ` `` (reverse comma) operator = evaluate two expressions. comma keeps the second. reverse comma keeps the first.\n- [ ] More static analysis\n- [ ] Alternative array syntax `tableau[INDICE_DEPART..INDICE_FIN] de type;`\n- [ ] Numeroted control stuctures (`si1`, `si2`, `si3`)\n- [ ] File handling (low priority)\n- [ ] Preprocessor\n  - [x] Static assertions\n  - [x] Expression/Type probing\n  - [ ] Modularity (`#include`)\n  - [ ] Conditional compilation\n- [ ] Configuration\n- [x] [GNU](https://www.gnu.org/prep/standards/standards.html#Errors)-compliant message formatting\n- [ ] Translations : resx, fr\n- [x] CLI (use nuget package)\n  - [ ] custom header\n  - [ ] Formatting customization\n  - [ ] documentation date: now, file?\n- [ ] **Language standard**\n- [ ] Tests\n  - [ ] Errors\n  - [ ] Valid code\n- [ ] Documentation\n  - [x] CLI\n  - [ ] Language tutorials\n- [ ] Initial release\n- [ ] Sample \"real\" program\n- [ ] Self-hosting (rewrite in Pseudocode)\n- [ ] VSCode tooling\n  - [ ] Debugger\n  - [ ] Language server\n  - [x] Better syntax highlighter\n- [ ] access to argc and argv\n- [ ] transpile comments\n\n### C output configuration\n\n- [ ] Non-null-terminated-string-proof format strings: width specifier for lengthed strings (usually useless since null-terminated, but could be useful if non null-terminated strings are used)\n- [ ] Type mappings\n  - [ ] `réel` \u0026rarr; `float`, `double`, `long double`?\n  - [ ] `entier` \u0026rarr; `short`, `int`, `long`?\n  - [ ] `caractère` \u0026rarr; `char`, `tchar_t`, `wchar_t`?\n- [ ] Parameter names in prototypes?\n- [ ] Doxygen documentation skeleton?\n- [ ] `i++` or `++i`\n- [ ] Use count-based string functions: strncpy, strncmp...\n- [ ] use `puts` instead of `printf` where possible\n- [ ] anonymous block in switch cases: always, when multiple statements, when vardecl\n- [ ] anonymous block in switch default: always, when multiple statements, when vardecl\n- [ ] Doxygen keyword char : `\\` or `@`\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2F5cover%2Fpsdc","html_url":"https://awesome.ecosyste.ms/projects/github.com%2F5cover%2Fpsdc","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2F5cover%2Fpsdc/lists"}