[projet]-langage de script

Sujets variés concernant le développement en PureBasic
Avatar de l’utilisateur
case
Messages : 1527
Inscription : lun. 10/sept./2007 11:13

[projet]-langage de script

Message par case »

Salut
je cherche a créer un langage de script pour un projet de jeu.
j'aimerais une syntaxe proche du basic et je rencontre pas mal de difficultés.

actuellement j'ai une ébauche.
avec quelques fonctions qui sortent le résultat en debug
tout n'est pas implémenté j'aimerais un peu d'aide pour les boucles par exemple
le script étant exécuté ligne par ligne comment faire pour que le script retourne au début d'une boucle lorsqu'il rencontre l'instruction de fin de boucle
et si on imbrique des boucles ca complique encore le travail.
est-ce qu'il vaudrais mieux que je parcours tout le script avant l’exécution pour définir les début et fin de boucles etc ?

je ne cherche pas forcement du code mais plus de l'aide sur la façon de procéder.
peut être aussi que tout mon code est foireux et qu'il faudrait tout reprendre.

Code : Tout sélectionner

Structure vars   ; variables non implémentées 
  name.s                                  ;// nom de la variable dans le code
  type.s                                  ;// tpe de variable ( string, numeric )
  cont.s                                  ;// contenu de la variable.
EndStructure
Structure scriptor
  script.s                                ; string contenant le script
  value.i                                 ; valeur de la ligne de script ( ex boucle)
  bra.i                                   ; valeur de branchement dans le script ( goto, next etc...)
EndStructure

Structure script
  ID.i                                    ;  l'id script  
  List locals.vars()                      ;  variables locales du script.  
  List functions.script()                 ;  fonctions dans le script
  List script.scriptor()
  line.i                                  ;  ligne actuelle du script
EndStructure
Global NewList globals.vars()             ; Variables globales utilisées par les scripts
Global NewList functions.script()         ; fonctions globales du moteur
Global NewList scripts.script()


Procedure.s calc(st$)
  dst$=st$
  ;
  ;   cette section remplace les strings par des tags afin de ne pas parser le contenu
  ;   et les stocke dans un tableau pour les reafficher ensuite
  ;
  Dim strings.s(0)
  While FindString(st$,"'")
    strg$=""  
    fnd=0
    For a=FindString(st$,"'") To Len (st$)
      If fnd=0 
        If Mid(st$,a,1)="'" 
          fnd=1
          st=a
        EndIf      
      Else
        If fnd=1
          If Mid(st$,a,1)="'" 
            fnd=0
            rep+1
            ReDim strings(rep)
            strings(rep)=Mid(st$,st,a-st+1)
            st$=Left(st$,st-1)+Chr(1)+Str(rep)+Chr(1)+Right(st$,Len(st$)-a)
            Break
          EndIf  
        EndIf
      EndIf
    Next  
  Wend
  ; calculs
  res=0
  res$=""
  ; remplace les signes par des espaces pour ne garder que les valeurs a traiter  
  noig$=ReplaceString(st$,"+"," ")
  noig$=ReplaceString(noig$,"*"," ")
  noig$=ReplaceString(noig$,"/"," ")
  noig$=ReplaceString(noig$,"-"," ")  
  noig$=ReplaceString(noig$,")"," ")     
  noig$=Trim(ReplaceString(noig$,"("," "))
  ; ne garde que les signes  pour effectuer les operations
  noda$=ReplaceString(st$,"(","")
  noda$=ReplaceString(noda$,")","")
  For a=0 To 255
    If Chr(a)<>"+" And Chr(a)<>"-" And Chr(a)<>"*" And Chr(a)<>"/"
      noda$=ReplaceString(noda$,Chr(a),"")
    EndIf
  Next 
  num=CountString(noig$," ")+1
  Dim valu$(num+1)
  For v=1 To num 
    valu$(v)=StringField(noig$,v," ")
  Next
  ; prioritise les calculs 
  ; multiplications et divisions
  While FindString(noda$,"*")  Or FindString(noda$,"/")
    c=0
    pos1=FindString(noda$,"*")
    pos2=FindString(noda$,"/")
    If pos1=0
      pos=pos2 ; division
    ElseIf pos2=0
      pos=pos1
      c=1 ; multiplication      
    ElseIf pos1<pos2
      pos=pos1
      c=1 ; multiplication      
    Else
      pos=pos2 ; division
    EndIf    
    dat1.s=(valu$(pos))
    dat2.s=(valu$(pos+1))     
    If c=1      
      res=Val(dat1)*Val(dat2)
      numeric=1
    Else
      If Val(dat2)>0
        res=Val(dat1)/Val(dat2)
        numeric=1
      Else
        ;error_handler="ERROR DIVISION BY ZERO"
      EndIf    
    EndIf
    noda$=Left(noda$,pos-1)+Right(noda$,Len(noda$)-pos)
    For k=pos To num-1
      valu$(k)=valu$(k+1)
    Next
    valu$(pos)=Str(res)   
  Wend  
  While FindString(noda$,"-")  Or FindString(noda$,"+")        ; addition / soustractions

    c=0
    pos1=FindString(noda$,"+")
    pos2=FindString(noda$,"-")    
    If pos1=0
      pos=pos2
    ElseIf pos2=0
      pos=pos1
      c=1 ; add      
    ElseIf pos1<pos2
      pos=pos1
      c=1 ; add      
    Else
      pos=pos2
    EndIf     
    dat1.s=(valu$(pos))
    dat2.s=(valu$(pos+1))      
    If c=0
      res=Val(dat1)-Val(dat2)
      noda$=Left(noda$,pos-1)+Right(noda$,Len(noda$)-pos)      
    Else
      If FindString(dat1,Chr(1))=0 And FindString(dat2,Chr(1))=0 ; not string
        res=Val(dat1)+Val(dat2)
        numeric=1
        noda$=Left(noda$,pos-1)+Right(noda$,Len(noda$)-pos)              
      Else ; concatenation de chaines **
        dat2.s=(valu$(pos+1))                   
        noda$=Left(noda$,pos-1)+" "+Right(noda$,Len(noda$)-pos)
        res$=RemoveString(strings(Val(RemoveString(dat1,Chr(1)))),"'")+RemoveString(strings(Val(RemoveString(dat2,Chr(1)))),"'")
        strings(Val(RemoveString(dat1,Chr(1))))=res$
        strings(Val(RemoveString(dat2,Chr(1))))=res$   
      EndIf
    EndIf    
    valu$(pos)=Str(res)       
  Wend  
  If res$="" And numeric=1
    res$=Str(res)
  Else
  EndIf 
  If res$=""
    res$=dst$
  EndIf
  ProcedureReturn res$
