View difference between Paste ID: PRc2zCcW and 0fbUa8eR
SHOW: | | - or go back to the newest paste.
1
# Manipulation de fichiers
2
	# File.write(fichier, texte)          - écrit à la suite du fichier
3
	# File.rewrite(fichier, texte)        - réécrit tout le fichier
4
	# File.writeline(fichier, texte)      - écrit dans une nouvelle ligne du fichier (à la fin)
5
	# File.writefirstline(fichier, texte) - écrit dans une nouvelle ligne du fichier (au début)
6
	# File.open(fichier, mode)            - permet d'ouvrir le fichier avec un mode
7
	# File.read(fichier)                  - permet de lire le fichier
8
	# File.readline(fichier, ligne)       - permet de lire une ligne spécifique du fichier
9
	# File.close(fichier)                 - permet de fermer le fichier
10
11
# Manipulation des textes
12
	# String.lower(texte)  - 
13
	# String.upper(texte)  - 
14
	# String.length(texte) - 
15
16
# Manipulation de la console
17
	# Console.clean.          - Efface tout le contenu (ce qui est écrit) de la console
18
	# Console.print   "Texte" - Affiche un texte sur la ligne courante
19
	# Console.println "Texte" - Affiche un texte sur une nouvelle ligne
20
21
# Manipulation des int et des float
22
	# Math.round 12.5  - 
23
	# Math.ceil 12.5   - 
24
	# Math.floor 12.5  - 
25
	# Math.random 12.5 - 
26
27
# Manipulation des tableaux
28
	# Array.in(element, array) - Retourne true si l'element se trouve dans l'array
29
	# Array.empty(array)       -
30
	# Array.size(array)        - 
31
32
# Définition des variables globales
33
	# *Non obligatoire signifie qu'il est possible de créer la fonction dans un script BM
34
	# 	mais c'est mieux si nous on créer la fonction plutôt que de déléguer ça aux développeurs
35
36
	opcodes = [
37
		# fonction             entre  adresse
38
		["nop",                 '\0', "\x00\x00"], # 
39
		["#",                   '\0', "\x00\x01"], # 
40-
		["if",                  '(',  "\x00\x02"], # 
40+
		["if",                  ' ',  "\x00\x02"], # 
41-
		["elseif",              '(',  "\x00\x03"], # 
41+
		["elseif",              ' ',  "\x00\x03"], # 
42
		["else",                '\0', "\x00\x04"], # 
43
		["end",                 '\0', "\x00\x05"], # 
44
		["continue",            '\0', "\x00\x06"], # 
45
		["break",               '\0', "\x00\x07"], # 
46
47
		["Program.exit",        '\0', "\x01\x00"], # 
48
49
		["Console.clean",       '\0', "\x02\x01"], # 
50
		["Console.print",       ' ',  "\x02\x01"], # 
51
		["Console.println",     ' ',  "\x02\x02"], # 
52
		["Console.sleep",       ' ',  "\x02\x03"], # 
53
54
		["String.lower",        '(',  "\x03\x00"], # 
55
		["String.upper",        '(',  "\x03\x01"], # 
56
		["String.length",       '(',  "\x03\x02"], # 
57
58
		["Math.floor",          '(',  "\x04\x00"], # 
59
		["Math.round",          '(',  "\x04\x01"], # 
60
		["Math.ceil",           '(',  "\x04\x02"], # 
61
		["Math.random",         '(',  "\x04\x03"], # 
62
63
		["Array.in",            '(',  "\x05\x00"], # Non obligatoire
64
		["Array.empty",         '(',  "\x05\x01"], # Non obligatoire
65
		["Array.size",          '(',  "\x05\x02"], # Non obligatoire
66
67
		["File.open",           '(',  "\x06\x00"], # 
68
		["File.write",          '(',  "\x06\x01"], # 
69
		["File.writeLine",      '(',  "\x06\x02"], # 
70
		["File.writeFirstLine", '(',  "\x06\x03"], # 
71
		["File.rewrite",        '(',  "\x06\x04"], # 
72
		["File.isEmpty",        '(',  "\x06\x05"], # 
73
		["File.read",           '(',  "\x06\x06"], # 
74
		["File.readLine",       '(',  "\x06\x07"], # 
75
		["File.close",          '(',  "\x06\x08"], # 
76
		["File.countLine",      '(',  "\x06\x09"]  # 
77
	]
