les bases d'un interpreteur/et pseudo compilation en *.Exe

Vous débutez et vous avez besoin d'aide ? N'hésitez pas à poser vos questions
Avatar de l’utilisateur
Zorro
Messages : 2185
Inscription : mar. 31/mai/2016 9:06

les bases d'un interpreteur/et pseudo compilation en *.Exe

Message par Zorro »

vous voulez creer votre propre language ?

voici un interpreteur bidon (vraiment pour le coup , mais montre le principe qu'on peut interpréter une ligne de code
sans passer par du chinois :mrgreen: :lol: (allusion au bytecode de Grom)


Cette version utilisant une pile d'instruction (liste chainée)
ce qui serai utile notamment pour l'emploi de "procedure" ,saut dans le code, etc ...

rappel cet interpréteur, interprète la ligne de code suivante

Code : Tout sélectionner

"boucle 5 print fin_boucle"
vous aurez compris que le but est de faire une boucle "For-Next" 5 fois et d'afficher le compteur


j'ai bien commenté le code, je pense que c'est clair
pour voir le fonctionnement posez un callDebugger au bon endroit
et Tracez pour voir ce qui se passe avec la Liste chainée Pile()

pour info , j’appelle "variable systeme" les variables internes a l'interpreteur
ne pas confondre avec les variables ...

plus tard , je vous ferai un exemple de gestion des variables "utilisateur" c'est assez simple :)


Code : Tout sélectionner

;***********************************************
;Titre  :*interpreteur_base
;Auteur  : Zorro
;Date  :31/12/2017
;Heure  :18:15:53
;Version Purebasic :  PureBasic 5.60 (Windows - x86)
;Version de l'editeur :EPB V2.68
; Libairies necessaire : Aucune 
;***********************************************

; interpreteur bidon 


Info.s="INTERPRETEUR"
ligne_code.s="boucle 5 print fin_boucle" ; <<<< ceci est la ligne de code qui sera executée ..

newlist Pile.s()




; Analyse syntaxique (et pose des instructions dans notre pile )
For i=1 to len(ligne_code.s)
		extrait.s=stringfield(ligne_code.s,i," ")
		select extrait.s
				Case "boucle" ; on tombe sur une commande de boucle
				addElement(pile.s()) ; on l'ajoute dans la pile d'instruction
				pile.s()="boucle"
				i=i+1
				nb=val(stringfield(ligne_code.s,i," ")) ; comme c'est une boucle, on recupe alors le nombre de boucle a faire (le parametre en fait )
				addElement(pile.s()) ; on le pose aussi sur la pile
				pile.s()=str(nb)
				Case  "print"  ; on veux afficher un truc ?? 
				addElement(pile.s()) ; on ajoute cette instruction sur la pile
				pile.s()= "print" 
				Case "fin_boucle" ; tien une fin de boucle se presente
				addElement(pile.s()) ; comme c'est une instruction reconnu par notre langage, on la pose aussi sur la pile
				pile.s()= "fin_boucle"
		EndSelect
Next i
;


ResetList(Pile()) ; on met le pointeur de pile a zero



; Execution  (l'interpreteur !!  )
; Lecture de notre pile d'instruction ET execution a la volée
ForEach Pile() ; pour chaque elements de notre pile , on va traiter
		commande.s=Pile()
		select commande.s
				Case  "boucle" ; on tombe sur la fonction boucle (For)
				NextElement(pile()) ; comme c'est une boucle, on recupere le parametre de notre boucle (le nombre de fois qu'on va boucler ), il se trouve a la suite de la fonction 'boucle' dans notre pile
				nb=val(Pile()); voila parametre recupéré dans notre variable systeme "nb"
				pointeur_de_pile_retour=ListIndex(Pile())  ; on met en memoire la position du debut de boucle, comme ça on pourra revenir si boucle pas finie
				Case "fin_boucle" ; tiens, on tombe sur la fonction de fin de boucle , il faut verifier si elle est finie ou pas
				compteur=compteur+1 ; on met a jour la variable systeme de notre boucle
				if compteur<nb ; boucle pas finie
						SelectElement(Pile(), pointeur_de_pile_retour) ; on retourn au debut de la boucle (on saute dans la pile a l'emplacement du debut de boucle
				Else ; la boucle est fini on a egalé ou depassé nb
						goto fin ; ici je termine, mais il faudrai passer a la suite du prg ligne suivante , mais mon exemple n'a qu'une ligne
				Endif
				Case "print" ; on tombe sur l'instruction d'affichage
				MessageRequester("sortie",str(compteur)) ; on execute l'affichage avec un requester, ais ça aurai pu etre une sortie ecran ou que sais-je
		EndSelect
Next

Fin:
Dernière modification par Zorro le jeu. 04/janv./2018 14:11, modifié 2 fois.
Image
Image
Site: http://michel.dobro.free.fr/
Devise :"dis moi ce dont tu as besoin, je t'expliquerai comment t'en passer"
Avatar de l’utilisateur
Zorro
Messages : 2185
Inscription : mar. 31/mai/2016 9:06

Re: les bases d'un interpreteur

Message par Zorro »

j'ai trouvé comment faire un executable autonome
a partir du code de notre XXlangage !!
ligne_code.s="boucle 5 print fin_boucle"
ci dessus :D

c'est en fait super simple .... :)

aujourd'hui je reçois du monde , mais des demain, je fait le pseudo-compilateur qui marchera avec le code de l’interpréteur ci dessus :)
vous verrez, c'est tellement simple, que je me demande pourquoi, je n'y ai pas pensé avant :)
Image
Image
Site: http://michel.dobro.free.fr/
Devise :"dis moi ce dont tu as besoin, je t'expliquerai comment t'en passer"
Avatar de l’utilisateur
Zorro
Messages : 2185
Inscription : mar. 31/mai/2016 9:06

Re: les bases d'un interpreteur

Message par Zorro »

bon , voila, j'y suis arrivé a faire mon compilateur a deux balle ! :)
pour bien comprendre ce dont je vais parler , le postula suivant :

un interpreteur , "interprete" a la volée chaque ligne de code, pour effectuer une action
un compilateur , "compile" ou creer un prg pour qu'il soi autonome ...
un patcheur "patch" un fichier ou un executable pour modifier son comportement ..

de ce point de vue, mon compilateur a deux balle , tiens plus du patcher, que d'un réel compilo :)
mais au final, l'utilisateur, ne verra pas la différence, car le compilo a deux balles génère un Exe ! :)


je repart donc sur mon petit interpréteur ci dessus, qui interprète un langage tres simple , comprenant 3 instructions

boucle x (lance une boucle et tiens a jour son compteur

Print (demande a afficher le resultat du compteur dans un requester )

fin_boucle qui termine la boucle pour pouvoir remonter (un Next quoi ) et met a jour le compteur

que je vais appeler notre langage maison, le "XXXlangage"/ou "XXXcode" pour qu'on ne se mélange pas les pinceaux :)

pour les besoins de mise en oeuvre du compilateur, j'ai légèrement modifié l’interpréteur pour que celui-ci interprète le contenu d'un fichier
et non plus le contenu d'une variable ... c'est a peine différent, mais nécessaire pour la suite ....

donc si vous voulez faire la démonstration que je vous propose , il vous faut creer un dossier exemple "interpreteur_base"
dans lequel vous poserez tout les listings qui suivent : (il n'y en que 3 :) )


le premier listing que voici , c'est un créateur de code en "XXXlangage" , qui va recopier un certain nombre de fois
la ligne de XXXcode suivante :

Code : Tout sélectionner

"boucle 5 print fin_boucle "
histoire de montrer que l’interpréteur fonctionne avec un fichier multi ligne, et que le compilateur fonctionnera aussi :)
ce prg va donc generer un fichier "test.txt" , ce sera notre XXXCode a compiler (et interpreter ) ... :)
laissez bien ce fichier generé dans notre dossier de travail ....

Code : Tout sélectionner

 
 OpenFile(1, GetCurrentDirectory()+"test.txt")
 		For i=1 to 10
 				WriteStringN (1,"boucle 5 print fin_boucle ")
 		Next i
 CloseFile(1)
; Epb

le listing numero deux , va etre un Exe_Squelette ! , j'en ai parlé l'autre jour , lorsque j'affirmais qu'on pouvais utiliser un *.exe
et le détourner pour en faire un exécutable a nous ...
c'est ce que je vais faire , avec ce listing ...

il faudra donc le compiler avec Purebasic ce listing SANS CHANGER LA MOINDRE LIGNE ,c'est important pour le fonctionnement
donc, tel quel , vous le sauverez dans notre dossier de travail
sous le nom de "Programme_container_x86.exe"

Code : Tout sélectionner


;***********************************************
;Titre  :*Programme_container_x86.exe
;Auteur  : Zorro
;Date  :31/12/2017
;Heure  :18:15:53
;Version Purebasic :  PureBasic 5.60 (Windows - x86)
;Version de l'editeur :EPB V2.68
; Libairies necessaire : Aucune 
;***********************************************

; interpreteur bidon 


Info.s="Programme_container_x86.exe"
newlist Pile.s()

Restore code:

While ligne_code.s<> "fin_code"
		read.s ligne_code.s
		; Analyse syntaxique (et pose des instructions dans notre pile )
		For i=1 to len(ligne_code.s)
				extrait.s=stringfield(ligne_code.s,i," ")
				select extrait.s
						Case "boucle" ; on tombe sur une commande de boucle
						addElement(pile.s()) ; on l'ajoute dans la pile d'instruction
						pile.s()="boucle"
						i=i+1
						nb=val(stringfield(ligne_code.s,i," ")) ; comme c'est une boucle, on recupe alors le nombre de boucle a faire (le parametre en fait )
						addElement(pile.s()) ; on le pose aussi sur la pile
						pile.s()=str(nb)
						Case  "print"  ; on veux afficher un truc ?? 
						addElement(pile.s()) ; on ajoute cette instruction sur la pile
						pile.s()= "print" 
						Case "fin_boucle" ; tien une fin de boucle se presente
						addElement(pile.s()) ; comme c'est une instruction reconnu par notre langage, on la pose aussi sur la pile
						pile.s()= "fin_boucle"
				EndSelect
		Next i
Wend

;

ResetList(Pile()) ; on met le pointeur de pile a zero


; Execution  (l'interpreteur !!  )
; Lecture de notre pile d'instruction ET execution a la volée
ForEach Pile() ; pour chaque elements de notre pile , on va traiter
		commande.s=Pile()
		select commande.s
				Case  "boucle" ; on tombe sur la fonction boucle (For)
				NextElement(pile()) ; comme c'est une boucle, on recupere le parametre de notre boucle (le nombre de fois qu'on va boucler ), il se trouve a la suite de la fonction 'boucle' dans notre pile
				nb=val(Pile()); voila parametre recupéré dans notre variable systeme "nb"
				pointeur_de_pile_retour=ListIndex(Pile())  ; on met en memoire la position du debut de boucle, comme ça on pourra revenir si boucle pas finie
				Case "fin_boucle" ; tiens, on tombe sur la fonction de fin de boucle , il faut verifier si elle est finie ou pas
				compteur=compteur+1 ; on met a jour la variable systeme de notre boucle
				if compteur<nb ; boucle pas finie
						SelectElement(Pile(), pointeur_de_pile_retour) ; on retourn au debut de la boucle (on saute dans la pile a l'emplacement du debut de boucle
				Else ; la boucle est fini on a egalé ou depassé nb
						compteur=0
				Endif
				Case "print" ; on tombe sur l'instruction d'affichage
				MessageRequester("sortie",str(compteur)) ; on execute l'affichage avec un requester, ais ça aurai pu etre une sortie ecran ou que sais-je
		EndSelect
Next

Fin:

Datasection
		; le buffer pour le code reservé dans notre prg porteur, le compilo a 2 balles, va poser notre xxxcode dedans (en principe )
		Code:
		data.s "                                                                                                                                                                                                                                                                                                                                 " 
		data.s "                                                                                                                                                                                                                                                                                                                                 " 
		data.s "                                                                                                                                                                                                                                                                                                                                 " 
		data.s "                                                                                                                                                                                                                                                                                                                                 " 
		data.s "                                                                                                                                                                                                                                                                                                                                 " 
		data.s "                                                                                                                                                                                                                                                                                                                                 " 
		data.s "                                                                                                                                                                                                                                                                                                                                 " 
		data.s "                                                                                                                                                                                                                                                                                                                                 " 
		data.s "                                                                                                                                                                                                                                                                                                                                 " 
		data.s "                                                                                                                                                                                                                                                                                                                                 " 
		data.s "                                                                                                                                                                                                                                                                                                                                 " 
		data.s "                                                                                                                                                                                                                                                                                                                                 " 
		data.s "                                                                                                                                                                                                                                                                                                                                 "
		data.s "                                                                                                                                                                                                                                                                                                                                 "
		data.s "                                                                                                                                                                                                                                                                                                                                 "
		data.s "                                                                                                                                                                                                                                                                                                                                 "
		data.s "                                                                                                                                                                                                                                                                                                                                 "
		data.s "                                                                                                                                                                                                                                                                                                                                 "
		data.s "                                                                                                                                                                                                                                                                                                                                 "
		data.s "                                                                                                                                                                                                                                                                                                                                 "
		data.s "                                                                                                                                                                                                                                                                                                                                 "
		data.s "                                                                                                                                                                                                                                                                                                                                 "
		data.s "                                                                                                                                                                                                                                                                                                                                 "
		data.s "                                                                                                                                                                                                                                                                                                                                 "
		data.s "                                                                                                                                                                                                                                                                                                                                 "
		data.s "                                                                                                                                                                                                                                                                                                                                 "
		data.s "                                                                                                                                                                                                                                                                                                                                 "
		data.s "                                                                                                                                                                                                                                                                                                                                 "
		data.s "                                                                                                                                                                                                                                                                                                                                 "
		data.s "                                                                                                                                                                                                                                                                                                                                 "
		data.s "                                                                                                                                                                                                                                                                                                                                 "
		data.s "                                                                                                                                                                                                                                                                                                                                 "
		data.s "                                                                                                                                                                                                                                                                                                                                 "
		data.s "                                                                                                                                                                                                                                                                                                                                 "
		data.s "                                                                                                                                                                                                                                                                                                                                 "
		data.s "                                                                                                                                                                                                                                                                                                                                 "
		data.s "                                                                                                                                                                                                                                                                                                                                 "
		data.s "                                                                                                                                                                                                                                                                                                                                 "
		data.s "                                                                                                                                                                                                                                                                                                                                 "
		data.s "                                                                                                                                                                                                                                                                                                                                 "
		data.s "                                                                                                                                                                                                                                                                                                                                 "
		data.s "                                                                                                                                                                                                                                                                                                                                 "
		data.s "                                                                                                                                                                                                                                                                                                                                 "
		data.s "                                                                                                                                                                                                                                                                                                                                 "
		data.s "                                                                                                                                                                                                                                                                                                                                 "
		data.s "                                                                                                                                                                                                                                                                                                                                 "
		data.s "                                                                                                                                                                                                                                                                                                                                 "
		data.s "                                                                                                                                                                                                                                                                                                                                 "
		data.s "                                                                                                                                                                                                                                                                                                                                 "
		data.s "                                                                                                                                                                                                                                                                                                                                 "
		data.s "                                                                                                                                                                                                                                                                                                                                 "
		data.s "                                                                                                                                                                                                                                                                                                                                 "
		data.s "                                                                                                                                                                                                                                                                                                                                 "
		data.s "                                                                                                                                                                                                                                                                                                                                 "
		data.s "                                                                                                                                                                                                                                                                                                                                 "
		data.s "                                                                                                                                                                                                                                                                                                                                 "
		data.s "fin_code"
EndDatasection
; Epb


j'ai deja commencé a commenter ce code , si vous etes perspicace, vous aurez compris que je vais utiliser la DATASECTION
pour poser notre XXXCode a interpréter !! , ne changez rien dans ce listing, sinon, ça ne marchera pas ....

et oui , si vous crée une datasection , et que vous laisser un signe dedans genre : data.s "toto"
si vous compilez avec Purebasic, en utilisant un viewer Hexadecimal , vous verrez "toto" ecris en clair dans le fichier *.exe ....
c'est un truc lié a l'assembleur , de memoire, on appel ça un segment .. je sais plus si c'est le Data,le Bss , ou autre...
bref, c'est cette particularité que je vais utiliser pour stocker mon XXXCode , et le faire exécuter par mon interpreteur

ben oui , mon executable ci dessus c'est en fait mon interpreteur compilé , qui cherchera a lire , le contenu de la datasection !!! :D (qui pour le moment est vide)

donc, mon compilateur a deux balles qui suit, se contentera de poser le XXXcode , dans la Datasection du prg compilé !

voici le "compilateur" le plus petit du monde : (a sauver aussi (pas besoin de la compiler , vous pouvez le lancer dans l'editeur )
mais attendez de lire l'utilisation plus bas .... :)

Le compilateur a deux Balle :

Code : Tout sélectionner

;**********²*********************²****************
;Titre  :*compilateur_a_deux_balles
;Auteur  : Zorro
;Date  :03/01/2018
;Heure  :00:20:00
;Version Purebasic :  PureBasic 5.60 (Windows - x86)
;Version de l'editeur :EPB V2.68
; Libairies necessaire : Aucune 
;***********************************************


file.s=OpenFileRequester( "ouvrir test.txt",GetCurrentDirectory() ,"Fichiers Textes|*.txt",0)
OpenFile(0 ,file.s)
		While Eof(0) = 0
				code.s=code.s+ReadString (0,#PB_Ascii  )
		Wend
CloseFile(0)

; code.s ..... contient le code a patcher dans notre Prg porteur

CopyFile(GetCurrentDirectory() +"Programme_container_x86.exe", GetCurrentDirectory() +"Programme_compile.exe") 

; on ouvre le prg porteur

If OpenFile( 0,  GetCurrentDirectory()+"Programme_compile.exe") 
		length = Lof(0)                       ; Lit la taille en octets du fichier
		FileSeek(0, 10936)              ; place le pointeur a la position 10936 (l'emplacement de notre zone Datasection dans le fichier )
		longueur_max= (46996-10936)/2  ; attention de ne pas depasser la zone reservé du prg Container
		if Len(code.s)>longueur_max
				code.s=left(code.s,longueur_max) ; on tronque si plus long
		Endif
		WriteString(0,code.s ,#PB_Unicode) 
Endif
CloseFile(0)


MessageRequester("fini", "le prg Programme_compile.exe  est genéré")

les lignes 27 et 28 determine a quel endroit commence et fini la datasection
c'est pourquoi il est important de ne rien toucher dans le code du prg container ....



explication de la mise en oeuvre :

en principe en lançant le premier listing, ça a du vous generer notre pseudo listing de XXXCode nommé "test.txt"

ensuite vous avez du compiler le deuxieme listing pour avoir dans le dossier l'executable "Programme_container_x86.exe"

donc si vous lancez le compilo a deux balles , celui ci vous demande d'ouvrir le listing "test.txt"
et va generer un prg executable nommé "Programme_compile.exe"

c'est ce dernier prg qui est le resultat de la compilation !

si vous modifiez le listing "test.txt" , il suffit seulement dorénavant de lancer le compilo a deux balle , pour avoir la nouvelle version
de notre prg compilé "Programme_compile.exe" :)


si vous lancez le prg "Programme_compile.exe" , celui ci doit vous afficher un requester et augmenter le chiffre , qui prouve que la boucle
en langage XXX fonctionne .... chaque ligne de code compte de 0 a 4 (5 boucles )

pour sortir de ce prg un passage par Ctrl+Alt+Del , sera obligatoire, a moins de cliquer longtemps pour finir le prg ... :)
Image
Image
Site: http://michel.dobro.free.fr/
Devise :"dis moi ce dont tu as besoin, je t'expliquerai comment t'en passer"
Avatar de l’utilisateur
djes
Messages : 4252
Inscription : ven. 11/févr./2005 17:34
Localisation : Arras, France

Re: les bases d'un interpreteur/et pseudo compilation en *.E

Message par djes »

Mmmm, concrètement, ce que tu fais tiens plus de l'interpréteur que du compilateur. Peu importe qu'il doit dans un fichier externe ou intégré à l'exécutable comme tu le fais, ton premier code n'est pas compilé en natif.

Mais c'est bien pensé, même si c'est plus une bidouille (un hack si tu préfères) qu'une belle démonstration pédagogique ;)
Avatar de l’utilisateur
Zorro
Messages : 2185
Inscription : mar. 31/mai/2016 9:06

Re: les bases d'un interpreteur/et pseudo compilation en *.E

Message par Zorro »

djes a écrit :Mmmm, concrètement, ce que tu fais tiens plus de l'interpréteur que du compilateur. Peu importe qu'il doit dans un fichier externe ou intégré à l'exécutable comme tu le fais, ton premier code n'est pas compilé en natif.

Mais c'est bien pensé, même si c'est plus une bidouille (un hack si tu préfères) qu'une belle démonstration pédagogique ;)
je le precise dans le titre "Pseudo compilateur"

je le dit dans mes explications, il s'agit d'un patch


mais.... si je t'avais donné mon prg tout compilé sans explications
si j'avais intergré dans mon interpreteur le fichier "Prg_container" en inclusion

et enfin si j'avais mis l'option de compilation dans un menu
du point de vue utilisateur , il aurai vu que mon prg "pond" un Executable de son XXXcode
et que celui ci est fonctionnel ... du point de vue utilisateur de l'ensemble, ça compile au sens ,ça genere un executable :)

apres le procedé utilisé pour obtenir cet executable, c'est une autre affaire ...

il me semble qu'il y a pas mal de "runtime" dans d'autre language, qui agissent un peut comme ça...


dire ,que ce n'est pas une belle démonstration pédagogique ...c'est un peu exagéré non ?

parce que premièrement, j'ai jamais présenté le truc comme ça
et qu'ensuite je n'ai pas vocation a etre prof

mais ça reste tout de même une information partagée , ce que je fait sur ce forum depuis quelques temps, il me semble
et je respecte ce que j'avais annoncé, il y a peu . la possibilité d'utiliser un exécutable (un exe_squelette) a nos fins

un "compilateur" transforme un langage "évolué" en binaire ..
d'une certaine façon, c'est ce que je fait, sauf que pour mon cas le binaire, est deja a 90 pourcent deja pré-transformé ... :mrgreen:
comme un pré-calcul en quelques sortes :)
Image
Image
Site: http://michel.dobro.free.fr/
Devise :"dis moi ce dont tu as besoin, je t'expliquerai comment t'en passer"
Avatar de l’utilisateur
djes
Messages : 4252
Inscription : ven. 11/févr./2005 17:34
Localisation : Arras, France

Re: les bases d'un interpreteur/et pseudo compilation en *.E

Message par djes »

Ne le prends pas mal, un constat n'est pas une critique ! L'art de la subtilité et des nuances, ce n'est pas qu'en musique. Les mots ont un sens, vivant, évolutif, les phrases ont une dynamique, un rythme. Le code lui-même est vu par beaucoup de programmeurs comme un travail artisanal dans le sens beauté, rigueur, maîtrise !

Je ne suis pas un maître à penser, et si je me permets de dire qu'un interpréteur n'est pas un compilateur, c'est pour rappeler une définition partagée par l'ensemble de la communauté, une base. Après, j'apprécie les digressions, la contre-culture, l'anti-système en ce sens qu'il sont sources d'évolution et qu'ils ouvrent la voie à d'autres approches en se libérant de tout carcan. Tu es très fort pour ça ;)

Il ne serait pas très compliqué de transformer l'interpréteur en véritable compilateur et d'embellir le code ; peut-être y-aura-t-il quelque volontaire pour ça ? :)
Avatar de l’utilisateur
celtic88
Messages : 309
Inscription : sam. 12/sept./2015 14:31
Localisation : Alger

Re: les bases d'un interpreteur/et pseudo compilation en *.E

Message par celtic88 »

très bonne idée bonne chance...., il me fait penser a "Autoit"
.....i Love Pb :)
G-Rom
Messages : 3627
Inscription : dim. 10/janv./2010 5:29

Re: les bases d'un interpreteur/et pseudo compilation en *.E

Message par G-Rom »

y a plus simple qu'une datasection hors norme. La concaténation de deux fichier [EXE]+[TRUC A RAJOUTE] , windows dispose je crois de xcopy pour le faire, mais le faire en PB
est simple. ca n'altère pas l'exécutable, c'est comme cela que procède certain soft, löve2D par exemple, pas besoin de datasection pour le coup.

une procedure en PB qui récupère l'exe courant , copie le fichier source a la fin du fichier executable :
ne pas faire un simple Run , mais créer un Exe dans la racine de votre source , a adapter selon vos besoins :

Code : Tout sélectionner

Procedure SelfAppend(File.s, Destination.s)
  Protected *buffer,PathSize.l,Exe$
  
  ; quel est l'exe courant ?
  *buffer   = AllocateMemory(4096)
  If *buffer
    PathSize  = GetModuleFileName_(#Null, *buffer, #MAX_PATH + 1)
    Exe$      = PeekS(*buffer,PathSize)  
    FreeMemory(*buffer)
  Else
    ProcedureReturn -1
  EndIf 

  If ReadFile(0,Exe$)
    *selfBuffer = AllocateMemory(Lof(0))
    
    If *selfBuffer
      
      ; on copie l'exe en mémoire
      ReadData(0,*selfBuffer,Lof(0))
      CloseFile(0)
      
      ; on lis le fichier source a rajouté
      If ReadFile(0,File)
        *fileBuffer = AllocateMemory(Lof(0))
        If *fileBuffer
          
          ReadData(0,*fileBuffer,Lof(0))
          CloseFile(0)
          
          
          finalSize = MemorySize(*selfBuffer) + MemorySize(*fileBuffer)
          *finalBuffer = AllocateMemory(finalSize)
          
          CopyMemory(*selfBuffer,*finalBuffer,MemorySize(*selfBuffer))
          CopyMemory(*fileBuffer,*finalBuffer + MemorySize(*selfBuffer), MemorySize(*fileBuffer))
          FreeMemory(*selfBuffer)
          FreeMemory(*fileBuffer)
          
          CreateFile(0,Destination)
          WriteData(0,*finalBuffer,finalSize)
          CloseFile(0)
          FreeMemory(*finalBuffer)

          Debug "!"
        Else
          ProcedureReturn -1
        EndIf        
      Else
        ProcedureReturn -2
      EndIf
    Else
      ProcedureReturn -1  
    EndIf
  Else 
    ProcedureReturn -2   
  EndIf 
  
EndProcedure

retour = SelfAppend(#PB_Compiler_File, GetPathPart(#PB_Compiler_File)+"Concat.exe")
MessageRequester("!","je marche toujours!")

On voit bien le code source avec un simple editeur de texte :

Image

nb: il est possible de concaténer autant de fichier que l'on veut.
Avatar de l’utilisateur
Zorro
Messages : 2185
Inscription : mar. 31/mai/2016 9:06

Re: les bases d'un interpreteur/et pseudo compilation en *.E

Message par Zorro »

Effectivement, ça doit le faire aussi

Je suis parti sur la data section parce-que je me suis dit
Que ce serai plus respectueux (en rapport avec les sections assembleur)
De la structure d'un exe

Le principe étant qu'au final on ne distribut qu'un seul fichier exe
Et que le source soit inclu dedans ...

Avec ta méthode ça force à lire le contenu de l'exe pour récupérer le source
Alors qu'en passant par la data section la commande read suffit

Après c'est un choix ... :)

Ma poubelle te passe le bonjour.

Signé le crasseux
Dernière modification par Zorro le jeu. 04/janv./2018 14:07, modifié 1 fois.
Image
Image
Site: http://michel.dobro.free.fr/
Devise :"dis moi ce dont tu as besoin, je t'expliquerai comment t'en passer"
G-Rom
Messages : 3627
Inscription : dim. 10/janv./2010 5:29

Re: les bases d'un interpreteur/et pseudo compilation en *.E

Message par G-Rom »

Avec ta méthode ça force à lire le contenu de l'exe pour récupérer le source
Alors qu'en passant par la data section la commande read suffit
Dans tout les cas, tu lis quelque chose... seul l'endroit change.
Avatar de l’utilisateur
djes
Messages : 4252
Inscription : ven. 11/févr./2005 17:34
Localisation : Arras, France

Re: les bases d'un interpreteur/et pseudo compilation en *.E

Message par djes »

Bonne idée ! Je me disais que j'allais ajouter mes deux cents avec un exemple d'utilisation d'une section .CODE pour inclure un programme compilé, et puis en cherchant sur le forum anglais, j'ai trouvé beaucoup mieux, par Keya : l'allocation d'une zone mémoire que l'on rend exécutable, où l'on copie une petite portion de code, et qu'on lance.

Voir http://www.purebasic.fr/english/viewtop ... 12&t=64101

On trouve tout sur nos forums !!! :)
Avatar de l’utilisateur
Zorro
Messages : 2185
Inscription : mar. 31/mai/2016 9:06

Re: les bases d'un interpreteur/et pseudo compilation en *.E

Message par Zorro »

G-Rom a écrit :
Avec ta méthode ça force à lire le contenu de l'exe pour récupérer le source
Alors qu'en passant par la data section la commande read suffit
Dans tout les cas, tu lis quelque chose... seul l'endroit change.
Oui , mais dans mon cas la fonction de lecture de la zone Data est prevue dans Purebasic
j'ai juste a faire :

Code : Tout sélectionner

Restore code:
While ligne_code.s<> "fin_code"
		read.s ligne_code.s
.....
alors que dans ton exemple, il faut la faire ...
Prechargement du source,(en sautant apres l'executable) puis lecture RAM pour traitement...

mais d'un autre coté ça ouvre peut etre d'autre possibilités ...
je pense a la lecture d'un son,planche de sprite, Exe, etc... notamment, (voir toutes ces choses mélangées ....)
les fonctions Purebasic, sont plus variées pour la lecture de binaire dans un fichier/Ram

je serai peut etre plus vite bloqué avec mon read dans la SectionData .?! ... je sais pas , jamais fait de tests
Image
Image
Site: http://michel.dobro.free.fr/
Devise :"dis moi ce dont tu as besoin, je t'expliquerai comment t'en passer"
Avatar de l’utilisateur
Kwai chang caine
Messages : 6962
Inscription : sam. 23/sept./2006 18:32
Localisation : Isere

Re: les bases d'un interpreteur/et pseudo compilation en *.E

Message par Kwai chang caine »

GRom a écrit :ne pas faire un simple Run , mais créer un Exe dans la racine de votre source
Alors comme dab, si y'en a un chez qui ça marche pas... :oops:
J'ai créé l'exe "Concat.exe", le l'ai déposé à coté du code source
J'ai lancé le code source, j'ai bien le code source à la fin de l'EXE en le regardant avec notepad 8)
Mais par contre quand le le lance, j'ai ça 8O
[Debugger Error] Le #File spÚcifiÚ n'est pas initialisÚ.
[Debugger Error] File: Concat.pb (Line: 44)
Do you wish to continue the program? (Yes, No, Debugger Console, Ignore all)
(y,N,d,i)
J'ai cassé mon jouet, parce qu'avant j'avais une belle boite "Je marche toujours" en lançant l'exe tout frais créé "Concat.exe" :|
ImageLe bonheur est une route...
Pas une destination

PureBasic Forum Officiel - Site PureBasic
G-Rom
Messages : 3627
Inscription : dim. 10/janv./2010 5:29

Re: les bases d'un interpreteur/et pseudo compilation en *.E

Message par G-Rom »

Kwai chang caine a écrit :
GRom a écrit :ne pas faire un simple Run , mais créer un Exe dans la racine de votre source
Alors comme dab, si y'en a un chez qui ça marche pas... :oops:
J'ai créé l'exe "Concat.exe", le l'ai déposé à coté du code source
J'ai lancé le code source, j'ai bien le code source à la fin de l'EXE en le regardant avec notepad 8)
Mais par contre quand le le lance, j'ai ça 8O
[Debugger Error] Le #File spÚcifiÚ n'est pas initialisÚ.
[Debugger Error] File: Concat.pb (Line: 44)
Do you wish to continue the program? (Yes, No, Debugger Console, Ignore all)
(y,N,d,i)
J'ai cassé mon jouet, parce qu'avant j'avais une belle boite "Je marche toujours" en lançant l'exe tout frais créé "Concat.exe" :|

Pourtant , je le dit bien, "ne pas faire un simple Run" , ce qui veut dire un coup de F5... ;)
-Tu créer un exe
-Tu le lance
-un second exe est créer avec la source dedans
Avatar de l’utilisateur
ChrisR
Messages : 222
Inscription : sam. 14/févr./2015 16:20

Re: les bases d'un interpreteur/et pseudo compilation en *.E

Message par ChrisR »

Et, le 1er exe créer ne doit pas être Concat.exe sinon il ne peut pas être écrasé une fois lancé.
G-Rom as-tu un petit exemple "simple" pour la lecture des lignes de la zone Data à interpréter ?
Pour comparaison avec l'exemple de zorro et le read de la SectionData.
Zorro a écrit :vous voulez creer votre propre language ?
Plus tard , je vous ferai un exemple de gestion des variables "utilisateur" c'est assez simple :)
Dans l'attente de te lire :wink:
Répondre