nabaztag_hack_kit 0.0.2
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +7 -0
- data/.travis.yml +3 -0
- data/CHANGELOG.md +11 -0
- data/Gemfile +4 -0
- data/README.md +119 -0
- data/Rakefile +21 -0
- data/bin/mtl_comp +41 -0
- data/bin/mtl_merge +22 -0
- data/bin/mtl_simu +40 -0
- data/bytecode/lib/buffer.mtl +109 -0
- data/bytecode/lib/button.mtl +27 -0
- data/bytecode/lib/data_helper.mtl +88 -0
- data/bytecode/lib/ear.mtl +90 -0
- data/bytecode/lib/led.mtl +33 -0
- data/bytecode/lib/rfid.mtl +50 -0
- data/bytecode/main.mtl +129 -0
- data/config.ru +6 -0
- data/ext/bytecode/Commands.md +172 -0
- data/ext/bytecode/Docs.md +488 -0
- data/ext/bytecode/README.md +5 -0
- data/ext/bytecode/lib/arp.mtl +159 -0
- data/ext/bytecode/lib/cfg.mtl +74 -0
- data/ext/bytecode/lib/choreos.mtl +1487 -0
- data/ext/bytecode/lib/dhcp.mtl +152 -0
- data/ext/bytecode/lib/dns.mtl +89 -0
- data/ext/bytecode/lib/http.mtl +84 -0
- data/ext/bytecode/lib/tcp.mtl +340 -0
- data/ext/bytecode/lib/udp.mtl +49 -0
- data/ext/bytecode/lib/util.mtl +74 -0
- data/ext/bytecode/lib/var.mtl +15 -0
- data/ext/bytecode/lib/wifi.mtl +243 -0
- data/ext/bytecode/nominal-ping.mtl +5828 -0
- data/ext/mtl/Makefile +42 -0
- data/ext/mtl/README.md +13 -0
- data/ext/mtl/bc.cpp +1891 -0
- data/ext/mtl/conf.bin.sans_password +0 -0
- data/ext/mtl/config.txt +5 -0
- data/ext/mtl/dumpbc.c +2566 -0
- data/ext/mtl/extconf.rb +1 -0
- data/ext/mtl/linux_simu.c +271 -0
- data/ext/mtl/linux_simuaudio.c +16 -0
- data/ext/mtl/linux_simuaudio.h +18 -0
- data/ext/mtl/linux_simunet.c +620 -0
- data/ext/mtl/linux_simunet.h +7 -0
- data/ext/mtl/log.c +297 -0
- data/ext/mtl/log.h +20 -0
- data/ext/mtl/main_compiler.cpp +104 -0
- data/ext/mtl/main_simu.cpp +221 -0
- data/ext/mtl/mp3/GTKANAL.H +97 -0
- data/ext/mtl/mp3/LAYER3.C +2090 -0
- data/ext/mtl/mp3/TABINIT.C +82 -0
- data/ext/mtl/mp3/common.c +265 -0
- data/ext/mtl/mp3/dct64_i386.c +316 -0
- data/ext/mtl/mp3/decode_i386.c +155 -0
- data/ext/mtl/mp3/huffman.h +332 -0
- data/ext/mtl/mp3/interface.c +258 -0
- data/ext/mtl/mp3/mpg123.h +182 -0
- data/ext/mtl/mp3/mpglib.h +44 -0
- data/ext/mtl/properties.c +293 -0
- data/ext/mtl/properties.h +10 -0
- data/ext/mtl/simu.c +750 -0
- data/ext/mtl/simuaudio.c +662 -0
- data/ext/mtl/simuaudio.h +74 -0
- data/ext/mtl/simunet.c +400 -0
- data/ext/mtl/simunet.h +30 -0
- data/ext/mtl/utils/correct_const.sh +34 -0
- data/ext/mtl/vaudio.c +677 -0
- data/ext/mtl/vaudio.h +46 -0
- data/ext/mtl/vbc.h +160 -0
- data/ext/mtl/vbc_str.h +166 -0
- data/ext/mtl/vcomp/Makefile +29 -0
- data/ext/mtl/vcomp/bootstrap.cpp +89 -0
- data/ext/mtl/vcomp/compiler.cpp +470 -0
- data/ext/mtl/vcomp/compiler.h +200 -0
- data/ext/mtl/vcomp/compiler_file.cpp +929 -0
- data/ext/mtl/vcomp/compiler_prog.cpp +250 -0
- data/ext/mtl/vcomp/compiler_term.cpp +1053 -0
- data/ext/mtl/vcomp/compiler_type.cpp +872 -0
- data/ext/mtl/vcomp/compiler_var.cpp +289 -0
- data/ext/mtl/vcomp/file.cpp +79 -0
- data/ext/mtl/vcomp/file.h +39 -0
- data/ext/mtl/vcomp/filesystem.h +14 -0
- data/ext/mtl/vcomp/interpreter.cpp +85 -0
- data/ext/mtl/vcomp/interpreter.h +121 -0
- data/ext/mtl/vcomp/memory.cpp +241 -0
- data/ext/mtl/vcomp/memory.h +326 -0
- data/ext/mtl/vcomp/param.h +95 -0
- data/ext/mtl/vcomp/parser.cpp +427 -0
- data/ext/mtl/vcomp/parser.h +97 -0
- data/ext/mtl/vcomp/parser_xml.cpp +124 -0
- data/ext/mtl/vcomp/prodbuffer.cpp +125 -0
- data/ext/mtl/vcomp/prodbuffer.h +42 -0
- data/ext/mtl/vcomp/resource.h +17 -0
- data/ext/mtl/vcomp/stdlib_core.cpp +122 -0
- data/ext/mtl/vcomp/terminal.cpp +73 -0
- data/ext/mtl/vcomp/terminal.h +30 -0
- data/ext/mtl/vcomp/util.cpp +48 -0
- data/ext/mtl/vcomp/util.h +31 -0
- data/ext/mtl/vinterp.c +1349 -0
- data/ext/mtl/vinterp.h +11 -0
- data/ext/mtl/vloader.c +127 -0
- data/ext/mtl/vloader.h +31 -0
- data/ext/mtl/vlog.c +589 -0
- data/ext/mtl/vlog.h +69 -0
- data/ext/mtl/vmem.c +424 -0
- data/ext/mtl/vmem.h +107 -0
- data/ext/mtl/vnet.c +255 -0
- data/ext/mtl/vnet.h +19 -0
- data/lib/nabaztag_hack_kit/message/api.rb +39 -0
- data/lib/nabaztag_hack_kit/message/helper.rb +39 -0
- data/lib/nabaztag_hack_kit/message.rb +36 -0
- data/lib/nabaztag_hack_kit/server.rb +50 -0
- data/lib/nabaztag_hack_kit/version.rb +3 -0
- data/lib/nabaztag_hack_kit.rb +4 -0
- data/nabaztag_hack_kit.gemspec +29 -0
- data/public/bytecode.bin +0 -0
- data/test/bytecode/helper.mtl +60 -0
- data/test/bytecode/native.mtl +28 -0
- data/test/bytecode/test.mtl +221 -0
- data/test/spec_helper.rb +5 -0
- data/test/unit/message_spec.rb +56 -0
- metadata +209 -0
@@ -0,0 +1,488 @@
|
|
1
|
+
# Projet METAL
|
2
|
+
|
3
|
+
## Grammaire
|
4
|
+
|
5
|
+
Auteur: Sylvain Huet
|
6
|
+
Création: 13/01/03
|
7
|
+
Dernière mise-à-jour: 20/02/07
|
8
|
+
|
9
|
+
|
10
|
+
## Introduction
|
11
|
+
### Aperçu sur le document
|
12
|
+
Grammaire du langage Métal.
|
13
|
+
|
14
|
+
## Description
|
15
|
+
### Types
|
16
|
+
|
17
|
+
Type = B | B( labels* )
|
18
|
+
| un | wn
|
19
|
+
| rn
|
20
|
+
| listType | tabType | [Type*]
|
21
|
+
| fun [Type*] Type
|
22
|
+
TypeMono = B | B( labels* )
|
23
|
+
| wn | rn
|
24
|
+
| listTypeMono | tabTypeMono | [TypeMono*]
|
25
|
+
| fun [TypeMono*] TypeMono
|
26
|
+
|
27
|
+
B = Type de base
|
28
|
+
un = variable liée
|
29
|
+
rn = récursion de niveau n
|
30
|
+
|
31
|
+
Les types de base sont:
|
32
|
+
|
33
|
+
I: int
|
34
|
+
S: string
|
35
|
+
F: float
|
36
|
+
Env: environnement
|
37
|
+
|
38
|
+
Cette liste n’est pas exhaustive: grâce aux structures et aux constructeurs de types, vous pouvez vous-même développer vos types de base.
|
39
|
+
|
40
|
+
Quelques commentaires sur le tableau, si vous n’êtes pas familier avec ces notations.
|
41
|
+
La première ligne définit l’expression Type, qui est en fait le type Scol. Puis, séparés par des ‘|’, on trouve les différentes manières d’écrire l’expression: cela peut être:
|
42
|
+
|
43
|
+
- B, qui est défini à la troisième ligne: c’est un type de base, tel que I, S, F, ... Donc puisque I est un type de base, B peut s’écrire I, et puisque Type peut s’écrire B, I est bien un type en Métal.
|
44
|
+
- un avec n entier: u0, u1, u2, u3, ... sont des types: ils correspondent aux variables liées.
|
45
|
+
- wn avec n entier: w0, w1, w2, w3, ... sont des types faibles.
|
46
|
+
- rn avec n entier: r0, r1, r2, r3, ... sont des types: ils définissent les récursions dans les types.
|
47
|
+
- tab Type: type tableau. Le mot tab est suivi du type des éléments du tableau. Par exemple tab I est le type d’un tableau d’entiers.
|
48
|
+
- list Type: type tableau. Le mot list est suivi du type des éléments de la liste. Par exemple list I est le type d’une liste d’entiers.
|
49
|
+
- [Type*]: type tuple. Entre crochets, on écrit plusieurs Types (c’est le sens de l’étoile *). Par exemple, [I S] est un tuple de deux éléments dont le premier est un entier et le second une chaîne de caractères. Eventuellement, le tuple est vide: [ ]. Le tuple peut lui-même contenir des tuples: [I [S I]]
|
50
|
+
- fun [Type*] Type: type fonction. le mot fun est suivi d’un tuple contenant les arguments de la fonction puis du type du résultat. Par exemple ‘fun [I I] S‘ est une fonction qui prend deux entiers en arguments, et retourne une chaîne de caractères.
|
51
|
+
|
52
|
+
L’expression TypeMono définit les types monomorphes (non polymorphes): la seule différence avec Type est l’absence des variables liées un.
|
53
|
+
|
54
|
+
|
55
|
+
### Sources
|
56
|
+
|
57
|
+
|
58
|
+
Metal = Definition*
|
59
|
+
|
60
|
+
|
61
|
+
Definition = fun Function Args = Program ;;
|
62
|
+
| var Var( = Val) ;;
|
63
|
+
| proto Function Nbargs ;;
|
64
|
+
| proto Function = Type ;;
|
65
|
+
| type TypeName ;;
|
66
|
+
| type TypeName = [ Fields ] ;;
|
67
|
+
| type TypeName = TypeConstr ;;
|
68
|
+
|
69
|
+
|
70
|
+
Program = Expr | Expr ; Program
|
71
|
+
|
72
|
+
|
73
|
+
Expr = Arithm | Arithm :: Expr
|
74
|
+
|
75
|
+
|
76
|
+
Arithm = A1 | A1 && Arithm | A1 || Arithm
|
77
|
+
|
78
|
+
|
79
|
+
A1 = A2 | !A1
|
80
|
+
|
81
|
+
|
82
|
+
A2 = A3 | A3 == A3 | A3 != A3
|
83
|
+
| A3 < A3 | A3 > A3 | A3 <= A3
|
84
|
+
| A3 >= A3 | A3 =. A3 | A3 !=. A3
|
85
|
+
| A3 <. A3 | A3 >. A3 | A3 <=. A3
|
86
|
+
| A3 >=. A3
|
87
|
+
A3 = A4 | A4 + A3 | A4 - A3
|
88
|
+
| A4 +. A3 | A4 -. A3
|
89
|
+
A4 = A5 | A5 * A4 | A5 / A4
|
90
|
+
| A5 % A4 | A5 *. A4 | A5 /. A4
|
91
|
+
A5 = A6 | A6 & A5 | A6 | A5
|
92
|
+
| A6 ^A5 | A6 << A5 | A6 >> A5
|
93
|
+
A6 = Term | -A6 | ~A6
|
94
|
+
| -. A6 | - int | - float
|
95
|
+
| float
|
96
|
+
|
97
|
+
|
98
|
+
Term = ( Program )
|
99
|
+
| int | 'char’ | nil
|
100
|
+
| string | Xml
|
101
|
+
| [ NameOfField : Expr (NameOfField : Expr)* ]
|
102
|
+
| [Expr* ] | {Expr* }
|
103
|
+
|
104
|
+
|
105
|
+
| Var(.Term)* | set Var(.Term)* = Expr
|
106
|
+
| Var(.NameOfField)* | set Var(.NameOfField)* = Expr
|
107
|
+
|
108
|
+
| Function ArgsFunction | #Function
|
109
|
+
| #{ Expr Expr Type}
|
110
|
+
|
111
|
+
| let Expr -> Locals in Expr
|
112
|
+
| if Expr then Expr else Expr
|
113
|
+
| while Expr do Expr
|
114
|
+
| for Local = Expr ; Expr ; Expr do Expr
|
115
|
+
| for Local = Expr ; Expr do Expr
|
116
|
+
| call Expr Expr
|
117
|
+
| update Expr with [ {_ , Expr}* ]
|
118
|
+
|
119
|
+
| Constr Expr | Constr0 | match Expr with Case
|
120
|
+
|
121
|
+
|
122
|
+
ArgsF = Expr ...Expr : autant de fois Expr que la fonction F a d’arguments
|
123
|
+
Args = nothing | Local Args
|
124
|
+
Locals = Local | (Locals’::Locals)
|
125
|
+
Locals’ = Local | [ Locals’’ ]
|
126
|
+
Locals’’ = {_ , Locals}*
|
127
|
+
|
128
|
+
Val = Val3 | Val3 :: Val
|
129
|
+
Val3 = Val4 | Val4 + Val3 | Val4 - Val3
|
130
|
+
| Val4 +. Val3 | Val4 -. Val3
|
131
|
+
Val4 = Val5 | Val5 * Val4 | Val5 / Val4
|
132
|
+
| Val5 % Val4 | Val5 *. Val4 | Val5 /. Val4
|
133
|
+
Val5 = Val6 | Val6 & Val5 | Val6 | Val5
|
134
|
+
| Val6 ^Val5 | Val6 << Val5 | Val6 >> Val5
|
135
|
+
Val6 = Val7 | -Val6 | ~Val6
|
136
|
+
| -. Val6 | - int | - float
|
137
|
+
| float
|
138
|
+
Val7 = int | 'char’ | nil
|
139
|
+
| string | Xml | [ Val* ]
|
140
|
+
| (Val) | { Val* }
|
141
|
+
| itof Val | ftoi Val
|
142
|
+
|
143
|
+
Fields = Field | Field, Fields
|
144
|
+
Field = NameOfField | NameOfField : TypeMono
|
145
|
+
|
146
|
+
TypeConstr = TypeConstr’ | TypeConstr’ | TypeConstr
|
147
|
+
TypeConstr’ = Constr TypeMono | Constr0
|
148
|
+
|
149
|
+
Case = Case' | Case' | Case | ( _ -> Program)
|
150
|
+
Case' = ( Constr Local -> Program ) | (Constr0 -> Program )
|
151
|
+
|
152
|
+
|
153
|
+
Var = nom de variable
|
154
|
+
Function = nom de fonction
|
155
|
+
TypeName = nom de type | nom de type( labels* )
|
156
|
+
|
157
|
+
Local = variable locale (liée)
|
158
|
+
NameOfField = nom de champ dans une structure
|
159
|
+
Constr = constructeur de type
|
160
|
+
Constr0 = constructeur de type vide
|
161
|
+
|
162
|
+
Xml = < Tag (Attribute*)>Sub</ Tag >
|
163
|
+
Sub = nothing
|
164
|
+
| Text
|
165
|
+
| Xml Sub
|
166
|
+
| Text Xml Sub
|
167
|
+
Attribute = label = string
|
168
|
+
|
169
|
+
int = entier
|
170
|
+
char = caractère
|
171
|
+
string = chaîne
|
172
|
+
float = flottant
|
173
|
+
|
174
|
+
Les entiers peuvent être codés dans les bases suivantes:
|
175
|
+
|
176
|
+
- en décimal - 12349
|
177
|
+
- en hexa - 0x3fe
|
178
|
+
- en binaire - 0b10011
|
179
|
+
- en octal - 0o234235
|
180
|
+
|
181
|
+
Ils sont codés sur 31 bits signés.
|
182
|
+
|
183
|
+
Les char permettent de récupérer le code ascii d'un caractère: 'A est un entier qui vaut 65.
|
184
|
+
|
185
|
+
Les chaînes de caractères sont entre guillemets. Le caractère `\` permet d'accéder à certaines commandes:
|
186
|
+
|
187
|
+
- \n - retour chariot
|
188
|
+
- \z - caractère NULL
|
189
|
+
- \" - guillemet
|
190
|
+
- \\ - \
|
191
|
+
- \<nombre en décimal> - \132 est le caractère Ascii 132
|
192
|
+
|
193
|
+
Un `\` en fin de ligne permet de signaler au compilateur de ne pas tenir compte du retour à la ligne.
|
194
|
+
|
195
|
+
Les remarques sont, comme en C, entre `/*...*/` et peuvent être imbriquées les unes dans les autres.
|
196
|
+
|
197
|
+
## Fondamentaux du langage
|
198
|
+
|
199
|
+
### Hello world
|
200
|
+
|
201
|
+
On suppose l’existence d’une fonction `Secholn` de type `fun [S] S`, qui retourne l’argument, et qui, en effet de bord, affiche l’argument sur la sortie standard, suivi d’un retour à la ligne.
|
202
|
+
|
203
|
+
On suppose également qu’au démarrage, le système évalue la fonction main de type `fun[]I`.
|
204
|
+
|
205
|
+
Dans ce cas l’exemple ‘Hello world’ s’écrit simplement:
|
206
|
+
|
207
|
+
fun main=
|
208
|
+
Secholn "hello world" ;
|
209
|
+
0 ;;
|
210
|
+
|
211
|
+
Dans la suite on suppose l’existence des fonctions suivantes:
|
212
|
+
|
213
|
+
- Secho de type ‘fun [S] S’, équivalente à Secholn, mais sans le retour à la ligne
|
214
|
+
- Iecholn de type ‘fun [I] I’, équivalente à Secholn, mais pour les entiers
|
215
|
+
- Iecho de type ‘fun [I] I’, équivalente à Secho, mais pour les entiers
|
216
|
+
|
217
|
+
### Calcul et variables
|
218
|
+
On peut définir une variable globale entière x initialisée avec la valeur ‘1’ de la manière suivante:
|
219
|
+
|
220
|
+
var x = 1;;
|
221
|
+
|
222
|
+
Dans l’exemple suivant, on veut calculer x+y, et (x+y)², en utilisant le premier résultat pour calculer le second, ce qui nécessite de créer une variable locale contenant x+y.
|
223
|
+
|
224
|
+
var x = 123;;
|
225
|
+
var y = 456;;
|
226
|
+
fun main=
|
227
|
+
let x + y -> z in
|
228
|
+
(
|
229
|
+
Secho "x+y="; Iecholn z;
|
230
|
+
Secho "(x+y)²="; Iecholn z*z
|
231
|
+
);
|
232
|
+
0;;
|
233
|
+
|
234
|
+
L’opérateur `let ... -> ... in ...` permet de créer une variable locale dont le scope est uniquement l’expression qui suit le `in`.
|
235
|
+
|
236
|
+
On peut modifier une variable globale grâce à l’opérateur `set ...=...` qui retourne la valeur passée en argument et qui, par effet de bord, remplace la valeur de la variable.
|
237
|
+
|
238
|
+
Dans l’exemple suivant, on veut calculer _x+y_ et placer le résultat dans _z_.
|
239
|
+
|
240
|
+
var x=123 ;;
|
241
|
+
var y=456 ;;
|
242
|
+
var z ;;
|
243
|
+
fun main=
|
244
|
+
set z=x+y ;
|
245
|
+
0 ;;
|
246
|
+
|
247
|
+
On remarque qu’il n’est pas nécessaire d’initialiser une variable globale. Dans ce cas sa valeur initiale est `nil`. `nil` est une valeur que peuvent prendre toutes variables, quelque soit leur type, et qui est équivalent à « vide ».
|
248
|
+
|
249
|
+
L’opérateur `if...then...[else ...]` est une fonction qui, en fonction du résultat de l’expression _condition_ calcule l’expression _then_ ou l’expression _else_. Le résultat de cette expression est le résultat de la fonction _if_. On peut donc intégrer cet opérateur dans une expression arithmétique:
|
250
|
+
|
251
|
+
1+if x==2 then 3 else 4
|
252
|
+
|
253
|
+
### Itération
|
254
|
+
|
255
|
+
Le langage propose un opérateur d’itération: `for ... ; ... [ ; ...] do ...`
|
256
|
+
|
257
|
+
Dans le cas d’une itération _simple_, on peut écrire par exemple: `for i=0 ; i<20 do ...`
|
258
|
+
|
259
|
+
L’expression qui suit le _do_ est alors évaluée 20 fois avec la variable locale _i_, créée pour l’occasion et dont le scope se limite à l’expression qui suit le _do_.
|
260
|
+
|
261
|
+
Si l’itération n’est pas de type _+1_ (par exemple on veut _+2_), on utilise la forme:
|
262
|
+
|
263
|
+
for i=0 ; i<20 ; i+2 do ... // on écrit i+2, et non pas i=i+2, le ‘i=’ étant implicite
|
264
|
+
|
265
|
+
Le langage propose également un opérateur while: `while ... do ...`
|
266
|
+
|
267
|
+
Il n’y a toutefois pas de commande `break` ou `continue`.
|
268
|
+
|
269
|
+
### Gestion de listes
|
270
|
+
|
271
|
+
Les langages fonctionnels se prêtent bien à gestion de listes.
|
272
|
+
|
273
|
+
La manipulation des listes s’appuie sur trois opérateurs:
|
274
|
+
|
275
|
+
- ... :: ... (double deux-points): constructeur de liste `fun [u0 list u0] list u0`
|
276
|
+
- `hd` - récupération du premier élément `fun [list u0] u0`
|
277
|
+
- `tl` - récupération de la liste privée de son premier élément `fun [list u0] list u0`
|
278
|
+
|
279
|
+
La liste vide vaut ‘nil’
|
280
|
+
|
281
|
+
On écrit la fonction ‘dumpListI’ qui affiche le contenu d’une liste d’entiers.
|
282
|
+
|
283
|
+
fun dumpListI l=
|
284
|
+
if l==nil then Secholn "nil"
|
285
|
+
else
|
286
|
+
(
|
287
|
+
Iecho hd l; Secho "::";
|
288
|
+
dumpListI tl l
|
289
|
+
);;
|
290
|
+
|
291
|
+
On peut également écrire:
|
292
|
+
|
293
|
+
fun dumpListI l0=
|
294
|
+
for l=l0;l!=nil;tl l do (Iecho hd l; Secho "::");
|
295
|
+
Secholn "nil";;
|
296
|
+
|
297
|
+
|
298
|
+
Pour concaténer deux listes quelconques:
|
299
|
+
|
300
|
+
fun conc p q= if p==nil then q else (hd p) ::conc tl p q ;;
|
301
|
+
|
302
|
+
|
303
|
+
### Gestion des tuples
|
304
|
+
Un tuple est un ensemble de valeurs quelconques ; on le note entre crochets, par exemple:
|
305
|
+
|
306
|
+
[123 “abc”]
|
307
|
+
|
308
|
+
On crée un tuple implicitement par cette écriture. On accède aux éléments d’un tuple par l’opérateur `let`:
|
309
|
+
|
310
|
+
let tuple->[a b] in ...
|
311
|
+
|
312
|
+
Par exemple, on peut utiliser les tuples pour définir des vecteurs à 2 dimensions:
|
313
|
+
|
314
|
+
fun tup2_add a b=
|
315
|
+
let a->[xa ya] in
|
316
|
+
let b->[xb yb] in
|
317
|
+
[xa+xb ya+yb];;
|
318
|
+
|
319
|
+
On peut modifier une ou plusieurs valeurs d’un tuple par l’opérateur ‘update’:
|
320
|
+
|
321
|
+
let [123 "abc"] -> t in
|
322
|
+
(
|
323
|
+
update t with [456 "def"] ;
|
324
|
+
update t with [_ "def"];
|
325
|
+
t
|
326
|
+
);
|
327
|
+
|
328
|
+
On évitera toutefois cet usage. Si on doit effectuer des effets de bord sur les tuples, on préfera utiliser des structures (voir plus loin).
|
329
|
+
|
330
|
+
### Gestion des tables
|
331
|
+
Une table est un ensemble de valeurs de même type ; on la note entre accolades, par exemple:
|
332
|
+
|
333
|
+
{1 2 3}
|
334
|
+
|
335
|
+
On peut créer une table de deux manières:
|
336
|
+
|
337
|
+
- en utilisant l’accolade
|
338
|
+
- en utilisant l’opérateur tabnew: `fun[u0 I] tab u0`
|
339
|
+
|
340
|
+
L’opérateur tabnew prend en argument la valeur d’initialisation des éléments de la table ainsi que la taille d’un table.
|
341
|
+
|
342
|
+
On accède à un élément de la table de la manière suivante:
|
343
|
+
|
344
|
+
t.i //i-ème élément de la table t
|
345
|
+
|
346
|
+
Comme en C, les éléments sont numérotés à partir de zéro. Si la valeur ‘i’ est hors limite (négative ou supérieure à la taille du tableau), la valeur retournée est ‘nil’.
|
347
|
+
|
348
|
+
On peut changer la valeur d’un élément de la table avec l’opérateur set:
|
349
|
+
|
350
|
+
set t.i = t.i + 1 ;
|
351
|
+
|
352
|
+
### Gestion des structures
|
353
|
+
Une structure est une sorte de tuple dont les champs sont nommés, ce qui permet d’y accéder plus simplement.
|
354
|
+
|
355
|
+
On doit d’abord définir les champs de la structure:
|
356
|
+
|
357
|
+
type AAA=[nameAAA scoreAAA] ;;
|
358
|
+
|
359
|
+
On peut alors créer une structure en écrivant:
|
360
|
+
|
361
|
+
[nameAAA : "foobar" scoreAAA : 123]
|
362
|
+
|
363
|
+
On pourra accéder aux champs de la manière suivante:
|
364
|
+
|
365
|
+
Secholn s.nameAAA ;
|
366
|
+
|
367
|
+
On peut changer la valeur d’un élément de la structure par l’opérateur set:
|
368
|
+
|
369
|
+
set s.scoreAAA = 1 + s.scoreAAA ;
|
370
|
+
|
371
|
+
|
372
|
+
### Gestion des types somme
|
373
|
+
Les types somme sont l’équivalent du ‘union’ du langage C. On peut l’utiliser pour implémenter les automates, ou certains arbres d’évaluation.
|
374
|
+
|
375
|
+
On définit par exemple les différents états des noeuds d’un arbre:
|
376
|
+
|
377
|
+
type MySum= Zero | Const _ | Add _ | Mul _ ;;
|
378
|
+
|
379
|
+
Le caractère ‘undescore’ indique qu’un paramètre est associé au type somme.
|
380
|
+
|
381
|
+
fun eval z=
|
382
|
+
match z with
|
383
|
+
( Zero -> 0)
|
384
|
+
|( Const a -> a)
|
385
|
+
|( Add [x y] -> (eval x)+(eval y))
|
386
|
+
|( Mul [x y] -> (eval x)*(eval y)) ;;
|
387
|
+
|
388
|
+
On crée alors l’arbre de l’expression `1 + (2 * 3)` de la manière suivante:
|
389
|
+
|
390
|
+
Add [ Const 1 Mul [ Const 2 Const 3]]
|
391
|
+
|
392
|
+
### Manipulation de fonctions
|
393
|
+
Le langage permet la manipulation de fonctions ; pour obtenir une sorte de _pointeur_ vers une fonction, on utilise l’opérateur _#_. On utilise alors l’opérateur « call » pour appeler une fonction à partir de son pointeur.
|
394
|
+
|
395
|
+
fun compare x y= x-y ;;
|
396
|
+
|
397
|
+
fun main =
|
398
|
+
compare 1 2 ;
|
399
|
+
let #compare -> f in
|
400
|
+
Iecholn call f [1 2] ;; //call: fun[ fun u0 u1 u0]u1
|
401
|
+
|
402
|
+
On peut fixer le dernier argument d’une fonction et obtenir ainsi une fonction avec un argument de moins.
|
403
|
+
|
404
|
+
fun main=
|
405
|
+
let #compare -> f in
|
406
|
+
let fixarg2 f 2 -> g in
|
407
|
+
Iecholn call g [1] ;;
|
408
|
+
|
409
|
+
Dans cet exemple, la fonction g est la fonction de comparaison avec l’entier ‘2’. On utilise l’opérateur fixargn, avec n=1, 2, 3, ...
|
410
|
+
|
411
|
+
|
412
|
+
## Exemples simples
|
413
|
+
### Génération d’une liste d’entiers aléatoires
|
414
|
+
|
415
|
+
On suppose l’existence d’une fonction ‘rand’ qui retourne un nombre aléatoire sur 16 bits.
|
416
|
+
|
417
|
+
fun mkrandomlist n=
|
418
|
+
if n > 0 then rand ::mkrandomlist n-1 ;;
|
419
|
+
|
420
|
+
### Tri par insertion d’une liste d’entiers
|
421
|
+
|
422
|
+
fun insert x l=
|
423
|
+
if l==nil then x::nil
|
424
|
+
else if (x-hd l )>0 then (hd l)::insert x tl l
|
425
|
+
else x::l;;
|
426
|
+
|
427
|
+
fun sort l= if l!=nil then insert hd l sort tl l;;
|
428
|
+
|
429
|
+
|
430
|
+
|
431
|
+
## Findings
|
432
|
+
|
433
|
+
Random notes of stuff I came accross while developing
|
434
|
+
|
435
|
+
### Leds
|
436
|
+
Thank god it's RGB: Led 0 - 4, Color RGB
|
437
|
+
|
438
|
+
```
|
439
|
+
led 0 0x000000; //black
|
440
|
+
led 0 0x0000FF; //blue
|
441
|
+
led 0 0x00FF00; //green
|
442
|
+
led 0 0xFF0000; //red
|
443
|
+
led 0 0xFFFF00; //yellow
|
444
|
+
led 0 0xFF00FF; //lila
|
445
|
+
led 0 0x00FFFF; //cyan
|
446
|
+
led 0 0xFFFFFF; //white
|
447
|
+
```
|
448
|
+
|
449
|
+
### Ears
|
450
|
+
|
451
|
+
### Custom functions
|
452
|
+
|
453
|
+
webmac // string to list of hex chars e.g.
|
454
|
+
|
455
|
+
### Main
|
456
|
+
|
457
|
+
`proto main 0;;` needs to be declared on top
|
458
|
+
|
459
|
+
Minimal func:
|
460
|
+
```
|
461
|
+
fun main=
|
462
|
+
confInit;
|
463
|
+
wifiInit 0;
|
464
|
+
loopcb #loop; // 20 p. second
|
465
|
+
|
466
|
+
netstart;
|
467
|
+
srand time_ms;
|
468
|
+
0
|
469
|
+
;;
|
470
|
+
```
|
471
|
+
|
472
|
+
### Metal Examples
|
473
|
+
Example:
|
474
|
+
|
475
|
+
```
|
476
|
+
type MySum= Zero | Const _ | Add _ | Mul _ ;;
|
477
|
+
|
478
|
+
fun eval z=
|
479
|
+
match z with
|
480
|
+
( Zero -> 0)
|
481
|
+
|( Const a -> a)
|
482
|
+
|( Add [x y] -> (eval x)+(eval y))
|
483
|
+
|( Mul [x y] -> (eval x)*(eval y)) ;;
|
484
|
+
|
485
|
+
Iecholn eval Add [Const 1 Mul [Const 2 Const 3]]; // -> 1 + 2 * 3 -> 7
|
486
|
+
```
|
487
|
+
|
488
|
+
See test for more.
|
@@ -0,0 +1,159 @@
|
|
1
|
+
// ------------- IP
|
2
|
+
|
3
|
+
fun strputchk s i w=
|
4
|
+
strset s i ~(w>>8);
|
5
|
+
strset s i+1 ~w;
|
6
|
+
0;;
|
7
|
+
|
8
|
+
// ------------- DEBUG
|
9
|
+
fun MACecho src i0 ln=
|
10
|
+
for i=0;i<6 do (Secho ctoh strget src i0+i; Secho "."); if ln then Secholn "";
|
11
|
+
src;;
|
12
|
+
|
13
|
+
fun SEQecho src i0 ln=
|
14
|
+
for i=0;i<4 do (Secho ctoh strget src i0+i; Secho "."); if ln then Secholn "";
|
15
|
+
src;;
|
16
|
+
|
17
|
+
fun IPecho src i0 ln=
|
18
|
+
for i=0;i<4 do (Iecho strget src i0+i; Secho ".");if ln then Secholn "";
|
19
|
+
src;;
|
20
|
+
|
21
|
+
fun itoh4 i = strcatlist (ctoh i>>24)::(ctoh i>>16)::(ctoh i>>8)::(ctoh i)::nil;;
|
22
|
+
|
23
|
+
fun dump s=
|
24
|
+
for i0=0;i0<strlen s;i0+16 do
|
25
|
+
(
|
26
|
+
//Secho itoh4 i0;
|
27
|
+
Secho " ";
|
28
|
+
for i=0;i<16 do let strget s i0+i -> c in
|
29
|
+
(
|
30
|
+
Secho if c==nil then " " else ctoh c;
|
31
|
+
Secho " "
|
32
|
+
);
|
33
|
+
Secho " ";
|
34
|
+
for i=0;i<16 do let strget s i0+i -> c in
|
35
|
+
(
|
36
|
+
Secho if c==nil then " " else if c<32 then "." else ctoa c
|
37
|
+
);
|
38
|
+
Secholn ""
|
39
|
+
);
|
40
|
+
s;;
|
41
|
+
|
42
|
+
fun dumpscan l0=
|
43
|
+
Secholn "## DUMPSCAN >>>>";
|
44
|
+
for l=l0;l!=nil;tl l do
|
45
|
+
let hd l->[ssid mac bssid rssi channel rateset encryption] in
|
46
|
+
(
|
47
|
+
Secho "## SCAN "; Secholn ssid;
|
48
|
+
Secho "mac:"; MACecho mac 0 1;
|
49
|
+
Secho "bssid:"; MACecho bssid 0 1;
|
50
|
+
Secho "rssi:"; Iecholn rssi;
|
51
|
+
Secho "channel:"; Iecholn channel;
|
52
|
+
Secho "rateset:"; Iecholn rateset;
|
53
|
+
Secho "encryption:"; Iecholn encryption
|
54
|
+
);
|
55
|
+
l0;;
|
56
|
+
|
57
|
+
// ------------- ARP
|
58
|
+
const ARPREQ=1;;
|
59
|
+
const ARPANS=2;;
|
60
|
+
|
61
|
+
var netip="\192\168\1\117";;
|
62
|
+
var netmask="\255\255\255\0";;
|
63
|
+
var netgateway="\192\168\1\1";;
|
64
|
+
var netdns="\192\168\1\1";;
|
65
|
+
|
66
|
+
var mymac;;
|
67
|
+
|
68
|
+
var macbroadcast="\$ff\$ff\$ff\$ff\$ff\$ff";;
|
69
|
+
var ipbroadcast="\$ff\$ff\$ff\$ff";;
|
70
|
+
|
71
|
+
var netip_empty="\0\0\0\0";;
|
72
|
+
|
73
|
+
var larp;;
|
74
|
+
var larpreq;;
|
75
|
+
|
76
|
+
fun mkarp op ipsrc macdst ipdst=
|
77
|
+
strcatlist
|
78
|
+
"\$aa\$aa\$03\$00\$00\$00\$08\$06\$00\$01\$08\$00\$06\$04\$00"::(ctoa op)::
|
79
|
+
mymac::
|
80
|
+
netip::
|
81
|
+
macdst::
|
82
|
+
ipdst
|
83
|
+
::nil;;
|
84
|
+
|
85
|
+
fun sendarp ip=
|
86
|
+
netSend (mkarp ARPREQ netip macbroadcast ip) 0 nil macbroadcast 0 1;;
|
87
|
+
|
88
|
+
|
89
|
+
fun filterarpip l src =
|
90
|
+
if l!=nil then let hd l->[ip _ _] in if !vstrcmp src 8+14 ip 0 4 then filterarpip tl l src
|
91
|
+
else (hd l)::filterarpip tl l src;;
|
92
|
+
|
93
|
+
fun checkarp l src=
|
94
|
+
if l!=nil then let hd l->[ip _ cb] in
|
95
|
+
(
|
96
|
+
if !vstrcmp src 8+14 ip 0 4 then
|
97
|
+
let strsub src 8+8 6 -> mac in
|
98
|
+
(
|
99
|
+
//Secho "found MAC target : "; MACecho mac 0 1;
|
100
|
+
set larp=[ip mac]::larp;
|
101
|
+
call cb [mac]
|
102
|
+
);
|
103
|
+
checkarp tl l src
|
104
|
+
);;
|
105
|
+
|
106
|
+
fun cbnetarp src mac=
|
107
|
+
Secho "<a";
|
108
|
+
let strget src 8+7-> op in
|
109
|
+
if op==1 then // req
|
110
|
+
(
|
111
|
+
// Secho "ask ";MACecho src 16+10 1; IPecho src 16+16 1;
|
112
|
+
if !vstrcmp src 32 netip 0 4 then
|
113
|
+
netSend (mkarp ARPANS netip strsub src 16 6 strsub src 22 4) 0 nil mac 0 1;
|
114
|
+
nil
|
115
|
+
)
|
116
|
+
else if op==2 then
|
117
|
+
let larpreq->l in
|
118
|
+
(
|
119
|
+
set larpreq=filterarpip larpreq src;
|
120
|
+
checkarp l src
|
121
|
+
);;
|
122
|
+
|
123
|
+
fun subnet_ ip i=
|
124
|
+
if i<0 then 1
|
125
|
+
else if ((strget ip i)^(strget netip i))&(strget netmask i) then 0
|
126
|
+
else subnet_ ip i-1;;
|
127
|
+
|
128
|
+
fun subnet ip=
|
129
|
+
Secho "test subnet ";
|
130
|
+
IPecho ip 0 1;
|
131
|
+
Iecholn subnet_ ip 3;;
|
132
|
+
|
133
|
+
|
134
|
+
fun arpreq ip cb=
|
135
|
+
let IPecho (if subnet ip then ip else netgateway) 0 1 -> ip in
|
136
|
+
let listswitchstr larp ip -> mac in
|
137
|
+
if mac!=nil then call cb [mac]
|
138
|
+
else
|
139
|
+
(
|
140
|
+
sendarp ip;
|
141
|
+
set larpreq=[ip time cb]::larpreq; // ### attention à la taille de la liste
|
142
|
+
0
|
143
|
+
);;
|
144
|
+
|
145
|
+
fun filterarp l dt =
|
146
|
+
if l!=nil then let hd l->[ip t _] in if (time-t)>dt then filterarp tl l dt
|
147
|
+
else
|
148
|
+
(
|
149
|
+
sendarp ip;
|
150
|
+
(hd l)::filterarp tl l dt
|
151
|
+
);;
|
152
|
+
|
153
|
+
fun arptime =
|
154
|
+
set larpreq=filterarp larpreq 10;;
|
155
|
+
|
156
|
+
fun resetarp=
|
157
|
+
set larp=nil;
|
158
|
+
set larpreq=nil;
|
159
|
+
0;;
|