Skip to content

Commit 4e5d525

Browse files
fix(sustainabot): parse-blocking OCaml-isms and HANDLE-keyword name (Refs #148) (#206)
## Summary Two hand-port corrections after re-validating sustainabot's ReScript→AffineScript files against the live `affinescript check`: 1. **OCaml-style float operators** `/.`, `*.`, `+.`, `-.` → AffineScript `/`, `*`, `+`, `-`. AffineScript uses unified arithmetic operators for Int and Float (see `examples/lessons/01_hello.affine`: `subtotal * 0.08`), so the OCaml separation was a hand-port artefact. Affected: `GitHubApp.affine`, `Oikos.affine`, `Report.affine`. 2. **`handle` is a contextual keyword** in AffineScript (HANDLE token, used in `handle body { handlers }` effect expressions), so it cannot be a function name. Renamed `Router.affine`'s `pub fn handle(...)` → `pub fn dispatch(...)`. The function dispatches a request to its matching route handler — the rename is also more accurate. ## Gate This PR's parse-time fix is fully effective only once the four parser PRs gated on the same issue have merged: - hyperpolymath/affinescript#370 (trailing-comma in fn params + expr lists + effect-annotated lambda) - hyperpolymath/affinescript#371 (fn-type with effect arrow in type position) - hyperpolymath/affinescript#372 (builtin/lowercase qualified paths + TOTAL field name) - hyperpolymath/affinescript#373 (underscore-prefix idents `_key`/`_unused`) - hyperpolymath/affinescript#376 (record-update spread at start) ## Test plan - [x] After landing the 5 affinescript PRs + this PR: `affinescript check` on all 13 sustainabot `.affine` files reaches at least Resolution (no parse errors). 12 hit `Resolve.UndefinedModule` (stdlib not loaded by the check), 1 (`tea/Sub.affine`) hit it from the start. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent 8a5f28f commit 4e5d525

4 files changed

Lines changed: 9 additions & 9 deletions

File tree

bots/sustainabot/bot-integration/src/GitHubApp.affine

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ pub fn generate_jwt(
6161
app_id: ref String,
6262
private_key_pem: ref String,
6363
) -{IO}-> Result<String, String> {
64-
let now_seconds = Time::now_millis() /. 1000.0;
64+
let now_seconds = Time::now_millis() / 1000.0;
6565

6666
let header = json::encode_object([
6767
("alg", json::encode_string("RS256")),
@@ -71,8 +71,8 @@ pub fn generate_jwt(
7171

7272
let payload = json::encode_object([
7373
("iss", json::encode_string(app_id)),
74-
("iat", json::encode_float(now_seconds -. 60.0)),
75-
("exp", json::encode_float(now_seconds +. 600.0)),
74+
("iat", json::encode_float(now_seconds - 60.0)),
75+
("exp", json::encode_float(now_seconds + 600.0)),
7676
]);
7777
let payload_b64 = base64_url_encode_string(json::stringify(payload));
7878

@@ -111,7 +111,7 @@ pub fn get_installation_token(
111111

112112
match cache_get(cache_key) {
113113
Some(cached) => {
114-
if cached.expiresAt > Time::now_millis() +. 60000.0 {
114+
if cached.expiresAt > Time::now_millis() + 60000.0 {
115115
Ok(cached)
116116
} else {
117117
fetch_installation_token(jwt, cache_key)

bots/sustainabot/bot-integration/src/Oikos.affine

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -194,9 +194,9 @@ pub fn update(msg: Msg, model: Model) -{IO}-> (Model, Cmd::T<Msg>) {
194194

195195
Tick => {
196196
let now = Time::now_millis();
197-
let one_hour = 60.0 *. 60.0 *. 1000.0;
197+
let one_hour = 60.0 * 60.0 * 1000.0;
198198
let pending = filter(model.pendingAnalyses, fn(a) -> Bool {
199-
now -. a.createdAt < one_hour
199+
now - a.createdAt < one_hour
200200
});
201201
(Model #{ ..model, pendingAnalyses: pending }, Cmd::none())
202202
},

bots/sustainabot/bot-integration/src/Report.affine

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@ pub fn generate_pr_comment(analysis: ref AnalysisResult, mode: ref BotMode) -> S
9191
let top_recs = Array::slice(analysis.recommendations, 0, max_recs);
9292

9393
let rec_lines = map(top_recs, fn(r) -> String {
94-
let confidence = Float::to_int(r.confidence *. 100.0);
94+
let confidence = Float::to_int(r.confidence * 100.0);
9595
"- **" ++ r.action ++ "** (" ++ Int::to_string(confidence)
9696
++ "% confidence): " ++ r.reason ++ "\n"
9797
});

bots/sustainabot/bot-integration/src/Router.affine

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -125,11 +125,11 @@ pub fn not_found(router: Router, handler: Handler) -> Router {
125125
Router #{ ..router, notFoundHandler: Some(handler) }
126126
}
127127

128-
// `handle` walks routes to find a method+path match and invokes its
128+
// `dispatch` walks routes to find a method+path match and invokes its
129129
// handler under the middleware chain. The mechanical migrator must
130130
// re-express this once the canonical Http::Request shape and
131131
// Array::iter / Array::fold_right externs are bound.
132-
pub fn handle(router: ref Router, req: Http::Request) -{IO}-> Http::Response {
132+
pub fn dispatch(router: ref Router, req: Http::Request) -{IO}-> Http::Response {
133133
// TODO(mechanical-migrator): re-implement against canonical Http::Request
134134
// shape. Stubbed to a 501 so the file parses.
135135
Http::not_implemented(req)

0 commit comments

Comments
 (0)