nabaztag_hack_kit 0.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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;;
|