EndProcedure
Procedure.s cAbs(st$)
  st$= RemoveString(st$,"(")
  st$= RemoveString(st$,")")
  st$=calc(st$)
  ProcedureReturn RemoveString(st$,"-")
EndProcedure
Procedure.s cstr(st$)
  st$= RemoveString(st$,"(")
  st$= RemoveString(st$,")")
  st$=calc(st$)  
  ProcedureReturn  "'"+st$+"'"  
EndProcedure
Procedure.s cval(st$)
  st$= RemoveString(st$,"(")
  st$= RemoveString(st$,")")
  st$=calc(st$)  
  ProcedureReturn RemoveString(st$,"'")
EndProcedure
Procedure.s parenthesis(st$)
  While FindString  (st$,"(")    
    fnd=0
    For search=1 To Len(st$)
      If Mid(st$,search,1)="("
        st=search        
      EndIf      
      If Mid(st$,search,1)=")"
        en=search        
        fnd=1
        Break
      EndIf      
    Next
    If fnd=1      
      LFT$=Left(st$,st-1)
      RGH$=Right(st$,Len(st$)-en)     
      PAR$= Mid(st$,st,en-(st-1))               
      st$=LFT$+calc(PAR$)+RGH$     
    EndIf
  Wend
  ProcedureReturn st$
EndProcedure
Procedure.s values(st$)
  While FindString  (st$,"(")
    fnd=0
    For search=1 To Len(st$)
      ;
      If Mid(st$,search,1)="("
        st=search        
      EndIf      
      If Mid(st$,search,1)=")"
        en=search        
        fnd=1
        Break
      EndIf      
    Next
    If fnd=1                 
      Select Mid(st$,st-3,3)  
        Case "abs","str","val"
          LFT$=Left(st$,st-4)
          PAR$= Mid(st$,st,en-(st-1))               
          RGH$=Right(st$,Len(st$)-en)          
          Select Mid(st$,st-3,3)  
            Case "abs"
              nv$=cabs(PAR$)
            Case "str"
              nv$=cstr(PAR$)
            Case "val"
              nv$=cval(PAR$)            
              
          EndSelect
        Default
          LFT$=Left(st$,st-1)
          nv$=calc(Mid(st$,st,en-(st-1)))
          RGH$=Right(st$,Len(st$)-en) 
      EndSelect
      st$=LFT$+nv$+RGH$   
    EndIf
  Wend 
  ProcedureReturn st$
