The piece between an editor and everything else. One long-lived Session, the program it belongs to launched and owned by the same process, and a socket that takes forms and installs them. What it adds over flan reload is that the session persists - a defvar added by one evaluation is part of what the next is checked against - and that it owns the build, which is what makes its layout rules describe the process actually running rather than a guess about it. The protocol is s-expressions rather than bencode, and I changed my mind about that. The case for nREPL was reusing a designed op set and not re-litigating session identity, but with the client ours too there is no CIDER to be compatible with, its eval is string-in/string-out with no slot for which form from which file, and Emacs already has read and prin1. So: one sexp per message, length framed because the payload contains newlines. No parsing code on the editor side, and on this side the parser is the language's own reader, where :op is already a keyword and Flan source is already a string literal. An nREPL front end can sit on the same Session later; it should not gate the editor. Two silent failures the daemon refuses to have. The agent socket is chosen by the daemon and forced through FLAN_AGENT_SOCKET before spawning, because a program's source has to name some path and a daemon that guessed would compile, build and deliver a module to nobody. And delivery is checked: agent/start returning 0 means a socket was bound, not that anyone connected, so a failed connect or a reply that is not ok becomes an error the editor sees. It waits for the program to bind before accepting an evaluation, since one arriving first fails for a reason that reads like a compiler bug, and it accepts with a timeout so a program that has exited takes the daemon with it instead of leaving an editor waiting on a socket nobody serves.
20 lines
982 B
Plaintext
20 lines
982 B
Plaintext
(tests
|
|
(names test_flan test_acceptance test_reload test_agent test_session test_dev)
|
|
(libraries flan unix)
|
|
; The acceptance programs are part of the test corpus: if the reader, the
|
|
; parser or the checker regresses on them we want to know here, not at the CLI.
|
|
(deps
|
|
(file %{workspace_root}/calc-me.flan)
|
|
(file %{workspace_root}/sand.flan)
|
|
; The sim package and the raylib bindings, because the headless sand case and
|
|
; the FFI case import them and an import reads the directory at build time.
|
|
(glob_files %{workspace_root}/sand-sim/*)
|
|
(glob_files %{workspace_root}/vendor/raylib/*)
|
|
; The dev agent package: its Flan declarations and the C that implements them.
|
|
(glob_files %{workspace_root}/vendor/agent/*)
|
|
(glob_files programs/*.flan)
|
|
; The reload primitive's host: a C main that dlopens what Build.shared made.
|
|
(file reload_host.c)
|
|
; test_dev runs the compiler itself: flan dev launches and owns a program.
|
|
(file %{workspace_root}/bin/main.exe)))
|