BobShit pour BobPhone / NoteOS
Guide court pour écrire, uploader et exécuter des apps .shit
(runtime C v0.1.1) sur le serveur Bob.
1. Introduction au langage
BobShit est un langage interprété human-first : fichiers .shit,
keywords bilingues FR/EN, et un mode soft (défaut) qui pardonne
parenthèses / end / virgules manquants avec un warning sur stderr.
# hello.shit
say "salut, c'est BobShit"
name = "Bob"
say "moi c'est", name
Mots-clés utiles
| EN | FR | Rôle |
|---|---|---|
say / print | affiche | sortie stdout |
if / elif / else | si / sinon_si / sinon | conditions |
for … in … to | pour … dans … jusqua | boucles |
fun / fn / def | fonction | fonctions |
input | — | lit stdin (prompt optionnel) |
end | fin | fin de bloc |
Soft vs strict -s
- Soft (défaut) — intention claire → on exécute.
10/0→0, var inconnue →nil, junk ignoré + warning. - Strict —
bobshit -s fichier.shit: la première erreur arrête tout (exit 1). Sur l’API BobPhone :{"strict": true}.
2. Soumettre un script via BobPhone
A) Upload store (app .shit)
Sur BobPhone, publie une app avec un fichier app.shit
(multipart file / js / app, extension .shit).
Le serveur génère un wrapper JS + page qui appelle le runtime.
POST https://bob.xem.yt/bobphone/api/pk/publish
Content-Type: multipart/form-data
name=MaShitApp
author=toi
file=@app.shit
Puis exécution par id :
POST https://bob.xem.yt/bobphone/api/pk/run
{"id": "ma-shit-app"}
Ou snippet inline :
POST https://bob.xem.yt/bobphone/api/pk/run
{"code": "say \"yo\"", "strict": false}
B) Endpoint public runtime /api/bobshit/run
Runtime serveur dédié (Flask · port 8350, exposé via Caddy).
Alias : /bobshit/run. Doc BobPhone :
/bobphone/docs/bobshit/
curl -X POST https://bob.xem.yt/api/bobshit/run \
-H 'Content-Type: application/json' \
-d '{"script":"say \"hello bobshit\"","args":[],"timeout":5}'
// réponse
{
"ok": true,
"output": "hello bobshit\n",
"errors": "",
"stdout": "hello bobshit\n",
"stderr": "",
"exit_code": 0
}
- Body :
script(oucode/shit),argsoptionnel,timeoutoptionnel (défaut 5s, max 10s) output/errors= contrat docs ;stdout/stderr= alias historiques- Health :
GET https://bob.xem.yt/api/bobshit/health→{"ok":true,"version":"bobshit 0.1.1"}
3. Exemple de script commenté
# demo.shit — say / if / for / fun / input
# input lit une ligne stdin (en sandbox serveur → souvent vide / EOF)
name = input("ton nom? ")
if name == nil or name == "" then
name = "Bob"
end
say "salut", name
# fun = fonction (alias: fn / def / fonction)
fun double(n)
return n * 2
end
# for range
for i in 1 to 5
if i % 2 == 0 then
say i, "→", double(i), "(pair)"
else
say i, "→", double(i), "(impair)"
end
end
# FR aussi OK dans le même fichier
fonction greet qui
affiche "yo", qui
fin
greet(name)
Test rapide :
curl -X POST https://bob.xem.yt/bobshit/run \
-H 'Content-Type: application/json' \
-d '{"code":"fun double(n)\n return n*2\nend\nfor i in 1 to 3\n say double(i)\nend"}'
4. Intégrer BobShit dans une app NoteOS
NoteOS tourne dans le navigateur (canvas desktop). Le code BobShit
s’exécute côté serveur — depuis le sandbox, tu appelles l’API
avec NoteNet.fetchJSON (ou fetch).
// apps/user/mon-bobshit.js — NoteOS
NoteApps.register({
id: "mon-bobshit",
name: "Mon BobShit",
glyph: "💩",
launch: function (kernel) {
var lines = ["…"];
NoteNet.fetchJSON("https://bob.xem.yt/bobshit/run", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
code: 'say "hello depuis NoteOS"\nfor i in 1 to 3\n say i\nend'
})
}).then(function (j) {
var text = (j && (j.output || j.stdout)) || (j && j.error) || "(vide)";
lines = String(text).replace(/\r/g, "").split("\n");
}).catch(function (e) {
lines = [String(e && e.message || e)];
});
return NoteWM.open({
id: "mon-bobshit",
title: "Mon BobShit",
w: 420, h: 280,
renderContent: function (ctx, box) {
NoteGfx.text(ctx, "BobShit output", box.x + 16, box.y + 28);
var y = box.y + 56;
for (var i = 0; i < lines.length; i++) {
NoteGfx.text(ctx, lines[i].slice(0, 48), box.x + 16, y);
y += 18;
}
}
});
}
});
.shit via
/bobphone/api/pk/publish, puis
POST /bobphone/api/pk/run avec {"id":"…"}
(même pattern que l’app démo hello-bobshit).
Docs NoteOS : bob.xem.yt/noteos/devdocs/
5. Limites et sandboxing
Le runtime C n’est pas un OS : pas de FS arbitraire, pas de réseau depuis le script. L’API enveloppe le binaire dans un process éphémère.
| Limite | Valeur | Où |
|---|---|---|
| Timeout exécution | 5 s (/bobshit/run) · 3 s (BobPhone) | API |
| Taille source max | 200 000 octets | API |
| Sortie max (stdout/stderr) | 64 000 octets | API |
| Rate limit BobPhone | ~40 runs / min / client | BobPhone |
| Profondeur d’appels | 256 frames | runtime C |
| Itérations de boucle | 1 000 000 | runtime C |
HTML / <script> / PHP | refusés à l’upload | sanitize |
| Env process | PATH minimal, HOME=/tmp, cwd /tmp | sandbox |
exec,
pas de sockets, pas d’accès disque hors ce que le binaire lit en lecture
(fichier temp). Boucles infinies → timeout. input() en HTTP
n’a pas de vrai stdin interactif — prévois une valeur par défaut.
Pas de scan trop large (find/grep sur tout le disque) pour tester :
ça lag le serveur — timeout + sandbox suffisent.
6. Liens
| Quoi | URL |
|---|---|
| Repo upstream | github.com/Riric65/bobshit |
| Runtime API (public) | POST https://bob.xem.yt/api/bobshit/run |
| Site / playground | bob.xem.yt/bobshit/ |
| Docs BobPhone | bob.xem.yt/bobphone/docs/bobshit/ |
| Ces docs | bob.xem.yt/bobshit/docs/ |
| BobPhone run | POST /bobphone/api/pk/run |
| NoteOS devdocs | bob.xem.yt/noteos/devdocs/ |
# runtime local (depuis le repo)
git clone https://github.com/Riric65/bobshit.git
cd bobshit/lang && make
./bobshit examples/hello.shit
./bobshit -s programme.shit # strict