78
79
	nbrWarnings = 0
80
	nbrErrors   = 0
81
82
# Fonction de compilation
83
	compile (File Src, File Dst)
84
		Data = [][]                 # contient le fichier source [ligne][colonne]
85
		nbrLignes = File.countLine(Src) # nombre de lignes du fichier
86
87
		print "Compilation de \"" . Src . "\" -> \"" . Dst . "\"...\n"
88
89
		if File.open(Src, "r") == null # Si le fichier source est inaccessible en lecture on affiche une erreur
90
			exit "Le fichier source \"" . Src . "\" n'a pu être ouvert en lecture."
91
		end
92
93
		for i = 0 to nbrLignes
94
			if File.readline(Src, Data[i]) != 1
95
				exit "Le fichier source \"" . Src . "\" n'a pu être lu correctement."
96
			end
97
98
			File.close(fpSrc)
99
		end
100
101
		if File.isEmpty(Src)
102
			exit "Le fichier source \"" . Src . "\" est vide.\n"
103
		end
104
105
		if File.open(Dst, "wb") == null # Si le fichier de destination n'a pas pu être ouvert en écriture on affiche une erreur
106
			exit "Le fichier de destination \"" . Dst . "\" n'a pu être ouvert en écriture."
107
		end
108
109
		File.write(Dst, "BM01")
110
111
		for y = 0 to nbrLignes
112
			if Data[y][0] == '\0'
113
				continue
114
			end
115
116
			for x = 0 to Array.size(opcodes)
117
				if Array.in(Data[y][x], opcodes)
118
					File.write(Dst, [j].code)
119
					k = 0
120
121
					# ---------------------------- #
122
					# début partie en modification #
123
					# ---------------------------- #
124
					if [j].nextCar != '\0'
125
						if [j].nextCar == ' '
126
							for (k=strlen (opcodes [j].str) ; Data [y][k]==' ' && k < strlen (Data [y]) ; k++)
127
							end
128
						else
129
							for (k=strlen (opcodes [j].str) ; (Data [y][k]!=opcodes [j].nextCar || Data [y][k]==' ') && k < strlen (Data [y]) ; k++)
130
							end
131
						end
132
133
						if k >= strlen (Data[y])
134
							exit "Instruction invalide dans le fichier " . Src . ":" . (y + 1) . "."
135
							break
136
						end
137
					end
138
					# -------------------------- #
139
					# fin partie en modification #
140
					# -------------------------- #
141
				else.
142
					exit "Instruction inconnue : \"" . Data[y] . "\" dans le fichier " . Src . ":" . (y + 1) . "."
143
				end
144
			end
145
		end
146
147
		File.close(Dst)
148
		print "Compilation terminée (" . nbrErrors . " erreur(s) et " . nbrWarnings . " warning(s))"
149
150
		if (nbrErrors > 0)
151
			return false
152
		end
153
154
		return true
155
	end
156
157
158
159
160
Syntaxe d’un objet BootMonkey
161
(Fichier binaire exécutable)
162
163
Signature (sur 4 octets) : “BM01”. Sans cette signature, l’exécutable .rbm NE pourra PAS être exécuté !
164
Puis :
165
166
Pour chaque instruction (non conditionnelle):
167
168
        code de l’instruction (2 octets).
169
        adresse de l’instruction suivante à partir du début du fichier (4 octets).
170
        nombre de paramètres (sur 1 octet)
171
            Pour chaque paramètre :
172
173
    - Son type (1 octets)
174
175
        - Le premier demi-octet : Type de variable (1=constante immédiate/0=adresse d’une variable).
176
177
        - Le deuxième demi-octet : Taille de la variable (1 ou 2 ou 4 / 4 obligatoire pour l’adresse d’une variable).
178
179
    - Son contenu (1 ou 2 ou 4 octets)
