Les membres ayant 30 points peuvent parler sur les canaux annonces, projets et hs du chat.
La shoutbox n'est pas chargée par défaut pour des raisons de performances. Cliquez pour charger.

Forum Casio - Projets de programmation


Index du Forum » Projets de programmation » Better Basic Casio : Un langage intermédiaire pour le peuple
Kikoodx Hors ligne Ancien labélisateur Points: 3011 Défis: 11 Message

Better Basic Casio : Un langage intermédiaire pour le peuple

Posté le 05/05/2020 11:37

Bonjour J'ai une nouvelle idée de projet que j'aimerai mettre en route : un "traducteur" d'une syntaxe custom vers le Basic Casio de nos chères calculatrices. J'aime beaucoup programmer en Basic Casio, mais je pense que changer sa syntaxe un poil sans impact sur la performance et le résultat final serait bon pour le futur du langage

Ce que j'aimerai faire :
Des fichiers textes .bc pour l'ordinateur écrits avec une meilleure syntaxe que le Basic Casio.
Un "convertisseur" de fichiers BC (Better/Basic Casio) vers .g1m en ligne de commande pour plus de liberté côté utilisateur.
Compabilité complète ou presque.
Raccourcis utiles pour augmenter la lisibilité. (tels que +=, -=...)

Pour la syntaxe, j'ai déjà quelques idées :
Remplacer la flèche → par le signe =.
Inclusion d'autres fichiers avec INCLUDE (voir plus bas).
Appel d'autres fichiers avec DO (voir plus bas).

Le projet n'est pas encore en cours, je note tout ici pour garder une trace !

Voici à quoi pourrait ressembler un code .bc et son output (exemple) :
//main.bc
#name PICKABOO
#pass HEHE
List 1 = {5, 6, 7}
B = 0
For A = 1 To 5 Step 2
Locate A, 1, A
B += 1
Next
#INCLUDE "example.bc"

//example.bc
Locate 1, 2, B

