Dans tout la documentation, h, i, j, k, n, m, p, q désignent des entiers positifs. h, i, j, k sont écrits en 4 octets petit boutiste, n, m, p, q sur un octet. Tout signe entre '' représente un mot ou une suite de mots reconnus par l'interpréteur.

L'interpréteur interprête votre code instruction par instruction dans l'ordre d'écriture. Chaque instruction effective doit se terminer par '?'.

Chaque case mémoire fait un octet. Les pointeurs et les numéros de waypoint sont encodés en petit boutiste sur 4 octets.

Tout programme doit se terminer par '__||__'.

Commentaires : Les commentaires sont écrits entre "" ou après ' jusqu'à la fin de la ligne.

Ecriture des données : - 'n' : un entier interprété sur un octet (allocation de mémoire ou entrée) les écritures comme 0b..... et 0x..... sont aussi supportées - 'i' : un entier interprété sur quatre octets petit boutiste (goto, opérations, stockage d'une entrée, déréférencement) les écritures comme 0b..... et 0x..... sont aussi supportées - ~string~ : une chaîne de caractères La chaine de caractère est interprêtée comme un entier en fonction du contexte dans lequel elle est utilisée (voir au dessus). Lors d'une allocation, toutes les lettres seront stockées dans l'ordre dans les case suivant celle uitilsée comme stockage, ie 'i <- ~ab~ ? est interprêté comme i <- (uin8_t) a , (i+1) <- (uint8_t) b'. \~ n'est pas interprêté comme la fin de la chaîne. les symboles commençant par \ sont supportés. - '@i' : déréférencement de i. Vaut la valeur stockée en i, selon le contexte, juste l'octet correspondant à i ou celle de i et des trois cases suivantes interprêtées en petit boutiste (voir au dessus).

Instructions : - '.' : crée un waypoint. Les waypoints sont numérotés à partir de 0 par l'interpréteur, et ne constituent pas une instruction. - '-> k ?': définit la prochaine instruction comme celle succédant le k-ième waypoint. Les instructions suivantes seront exécutées à partir de cette instruction. - 'n ?' : réalloue le tableau mémoire pour qu'il fasse n octets. Par défaut le tableau n'est pas alloué. - 'i <= n ?' : écrit n%256 dans la i-ème case du tableau Plusieurs entrées en une ligne sont possibles : 'i j k <= m n p ?' écrit respectivement m%256 dans i, n%256 dans j et p%256 dans k. Au moins une destination doit être donnée pour que l'instruction soit valide. (ex : 'i <= ?' est valide mais pas ' <= j ?') Si il n'y a pas le même nombre d'opérandes à droite et à gauche, l'interpréteur en fera le maximum possible, de gauche à droite. ex : 'i j <= n ?' écrit n%256 dans i. - 'i <- ;j ?' : écrit le resultat de l'opération unitaire ';' appliquée sur la valeur stockée en j et la stocke en i. Les opérateurs unitaires se placent à droite du pointeur. On peut cumuler des opérateurs unitaires qui seront résolus de droite à gauche, si on met à disposition des mémoires tampons pour l'interpréteur. Par exemple : 'i j k <- :;!h ?' est lu comme 'k <- !h ? j <- ;k ? i <- :j ?' On peut dans ce cas aussi utilser des parenthèses pour délimiter les opérateurs si '=' et '==' sont deux opérateurs distincts. Par défaut, l'interpréteur lira le plus long, ie '==' est lu == et '(=)=' est lu = puis =. - 'i <- j , k ?' : écrit le resultat de l'opération binaire ',' appliquée sur la valeur stockée en j et en k et la stocke en i. Pas de cumuls, pas de parenthèses.

Opérateurs natifs : - '; i' : non bit à bit - 'i , j' : ou bit à bit - 'i < j' : décale la valeur stockée en i de la valeur stockée en j bits vers la droite (et la stocke dans la destination). Tous les bits qui sortent de l'octet stocké en i sont écrasés. - 'j > i' : décale la valeur stockée en i de la valeur stockée en j bits vers la gauche (et la stocke dans la destination). Tous les bits qui sortent de l'octet stocké en i sont écrasés.

Instructions préprocesseur : - '$ [op] [d <- ;r ?]' : création d'un opérateur unitaire Toute occurence de 'i <- op j ?' sera remplacée par sa définition dans les crochets de droite, ici par 'i <- ; j ?'. 'd' désigne la destination du résultat, r l'opérande à droite de l'opérateur. On peut mettre autant de code que l'on veut dans les crochets de droite. Les waypoints ne sont pas acceptés dans les crochets de droite pour des raisons évidentes. - '$$ [op] [d <- l , r ?]' : création d'un opérateur binaire Idem, où l désigne l'opérande à gauche de op. - '$$$ [rechercher] [remplacer]' : remplace toutes les occurences de 'rechercher' par 'remplacer' dans la suite du code, y compris dans le code des fichiers inclus après ce code, sauf dans les chaînes de caractère et les commentaires. Tout est permis, rien n'est vérifié - '$$$$ [path.bbs]' : recopie tout le code de path.bbs à cette endoit du code. Toute les macros précédemment actives lui sont appliqué. Toute nouvelle macro définie dans ce code sera appliquée sur le reste du code.

Bonnes pratiques : exemple de stdio - Ne pas définir de macros dans les fichier à inclure, mais avant de les inclure.

Ici pour inclure stdio, il faut définir au préalable 10 macros : $$$ [#STDIO_SIZE_REGISTER_0] [i] "case ou stocker le premier paramètre ou la première sortie de SIZE" $$$ [#STDIO_SIZE_REGISTER_1] [j] "case ou stocker le premier paramètre ou la première sortie de SIZE" $$$ [#STDIO_SIZE_RETURN] [k] "numéro du waypoint auquel retourner après l'exécution de SIZE" $$$ [#STDIO_CAT_REGISTER_0] [i] "case ou stocker le premier paramètre ou la première sortie de CAT" $$$ [#STDIO_CAT_REGISTER_1] [j] "case ou stocker le premier paramètre ou la première sortie de CAT" $$$ [#STDIO_CAT_RETURN] [k] "numéro du waypoint auquel retourner après l'exécution de CAT" $$$ [#STDIO_SET_OUT_STREAM_REGISTER_0] [i] "case ou stocker le premier paramètre ou la première sortie de SET_OUT_STREAM" $$$ [#STDIO_SET_OUT_STREAM_RETURN] [k] "numéro du waypoint auquel retourner après l'exécution de SET_OUT_STREAM" $$$ [#STDIO_PUSH_REGISTER_0] [i] "case ou stocker le premier paramètre ou la première sortie de PUSH" $$$ [#STDIO_PUSH_RETURN] [k] "numéro du waypoint auquel retourner après l'exécution de PUSH" $$$$ [stdio.bbs]

Bibliothèque stdio : Définit 4 waypoints dans l'ordre suivant (numérotés en même temps que tous les autres) : - SIZE écrit dans STDIO_SIZE_ARGUMENT_DESTINATION (sur 4 octets en petit boutiste) la taille du fichier dont le nom est écrit à partir de STDIO_SIZE_ARGUMENT_PATH finissant par le carctère nul. - CAT écrit à partir de STDIO_SIZE_ARGUMENT_DESTINATION le contenu du fichier dont le nom est écrit à partir de STDIO_CAT_ARGUMENT_PATH finissant par le carctère nul, ou de stdin si STDIO_CAT_ARGUMENT_PATH contient le caractère nul. - SET_OUT_STREAM sélectionne le fichier de sortie pour PUSH dont le nom est écrit à partir de STDIO_SET_OUT_STREAM_ARGUMENT_PATH finissant par le carctère nul, ou stdout si STDIO_SET_OUT_STREAM_ARGUMENT_PATH contient le caractère nul. - PUSH écrit l'octet stocké en STDIO_PUSH_ARGUMENT_SOURCE dans le fichier de sortie.

Problème

Classement

Tests en cours

Veuillez donner les entrées du programme