180
181
        En fonction du type.
182
183
184
	
185
186
187
// PISTES
188
	
189
190
				switch (opcodes [j].nextCar)
191
				{
192
					case ' ':
193
					{
194
						// ArgsSize est la taille de l'argument passé en paramètre.
195
						uint32_t ArgsSize = strlen (Data [i]) - k ;
196
						// ArgsSize + 1 pour prendre en compte le '\0' de fin de chaîne.
197
						uint8_t *Var = malloc (ArgsSize + 1) ;
198
						memcpy (Var, &Data [i][k], ArgsSize + 1) ;
199
						
200
						// ArgsSize - 1 car ArgsSize est un tableau, donc pour utiliser le dernier paramètre
201
						if (Var [0] == '\"' && Var [ArgsSize - 1] == '\"')
202
						{
203
							// addr est l'adresse de l'instruction suivante.
204
							uint32_t addr = ftell (fpDst) + 4 + (ArgsSize - 2) + 1 ;
205
							uint32_t fill = 0 ;
206
							fwrite (&addr, 1, 4, fpDst) ;
207
							for (uint32_t k=1 ; k < ArgsSize-1 ; k++)
208
							{
209
								if (Var [k] == '\\' && k+1 < ArgsSize-1)
210
								{
211
									switch (Var [++k])
212
									{
213
										case '\\':
214
											Var [k] = '\\' ;
215
											break ;
216
										case '\"':
217
											Var [k] = '\"' ;
218
											break ;
219
										case '\'':
220
											Var [k] = '\'' ;
221
											break ;
222
										case 'a':
223
											Var [k] = '\a' ;
224
											break ;
225
										case 'b':
226
											Var [k] = '\b' ;
227
											break ;
228
										case 'e':
229
											Var [k] = '\e' ;
230
											break ;
231
										case 'f':
232
											Var [k] = '\f' ;
233
											break ;
234
										case 'n':
235
											Var [k] = '\n' ;
236
											break ;
237
										case 'r':
238
											Var [k] = '\r' ;
239
											break ;
240
										case 't':
241
											Var [k] = '\t' ;
242
											break ;
243
										case 'v':
244
											Var [k] = '\v' ;
245
											break ;
246
										default:
247
											warning ("Séquence d'échappement invalide \"\\%c\" dans le fichier %s:%d, utilisation du caractère sans échappement.", Var [k], Src, i+1) ;
248
											break ;
249
									}
250
									fill++ ;
251
								}
252
									
253
								fprintf (fpDst, "%c", Var [k]) ;
254
							}
255
							fwrite ("\0", 1, 1, fpDst) ;
256
							while (fill-- > 0)
257
								fwrite ("\0", 1, 1, fpDst) ;
258
						}
259
						else if (isdigit (Var [0]))
260
						{
261
							uint32_t addr = ftell (fpDst) + 4 + ArgsSize + 1 ;
262
							fwrite (&addr, 1, 4, fpDst) ;
263
							fprintf (fpDst, "%d", atoi (&Var [0])) ;
264
							fwrite ("\0", 1, 1, fpDst) ;
265
						}
266
						else
267
							dieOnError ("Déclaration de constante immédiate illégale dans le fichier %s:%d.", Src, i+1) ;
268
						free (Var) ;
269
						break ;
270
					}
271
				}
272
				break ;
273
			}
274
		}
275
		if (j >= NbrOpCodes)
276
			dieOnError ("Instruction inconnue : \"%s\" dans le fichier %s:%d.", Data [i], Src, i+1) ;
277
	}
278
	fclose (fpDst) ;
279
	fprintf (stdout, "Compilation terminée (%d erreur", nbrErrors) ;
280
	if (nbrErrors > 1)
281
		fprintf (stdout, "s") ;
282
	fprintf (stdout, " et %d warning", nbrWarnings) ;
283
	if (nbrWarnings > 1)
284
		fprintf (stdout, "s") ;
285
	fprintf (stdout, ").\n") ;
286
	if (nbrErrors > 0)
287
		return EXIT_FAILURE ;
288
	return EXIT_SUCCESS ;
289
}