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