EndProcedure
Procedure Prnt(st$)
  s$=values(st$)
  s$=parenthesis(s$)
  s$=calc(s$)
  Debug s$
EndProcedure
Procedure eval(st$)
  ;
  ;   cette section remplace les strings par des tags afin de ne pas parser le contenu
  ;   et les stocke dans un tableau pour les reafficher ensuite
  ;
  Dim strings.s(0)  
  While FindString(st$,"'")
    strg$=""  
    fnd=0
    For a=FindString(st$,"'") To Len (st$)      
      If fnd=0 
        If Mid(st$,a,1)="'" 
          fnd=1
          st=a
        EndIf      
      Else
        If fnd=1
          If Mid(st$,a,1)="'" 
            fnd=0
            rep+1
            ReDim strings(rep)
            strings(rep)=Mid(st$,st,a-st+1)
            st$=Left(st$,st-1)+Chr(1)+Str(rep)+Chr(1)+Right(st$,Len(st$)-a)
            Break
          EndIf  
        EndIf
      EndIf
    Next  
  Wend
  ;
  ; cette section parse la ligne de script pour executer les commandes
  ; 
  nb=CountString(st$,":")  
  For ev=1 To nb+1 
    pair$=StringField(st$,ev,":")    
    cmd$=StringField(pair$,1," ")
    valu$=StringField(pair$,2," ") 
    ;
    While FindString(valu$,Chr(1))
      st=FindString(valu$,Chr(1))
      en=FindString(valu$,Chr(1),st+1)            
      idx=Val(RemoveString(Mid(valu$,st,a-st+1),Chr(1)))
      valu$=Left(valu$,st-1)+strings(idx)+Right(valu$,Len(valu$)-en)            
    Wend 
    Select LCase(cmd$)
      Case "print"
        prnt(valu$)               
      Case "end"
        End
    EndSelect
  Next
EndProcedure
AddElement(scripts())
AddElement(scripts()\script())
scripts()\script()\script = "print str(59+5)+str(abs(-1))+str(val('2'))+str(3*4+(5*6))+str(7*8):print 'ceci est : un test ':print val('5')+val(50):end" 
Repeat
  If ListSize(scripts())
    ForEach scripts()
      If ListSize(scripts()\script())
        SelectElement(scripts()\script(),scripts()\line)
        eval(scripts()\script()\script)   
        If NextElement(scripts()\script())
          scripts()\line +1
        Else
          scripts()\line =0
        EndIf
      EndIf
    Next
  EndIf
ForEver
DataSection
  keywords:        ; non implementé pour l'instant 
  Data.s "end","print","str","val","abs"
EndDataSection
ImageImage
Avatar de l’utilisateur
Zorro
Messages : 2185
Inscription : mar. 31/mai/2016 9:06

Re: [projet]-langage de script

Message par Zorro »

est-ce qu'il vaudrais mieux que je parcours tout le script avant l’exécution pour définir les début et fin de boucles etc ?
oui !! clairement

perso j'utilise une liste chainée qui me sert de "pile d'instructions"

tu fait une premiere passe qui analyse chaque ligne de code

tu rencontre un "For" (debut de boucle ) , tu notes sa position (numero de ligne) dans un tableau ou une liste ....
si tu rencontre a nouveau un "For" , tu notes sa positon (numero de ligne ) etc ....