//PICKABOO.g1m (exemple)
{5,6,7→List1
0→B
For 1→A To 5 Step 2
Locate A,1,A
B+1→B
Next
Locate 1,2,B


Je noterai les changements ici, je vais me renseigner sur les .g1m.
Si vous avez des remarques, idées, suggestions... je suis tout ouïe

J'espère que j'aurai été clair ^^'


1, 2, 3 Suivante
Lephenixnoir Hors ligne Administrateur Points: 24234 Défis: 170 Message

Citer : Posté le 05/05/2020 11:39 | #


Bienvenue dans le monde fascinant de la compilation !
Mon graphe (11 Avril): ((Rogue Life || HH2) ; PythonExtra ; serial gint ; Boson X ; passe gint 3 ; ...) || (shoutbox v5 ; v5)
Kikoodx Hors ligne Ancien labélisateur Points: 3011 Défis: 11 Message

Citer : Posté le 05/05/2020 12:03 | #


Je note ce que Lephé et Cake balancent dans la shout :
https://bible.planet-casio.com/simlo/chm/v20/fxCG20_OPCODES.htm
https://forge.touhey.org/casio/fontcharacter.git/tree/formats/BINARY1.md

Shadow a mentionné la piste des .txt gérés par les derniers modèles, je verrai ça ASAP.

Sinon, je ne comprend pas exactement comment fonctionnent les compilateurs. Je vais me renseigner et espérer trouver des choses utiles.
ouais ouais
Hackcell Hors ligne Maître du Puzzle Points: 1524 Défis: 11 Message

Citer : Posté le 05/05/2020 12:06 | #


Ya le "dragon book" qui explique le fonctionement des compilateur en détail de A à Z
Zezombye Hors ligne Rédacteur Points: 1756 Défis: 13 Message

Citer : Posté le 05/05/2020 12:12 | #


Faut pas faire les mêmes erreurs que j'ai faites et utiliser un tokenizeur et AST
Divers jeux : Puissance 4 - Chariot Wars - Sokoban
Ecrivez vos programmes basic sur PC avec BIDE
Kikoodx Hors ligne Ancien labélisateur Points: 3011 Défis: 11 Message

Citer : Posté le 05/05/2020 12:20 | #


Merci Hackcell
Ça m'étonnerait que j'ai le niveau pour comprendre le bouquin. Première version si je tente ?

ZZ : c'est noté.

C'est compliqué tout ça Je relirai tout ça en essayant de distinguer les trolls d'infos utiles plus tard.
ouais ouais
Lephenixnoir Hors ligne Administrateur Points: 24234 Défis: 170 Message

Citer : Posté le 05/05/2020 12:43 | #


Voici quelques éléments pour t'aider à démarrer. Le dragon book est assez théorique, si tu sens que ça te va pas n'insiste pas trop. Prends la dernière version.

La première chose à comprendre est qu'un programme est un objet structuré. Il y a des blocs imbriqués les uns dans les autres, et il y a des programmes qui n'ont aucun sens comme While 1 Do WhileEnd LpWhile 1. La première chose à faire est de sortir le programme de sa forme textuelle pour en obtenir une version structurée. (Exactement ce que Zezombye n'a pas fait dans B2C d'ailleurs.) Ça se passe en deux étapes :

• L'analyse lexicale (lexing) groupe les caractères en mots. C'est là que tu te débarrasses des espaces et des lettres individuelles. Après cette étape, ton List 1 = {5,6,7} devient une séquence [ LIST, INT 1, EQUALS, LBRACE, INT 5, COMMA, INT 6, COMMA, INT 7, RBRACE ].
• L'analyse syntaxique (parsing) groupe les mots en phrases. C'est là que tu comprends la structure imbriquée des blocs If/While/etc, que tu te débarrasses des priorités opératoires, et que tu peux découvrir les lignes compliquées comme les affections. Après cette étape, l'exemple précédent devient un truc comme Assign(List(1), [5,6,7]).

Le résultat du parsing s'appelle un arbre de syntaxe, et comme il correspond exactement à ce qui se trouve dans le code on dit qu'il est concret. On appelle donc ça un CST pour Concrete Syntax Tree.

Si t'en arrives là, ton programme est quasiment fini. Il suffit de faire un bon paquet de print pour reconstruire un programme Basic Casio qui correspond aux instructions que tu as enregistrées. Tu peux donc écrire pour un Assign(var,value) le texte value → var.

Tout ça rentre dans un contexte formel bien bien cadré avec tous les outils qu'il faut pour t'aider à gagner du temps. Le lexer fonctionne avec des regex pour détecter les mots, par exemple les entiers peuvent être détectés par la regex [+-]?[0-9]+\b. Il y a des tas de générateurs de lexers auxquels tu donnes juste la liste des regex et qui te génèrent un programme qui fait le lexing pour toi. Le parser fonctionne avec des grammaires pour détecter les phrases ; c'est pas très différent des regex, mais c'est plus puissant (les regex sont incapables de comprendre les objets imbriqués). Tu peux écrire un parser à la main ou le générer avec un générateur de parsers... selon ton goût. Écrire un lexer à la main n'a presque aucun intérêt, écrire un parser à la main est un exercice plus intéressant.

Et, comme je l'ai mentionné rapidement, ton programme est en gros un cas simple de traducteur syntaxique (Syntax-Directed Translator ou SDT). Un SDT c'est un lexer+parser, sauf qu'au lieu de générer la forme structure du programme genre Assign(List(1), [5,6,7]) à la sortie du parser, il affiche directement une version modifiée du texte genre {5,6,7}→List 1. Pour te dire à quel point tout ces concepts sont bien étudiés et bien compris, on peut faire ce que tu décris dans ton post principal en moins de 200 lignes de texte pour décrire le lexer, le parser, et la traduction.
Mon graphe (11 Avril): ((Rogue Life || HH2) ; PythonExtra ; serial gint ; Boson X ; passe gint 3 ; ...) || (shoutbox v5 ; v5)
Zezombye Hors ligne Rédacteur Points: 1756 Défis: 13 Message

Citer : Posté le 05/05/2020 12:50 | #


C'est simple à comprendre en plus

On va prendre le code suivant :

A += "mon+string " + "autre string"


Qui va être compilé, après optimisation, en :

A + "mon+string autre string" -> A


On fait tout d'abord de la tokenization, tout simplement car si on veut transformer en AST, on ne peut pas faire un string.split("+"), ça prendrait le "+" dans le string mais aussi le "+" du "+=".

Du coup après tokenization on a un array :

['A', '+=', '"mon+string"', '+', '"autre string"']

En pratique ce serait des arrays de Token, qui seraient des objets qui contiennent le texte, mais aussi la ligne+colonne (pour quand il y a une erreur).

Ensuite maintenant c'est beaucoup plus facile de convertir en AST, on peut splitter sur "+" sans se soucier de si c'est dans un string, ou que ça fait partie d'un autre opérateur. À noter que la fonction de "splittage sur un token" ne doit pas prendre en compte les tokens entre parenthèses.

Du coup en respectant l'ordre des opérations et en splittant sur les opérateurs, on arrive à ça :


__modifyAdd__(__var__(A), __add__(__string__("mon+string"), __string__("autre string"))


On peut ensuite faire des trucs du genre "si on concatène 2 strings littéraux, les préprocesser" pour obtenir :

__modifyAdd__(__var__(A), __string__("mon+string autre string"))


Et après il suffit de définir une compilation pour chaque méthode interne :

__modifyAdd__(arg1, arg2) -> arg1 + arg2 -> arg1
Divers jeux : Puissance 4 - Chariot Wars - Sokoban
Ecrivez vos programmes basic sur PC avec BIDE
Lephenixnoir Hors ligne Administrateur Points: 24234 Défis: 170 Message

Citer : Posté le 05/05/2020 12:54 | #


Okay dans l'ensemble, mais non pour ça :

Ensuite maintenant c'est beaucoup plus facile de convertir en AST, on peut splitter sur "+" sans se soucier de si c'est dans un string, ou que ça fait partie d'un autre opérateur. À noter que la fonction de "splittage sur un token" ne doit pas prendre en compte les tokens entre parenthèses.

Tu n'as pas compris ta leçon toi. Après avoir fait de la tambouille avec le texte tu mets enfin un lexer sur ton programme, et ensuite tu fais de la tambouille sur la sortie du lexer.

Non, on ne sépare pas sur '+', on utilise un parser qui implémente une grammaire qui possède des priorités opératoires et fait son job proprement. x)
Mon graphe (11 Avril): ((Rogue Life || HH2) ; PythonExtra ; serial gint ; Boson X ; passe gint 3 ; ...) || (shoutbox v5 ; v5)
Kikoodx Hors ligne Ancien labélisateur Points: 3011 Défis: 11 Message

Citer : Posté le 05/05/2020 13:39 | #


Merci beaucoup pour explication Lephé !
J'ai globalement compris.
Comment est-ce que les cas d'optimisations du Basic seraient gérés avec cette procédure ? Il y a beaucoup de parenthèses/crochets qui sautent, mais de ce que j'ai compris c'est gérable.
Je commence donc par me renseigner sur les lexer, une recommandation ? (J'ai lu qu'on est censé les générer.)
ouais ouais
Zezombye Hors ligne Rédacteur Points: 1756 Défis: 13 Message

Citer : Posté le 05/05/2020 13:44 | #


Mouais les parenthèses qui sautent c'est gérable, dans le tokenizeur suffit de rajouter les parenthèses qui manquent lorsqu'on rencontre une fin de ligne.
Divers jeux : Puissance 4 - Chariot Wars - Sokoban
Ecrivez vos programmes basic sur PC avec BIDE
Cakeisalie5 En ligne Ancien administrateur Points: 1910 Défis: 11 Message

Citer : Posté le 05/05/2020 13:47 | #


Ça existe déjà. Ça s'appelle le CTF, pour CASIO Text Format.

http://web.archive.org/web/20031004183838/http://www.abc.se/~m9935/casio/ctf-spec.html

C'est un peu tombé dans l'oubli je crois, mais peut-être que tu peux participer à le remettre au goût du jour.

(silverstone est une mine d'or en termes d'informations pour ce qui a été fait pour les calculatrices CASIO entre 1995 et 2010 environ. Pour le reste j'ai un tas d'archives, n'hésites pas à demander, je te répondrai quand j'aurai le temps)

Promotion ordinaire sur les inscriptions sur Planète Casio : en ce moment, c'est gratuit !

Mon blogBesoin d'utilitaires de transfert vers et depuis la calculatrice sous GNU/Linux ?
Kikoodx Hors ligne Ancien labélisateur Points: 3011 Défis: 11 Message

Citer : Posté le 05/05/2020 14:36 | #


Merci pour le lien Cake
Contrairement à CTF, je compte changer pas mal d'éléments du langage. Je ne suivrai donc pas la norme, mais j'en créerai une nouvelle en prenant appui sur le CTF.
ouais ouais
Lephenixnoir Hors ligne Administrateur Points: 24234 Défis: 170 Message

Citer : Posté le 05/05/2020 16:37 | #


Comment est-ce que les cas d'optimisations du Basic seraient gérés avec cette procédure ? Il y a beaucoup de parenthèses/crochets qui sautent, mais de ce que j'ai compris c'est gérable.

Le parser les rajoutera à la main. Il suffit de les marquer comme optionnelles, et de rajouter une règle de priorité pour éliminer le conflit qui en découle.

Le conflit en question, c'est que l'élimination de la parenthèse rend la grammaire ambigue : on ne sait pas si f(g(x,y représente f(g(x),y) ou f(g(x,y)). Ici on choisit le second donc il faut indiquer la priorité pour que ça se passe bien.

Je n'ai pas de générateur de lexer/parser à te conseiller parce que je sais pas dans quel langage tu veux coder ! x_x

Mouais les parenthèses qui sautent c'est gérable, dans le tokenizeur suffit de rajouter les parenthèses qui manquent lorsqu'on rencontre une fin de ligne.

Non. Je t'ai dit en plus que la notion de ligne est une mauvaise idée. Regarde même un truc trivial comme f(x→A, ta proposition ne marche pas. N'essaie pas de hacker.
Mon graphe (11 Avril): ((Rogue Life || HH2) ; PythonExtra ; serial gint ; Boson X ; passe gint 3 ; ...) || (shoutbox v5 ; v5)
Kikoodx Hors ligne Ancien labélisateur Points: 3011 Défis: 11 Message

Citer : Posté le 05/05/2020 16:42 | #


Je ne suis pas sûr avoir été clair sur l'histoire des parenthèses ^^'
Le but serait qu'une entrée telle que celle-ci : "A = List 9[1]" résulte en "List 9[1→A"` et non l'inverse.

[quote=Lephenixnoir]Je n'ai pas de générateur de lexer/parser à te conseiller parce que je sais pas dans quel langage tu veux coder ! x_x[/quote]
Je pense partir sur du Python :)

ouais ouais
Zezombye Hors ligne Rédacteur Points: 1756 Défis: 13 Message

Citer : Posté le 05/05/2020 16:44 | #


Fin de ligne ou opérateur -> donc
Divers jeux : Puissance 4 - Chariot Wars - Sokoban
Ecrivez vos programmes basic sur PC avec BIDE
Kikoodx Hors ligne Ancien labélisateur Points: 3011 Défis: 11 Message

Citer : Posté le 05/05/2020 16:45 | #


Zezombye a écrit :
Fin de ligne ou opérateur -> donc

Non, il y a d'autres cas particuliers comme ⇒ par exemple. De plus, certains cas nécessitent de fermer les parenthèses (notamment les fonctions liées aux strings).
ouais ouais
Zezombye Hors ligne Rédacteur Points: 1756 Défis: 13 Message

Citer : Posté le 05/05/2020 16:47 | #


Bien du brin ce langage, il faudrait commencer par recenser dans quels cas exactement tu peux enlever des parenthèses du coup.
Divers jeux : Puissance 4 - Chariot Wars - Sokoban
Ecrivez vos programmes basic sur PC avec BIDE
Lephenixnoir Hors ligne Administrateur Points: 24234 Défis: 170 Message

Citer : Posté le 05/05/2020 16:48 | #


Kikoodx a écrit :
Je ne suis pas sûr avoir été clair sur l'histoire des parenthèses ^^'
Le but serait qu'une entrée telle que celle-ci : "A = List 9[1]" résulte en "List 9[1→A" et non l'inverse.

Ah ben oui tiens je suis con. C'est encore plus marrant ça !

Une fois que t'as ton AST, tu peux écrire une jolie petite fonction récursive qui détermine si oui ou non la parenthèse à la fin est nécessaire. Et si non, tu l'affiches pas. C'est pas très dur, juste une question de priorité opératoire vu de loin.

Arf, le lexing/parsing en Python, le truc que je connais le moins au monde. Les seuls que je connais de loin sont ANTLR (moderne mais pas très sympa à utiliser) et PLY (port direct de lex/yacc, les outils historiques pour faire ça en C, pas hyper moderne). Et y'en a plein d'autres. Je crois que tu vas devoir chercher un peu ^^"

Zezombye a écrit :
Fin de ligne ou opérateur -> donc

Va pas t'étonner qu'on te bashe après. x)
Mon graphe (11 Avril): ((Rogue Life || HH2) ; PythonExtra ; serial gint ; Boson X ; passe gint 3 ; ...) || (shoutbox v5 ; v5)
Kikoodx Hors ligne Ancien labélisateur Points: 3011 Défis: 11 Message

Citer : Posté le 05/05/2020 18:41 | #


Bonne nouvelle : le format .txt de Casio est très proche du CTF. Les fonctions sont entièrement écrites.
Voici un programme simple d'aide aux touches exporté depuis leur menu :
'ProgramMode:RUN
While 1
ClrText
Locate 1,1,Getkey
WhileEnd

Peut-être qu'un pseudo-compilateur ne sera pas nécessaire, et qu'un programme qui exécute quelques opérations plus ou moins basiques sera suffisant
ouais ouais
Lephenixnoir Hors ligne Administrateur Points: 24234 Défis: 170 Message

Citer : Posté le 06/05/2020 09:40 | #


Note bien que si tu restes au niveau lexical/regex sans parser toute une classe de modifications de syntaxe sera inaccessible. Après tant que ça suffit, tu fais comme tu veux...
Mon graphe (11 Avril): ((Rogue Life || HH2) ; PythonExtra ; serial gint ; Boson X ; passe gint 3 ; ...) || (shoutbox v5 ; v5)
1, 2, 3 Suivante

LienAjouter une imageAjouter une vidéoAjouter un lien vers un profilAjouter du codeCiterAjouter un spoiler(texte affichable/masquable par un clic)Ajouter une barre de progressionItaliqueGrasSoulignéAfficher du texte barréCentréJustifiéPlus petitPlus grandPlus de smileys !
Cliquez pour épingler Cliquez pour détacher Cliquez pour fermer
Alignement de l'image: Redimensionnement de l'image (en pixel):
Afficher la liste des membres
:bow: :cool: :good: :love: ^^
:omg: :fusil: :aie: :argh: :mdr:
:boulet2: :thx: :champ: :whistle: :bounce:
valider
 :)  ;)  :D  :p
 :lol:  8)  :(  :@
 0_0  :oops:  :grr:  :E
 :O  :sry:  :mmm:  :waza:
 :'(  :here:  ^^  >:)

Σ π θ ± α β γ δ Δ σ λ
Veuillez donner la réponse en chiffre
Vous devez activer le Javascript dans votre navigateur pour pouvoir valider ce formulaire.

Si vous n'avez pas volontairement désactivé cette fonctionnalité de votre navigateur, il s'agit probablement d'un bug : contactez l'équipe de Planète Casio.

Planète Casio v4.3 © créé par Neuronix et Muelsaco 2004 - 2024 | Il y a 147 connectés | Nous contacter | Qui sommes-nous ? | Licences et remerciements

Planète Casio est un site communautaire non affilié à Casio. Toute reproduction de Planète Casio, même partielle, est interdite.
Les programmes et autres publications présentes sur Planète Casio restent la propriété de leurs auteurs et peuvent être soumis à des licences ou copyrights.
CASIO est une marque déposée par CASIO Computer Co., Ltd