tu rencontres un Next (fin_de boucle) , (alors je te conseille d'inverser le sens de la liste des FOR si tu utilises une list chainée )


tu notes la position de ce Next et tu l'associes au Dernier element de 'for" (le premier de la list FOR si tu l'a inversé ;) )
tu fais l'association soit en utilisant un nouveau tableau , ou une nouvelle liste....Structure ... bref ce qui te passe par la tete


lors de l'execution , tu n'aura plus qu"a lire que Ligne XX tu as un FOR , tu aura du coup automatiquement son NEXT correspondant

ps: je sais pas si je suis clair


ps2: la meme chose est a faire pour les "IF" -"ENdIF"

les fonctions aussi , mais plus simple, puisque il y a un Saut vers la fonction , il faut savoir sur quelle ligne elle se trouve ..
par contre le retour, c'est simple , en principe juste avant le Saut tu note le numero de ligne
comme ça au Return , tu sais ou revenir

ce numero de ligne, tu "l'empile" sur ta liste des instruction (La pile)
et tu "Depiles" lorsque tu ressors de ta fonction ....

le principe de pile, permet ainsi d'imbriquer les boucles, les If et les appels de fonctions (une fonction qui en appel une autre )
voir meme de gerer la récursivité !! (ce que j'ai fait dans mon PureGolo )


pour verifier le tout, je te conseille un system de Flag
genre :
1- je rencontre un If .... (je met mon Flag=1 )
2- je rencontre un autre IF ( je met mon flag =2 )
3- je fait d'autres chose ... a ce moment mon Flag des IF est encore superieur a 0 donc il manque des Endif

4- si je suis en fin de prg , il y a un probleme de syntaxe, il manque des Endif , car mon Flag est toujours a 2

5- je ne suis pas a la fin , voici un ENDIF , ok , Flag=Flag-1
6- voici mon dernier Endif : ok, Flag=Flag-1
7- Flag =0 tout va bien ;)

ps: on peut meme utiliser Flag pour creer un code mis en forme


en definitif un interpreteur c'est composé d'une pile , d'un pointeur d'instructions qu'on fait descendre dans le code ou remonter si boucle


le pointeur Designe la ligne en cours , il s’incrémente pour chaque ligne executée , il contient le numero de ligne en cours

la pile servira a noter (empiler ) la position des sauts, pour les retours , une simple liste Suffit pour ça !

il te faudra une liste structuré aussi pour les IF ENDIF .....
il te faudra aussi une liste structuré pour tes variables .... list avec Structure qui contient le nom de la variable , son type, son contenu ....

tu peux eventuellement lire ce topic
http://www.purebasic.fr/french/viewtopi ... terpreteur
Fait par G-Rom ("Anonyme" )
Dernière modification par Zorro le ven. 16/juin/2017 15:24, modifié 11 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
falsam
Messages : 7244
Inscription : dim. 22/août/2010 15:24
Localisation : IDF (Yvelines)
Contact :

Re: [projet]-langage de script

Message par falsam »

case a écrit :est-ce qu'il vaudrais mieux que je parcours tout le script avant l’exécution pour définir les début et fin de boucles etc ?
Tout comme zorro je confirme que oui.
Configuration : Windows 11 Famille 64-bit - PB 6.03 x64 - AMD Ryzen 7 - 16 GO RAM
Vidéo NVIDIA GeForce GTX 1650 Ti - Résolution 1920x1080 - Mise à l'échelle 125%
Avatar de l’utilisateur
case
Messages : 1527
Inscription : lun. 10/sept./2007 11:13

Re: [projet]-langage de script

Message par case »

j'avais pas vu ce poste de grom... je vais le lire .avec le principe de pile du coup j'ai pas besoin de prelire le script du coup puisque l’élément actuel correspond toujours a la dernière boucle rencontrée
ImageImage
Avatar de l’utilisateur
ChrisR
Messages : 221
Inscription : sam. 14/févr./2015 16:20

Re: [projet]-langage de script

Message par ChrisR »

A la suite du poste de G-Rom,
Tu peux regarder ce poste de Thyphoon avec une base de Language Interprété et avec le principe de la pile
http://www.purebasic.fr/french/viewtopi ... =6&t=11936
Sujet interessant, tiens nous au courant
G-Rom
Messages : 3626
Inscription : dim. 10/janv./2010 5:29

Re: [projet]-langage de script

Message par G-Rom »

Bonjour Case, créer un langage de script équivaut à recréer la partie avant d'un compilateur,
c'est à dire , la lecture d'un code source, du nettoyage ( commentaire , espace superflu , etc... ) , de l'analyse lexicale , de l'analyse syntaxique et la mise sous forme d'arbre, les jetons que constitue ton code... c'est compliqué à faire pour avoir quelque chose qui marche correctement. mais c'est faisable.
Sinon, il existe la possibilité d'adjoindre à ton code des langages embarqué qui marche très bien, lua, angelscript, javascript , etc...
je dispose d'un code permettant l'embarquement de javascript au sein d'un programme PureBasic , c'est un wrapp de duktape (http://duktape.org)
le code source est disponible , avec quelque exemples, je ne le distribue pas , mais je peu te le donner en mp si cela t'intéresse.
Tu peu avec cela , scripté n'importe quel partie de ton programme pour peu que celui ci "s'expose" à javascript.
c'est toi qui choisi d'exposé ce que tu veut.
je suis revenu exprès pour toi d'entre les morts. je remercie Falsam & Fred.
Avatar de l’utilisateur
case
Messages : 1527
Inscription : lun. 10/sept./2007 11:13

Re: [projet]-langage de script

Message par case »

salut grom, je suis très content que tu revienne du royaume des morts pour moi ,
ça fait toujours plaisir d'avoir des nouvelles, merci pour ta proposition est-ce facile a implanter ?
coder en JavaScript je ne sais pas si je pourrais le faire.
j'ai plus autant de facilité a programmer qu'avant.
je veux bien regarder et tester ton wraper, bien sur je ne diffuserais rien que tu ne veuille toi même diffuser ,)
en tout cas dommage que tu ne passes pas plus souvent ^ ^

pour le mp faudrait que tu réactive ta boite a mp ^^
ImageImage
G-Rom
Messages : 3626
Inscription : dim. 10/janv./2010 5:29

Re: [projet]-langage de script

Message par G-Rom »

Oui, c'est facile à implémenté , la dll marche avec pb x86
Les procédures PB que tu veut exposé doivent etre en ProcedureC , je te laisse regardé les exemples.
Avatar de l’utilisateur
case
Messages : 1527
Inscription : lun. 10/sept./2007 11:13

Re: [projet]-langage de script

Message par case »

merci je vais regarder :)
ImageImage
Avatar de l’utilisateur
Kwai chang caine
Messages : 6962
Inscription : sam. 23/sept./2006 18:32
Localisation : Isere

Re: [projet]-langage de script

Message par Kwai chang caine »

@CPL
Je sais pas qui est le malotru qui a osé te tuer :? , mais je profite que tu revives pour te dire que tu me manque et je suis sûr de ne pas être le seul :cry:
C'est que je l'ai toujours aimé moi, le capitaine au langage plus que militaire :mrgreen: l'inventeur du "tiroir à con" :lol: j'en rie encore :lol:
La bonne nouvelle, c'est qu'il ne t'es rien arrivé :D
Au plaisir de te relire 8)
ImageLe bonheur est une route...
Pas une destination

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

Re: [projet]-langage de script

Message par G-Rom »

Kwai chang caine a écrit :@CPL
Je sais pas qui est le malotru qui a osé te tuer :? , mais je profite que tu revives pour te dire que tu me manque et je suis sûr de ne pas être le seul :cry:
C'est que je l'ai toujours aimé moi, le capitaine au langage plus que militaire :mrgreen: l'inventeur du "tiroir à con" :lol: j'en rie encore :lol:
La bonne nouvelle, c'est qu'il ne t'es rien arrivé :D
Au plaisir de te relire 8)
Toujours autant de tchatche le père kcc. ;)
Merci.
Avatar de l’utilisateur
blendman
Messages : 2017
Inscription : sam. 19/févr./2011 12:46

Re: [projet]-langage de script

Message par blendman »

Punaise, ouais, G-rom, ça fait plaisir de te revoir sur ce forum ;)
Tu m'as énormément aidé sur PB (avec Dobro et pas mal autres utilisateurs) et je t'en remercie :).

Content de voir que tu vas bien.
G-Rom
Messages : 3626
Inscription : dim. 10/janv./2010 5:29

Re: [projet]-langage de script

Message par G-Rom »

blendman a écrit :Punaise, ouais, G-rom, ça fait plaisir de te revoir sur ce forum ;)
Tu m'as énormément aidé sur PB (avec Dobro et pas mal autres utilisateurs) et je t'en remercie :).

Content de voir que tu vas bien.
Merci Blendman.
Avatar de l’utilisateur
MLD
Messages : 1097
Inscription : jeu. 05/févr./2009 17:58
Localisation : Bretagne

Re: [projet]-langage de script

Message par MLD »

Avec un peu de retard :cry:

Salut G-Rom.
Quel plaisir de te revoir ici :lol:
Vient un peu plus souvent STP
Avatar de l’utilisateur
Kwai chang caine
Messages : 6962
Inscription : sam. 23/sept./2006 18:32
Localisation : Isere

Re: [projet]-langage de script

Message par Kwai chang caine »

Le GRom c'était notre petit soleil à nous
Notre petite brindille, oscillant au gré du souffle de la brise du matin
Tout de délicatesse et de tendresse à la fois...
Un cerveau d'acier dans un écrin de velour ... :mrgreen:

Image

Enfin cétait notre GRom quoi :cry:
ImageLe bonheur est une route...
Pas une destination

PureBasic Forum Officiel - Site PureBasic
Répondre