diff --git a/AGENTS.md b/AGENTS.md index 04b1c29..5e3d96b 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -171,8 +171,9 @@ Design specs and plans are not kept in this repo; they live under - `Kind` is a keyword: no type of that name. - `bend x.bend` runs main after checking. To check only, `bend --check-only` (or `bend x.bend -o t.js`). - A foreign effect `def a.b(..) -> IO(T)` with `import "./x.c"` and - `import "./x.js"` bodies is `a_b_run` + `io_eff(CID_A_B, ..)` in C and - `function a_b(..)` in JS (src/lsp/checker/exec.*). + `import "./x.js"` bodies registers itself on both lanes by its def name: + `io_eff(CID(a.b), a_b_run, 0)` in C and `io_eff(CID(a.b), a_b)` in JS + (bend 2.0.28; `bend guide effects`, src/lsp/checker/exec.*). - A server's stdin and stdout may be sockets (node spawns children that way), and no path opens a socket: wrap descriptors 0 and 1 (src/lsp/transport/fd.c), never `File.open("/dev/stdin")`. Test a server spawned from node diff --git a/README.md b/README.md index 5572a2c..235f69b 100644 --- a/README.md +++ b/README.md @@ -22,7 +22,7 @@ bolt needs a Bend 2, and any Bend 2 will do: the one one built from source. You do not need ez or nix. Building bolt needs clang 14+ as well, since bolt is one native binary. -**Bend version.** bolt is built and tested with Bend 2.0.27, the version +**Bend version.** bolt is built and tested with Bend 2.0.28, the version `flake.lock` pins. `bolt check` and `bolt lsp` run the `bend` on your PATH, so that `bend` is the one to keep at the tested version. diff --git a/ez.lock.toml b/ez.lock.toml index 4ceafbe..2af1462 100644 --- a/ez.lock.toml +++ b/ez.lock.toml @@ -17,29 +17,6 @@ LICENSE = "309f5aae946e4db157750e002fb179a74ed0fe27fce09a7be68a6977b14f205f" "src/args.bend" = "cb408b31dc02aa0525dc07f7a3119798f6d1d96f244361dc941797bb90653b24" "src/check.bend" = "ad47c820def9bb1b77ea52b8097e4a62a7f1bbe6aac3c753ddf089c29f9c012a" "src/cli.bend" = "c8b1c75699e77ca233aac1125cff8565246ae230aee25752c52f05e608f41362" -[packages.0x103d0af04de36ab98b311e537366ec67] -[packages.0x103d0af04de36ab98b311e537366ec67.source] -kind = "git" -url = "https://github.com/Emerging-Patterns/snap" -rev = "ced24e103db518e37f565c577ef312602c217cf5" -entry = "main.bend" -root = "." -narHash = "sha256-dEO94GFkcgssyzOqz4A5VveB3npPq4/zpDpI+EvqnvI=" -tag = "v1.0.0" -[packages.0x103d0af04de36ab98b311e537366ec67.files] -LICENSE = "309f5aae946e4db157750e002fb179a74ed0fe27fce09a7be68a6977b14f205f" -"main.bend" = "68a5a2f373983f652dc260683c57261930bbe1fba3b89f05973066697a4e8d43" -"src/answer.bend" = "cfeb97ada7d0708c49abae1164af3e988a32c7fbdfb6591c61ce148b46d0738d" -"src/argv.bend" = "6a3a6e8669fb5dab77f843fdd778402593d898c52a0dcd8738b689d95ff35856" -"src/effect.bend" = "d0db20f66f1d55128b865d369a6bccfe8353dc05ec7f8b1b9576317ecaba8d8d" -"src/exec.c" = "76f3490075a1640af38dc0422f9e9ebe849f60ad6e9b001f97313dbdaa03880d" -"src/exec.js" = "0a4f99c247fd0e8346b6f541ceeb67e477e450332c5c1942a082280af75bc986" -"src/file.bend" = "261a8f461bf0203e3e33bb3dfe0e21f88b1be1ffad8d9bb088827dcd3904c8f8" -"src/par.bend" = "c5c316830a377d4f6b5390e12e0dd886f00351d882e6e8803b3514491bf5964e" -"src/par.c" = "4843bf8fa1e76c69cf33fa769fa4b8e9f22df69aff990cb5a3de08ecfe9034bc" -"src/par.js" = "791ced8192ca1d7238919629db661bfd3799db24d9483b397052e054f12d4225" -"src/start.c" = "7306425871c0d4b859c6809f34b83ae7947b2065781fd2a8fe8ac8806a77391b" -"src/start.js" = "d45eca4a2782e3fdbc1b7abc798fc3f131dc87dde34ab9cfa6dd917fff2ea04c" [packages.0x81c67699424929b5c44cd8577e18117f] [packages.0x81c67699424929b5c44cd8577e18117f.source] kind = "git" @@ -58,3 +35,26 @@ LICENSE = "309f5aae946e4db157750e002fb179a74ed0fe27fce09a7be68a6977b14f205f" "src/print.bend" = "32a92e32f9e58cb028c59209c6aeb2b408f0510d199b31cff172c09bbb68fd6a" "src/pull.bend" = "c682f4f968f78b10bf39351130aa48fc9ade47c01f5bb2b4b74a061df7afb141" "src/value.bend" = "e4fe80f757464b9c35e298b921c1a6562e4e9251c779774b0d8873f46129e8e7" +[packages.0xabe575924687afad4cee1a2c1194d639] +[packages.0xabe575924687afad4cee1a2c1194d639.source] +kind = "git" +url = "https://github.com/Emerging-Patterns/snap" +rev = "fcabc81830c9e21d86d4968810285b287da49c12" +entry = "main.bend" +root = "." +narHash = "sha256-uKIWgjm98bQAYaNiMD/UOfwg55LWcAj2oC9AzSQuNBA=" +tag = "v1.1.0" +[packages.0xabe575924687afad4cee1a2c1194d639.files] +LICENSE = "309f5aae946e4db157750e002fb179a74ed0fe27fce09a7be68a6977b14f205f" +"main.bend" = "68a5a2f373983f652dc260683c57261930bbe1fba3b89f05973066697a4e8d43" +"src/answer.bend" = "cfeb97ada7d0708c49abae1164af3e988a32c7fbdfb6591c61ce148b46d0738d" +"src/argv.bend" = "6a3a6e8669fb5dab77f843fdd778402593d898c52a0dcd8738b689d95ff35856" +"src/effect.bend" = "d0db20f66f1d55128b865d369a6bccfe8353dc05ec7f8b1b9576317ecaba8d8d" +"src/exec.c" = "1478ed5e6315c40f220bfa717d1d6a32103446641e713593c5f6557f484c607e" +"src/exec.js" = "70268064b34529d651b670fb180027703d15ec494f6ea9dd7dcfc878dbb30a74" +"src/file.bend" = "261a8f461bf0203e3e33bb3dfe0e21f88b1be1ffad8d9bb088827dcd3904c8f8" +"src/par.bend" = "c5c316830a377d4f6b5390e12e0dd886f00351d882e6e8803b3514491bf5964e" +"src/par.c" = "7edbca9e791b0d202e78543e7863b8d74d38e79b7f1fcb645dd15fbdb6ffcde0" +"src/par.js" = "33ff4eca5d524264d28da36a9caf0a8252036efd44b92358a4c07daeb3ba69c9" +"src/start.c" = "1bec197312b644549c176463e9476986301b28f6e01e5c34ea508f396cda1aec" +"src/start.js" = "8ea49fe5324a2608342b4629b29d841a81d72ee8006869ac06971a0fb1aed53a" diff --git a/ez.toml b/ez.toml index fb389ab..d344188 100644 --- a/ez.toml +++ b/ez.toml @@ -1,7 +1,7 @@ [package] name = "bolt" entry = "main.bend" - +[deps] [deps.ezjson] hash = "0x81c67699424929b5c44cd8577e18117f" git = "https://github.com/Emerging-Patterns/ezjson" @@ -10,16 +10,14 @@ tag = "v1.1.0" root = "." narHash = "sha256-yHxl1aW4luf2bdPqOUcULhOEZLlcaTOWjTrPJys4CMI=" entry = "main.bend" - [deps.snap] -hash = "0x103d0af04de36ab98b311e537366ec67" +hash = "0xabe575924687afad4cee1a2c1194d639" git = "https://github.com/Emerging-Patterns/snap" -rev = "ced24e103db518e37f565c577ef312602c217cf5" -tag = "v1.0.0" +rev = "fcabc81830c9e21d86d4968810285b287da49c12" +tag = "v1.1.0" root = "." -narHash = "sha256-dEO94GFkcgssyzOqz4A5VveB3npPq4/zpDpI+EvqnvI=" +narHash = "sha256-uKIWgjm98bQAYaNiMD/UOfwg55LWcAj2oC9AzSQuNBA=" entry = "main.bend" - [deps.shake] hash = "0x085b03c84ca37125e38dddede7b91e55" git = "https://github.com/Emerging-Patterns/shake" diff --git a/flake.lock b/flake.lock index 55e5bef..6ac021f 100644 --- a/flake.lock +++ b/flake.lock @@ -7,11 +7,11 @@ ] }, "locked": { - "lastModified": 1790348040, - "narHash": "sha256-6oh+6jj7kyl4xJsmq4p3BtU/BUl2f2LlC/5kH081D1M=", + "lastModified": 1790359392, + "narHash": "sha256-z0Xwg46QesyRnlb7+sQue2GRq90v9M2XVaNVVSdd5Vs=", "owner": "bendlang", "repo": "bend", - "rev": "774ef644dccf9c3f8053f7276d8901ad23da006c", + "rev": "11c65a2572e16d0bfc2e83068b23ed8fb180ccc0", "type": "github" }, "original": { @@ -20,11 +20,28 @@ "type": "github" } }, + "bend_2": { + "inputs": { + "nixpkgs": "nixpkgs" + }, + "locked": { + "lastModified": 1790200275, + "narHash": "sha256-huYLnKbMUukFhFLypIXx/wLVU3EmgsUEe9l67mU6CDw=", + "owner": "bendlang", + "repo": "bend", + "rev": "d37909174ebd664338ae3194799a9e0899dedd51", + "type": "github" + }, + "original": { + "owner": "bendlang", + "repo": "bend", + "rev": "d37909174ebd664338ae3194799a9e0899dedd51", + "type": "github" + } + }, "ez": { "inputs": { - "bend": [ - "bend" - ], + "bend": "bend_2", "nixpkgs": [ "nixpkgs" ] @@ -44,6 +61,22 @@ } }, "nixpkgs": { + "locked": { + "lastModified": 1790185690, + "narHash": "sha256-xJ+X4hBtOcAFGBOe5nAMyMUeF9foJBmIOu3NjBqBycU=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "4975466d324710c576dc11ad614684e6bd8cad8e", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixos-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, + "nixpkgs_2": { "locked": { "lastModified": 1789546076, "narHash": "sha256-zVxLZiSnmaaPLwnhj7pwmqe3axBg/C6nG5JZsJMh2g4=", @@ -63,7 +96,7 @@ "inputs": { "bend": "bend", "ez": "ez", - "nixpkgs": "nixpkgs" + "nixpkgs": "nixpkgs_2" } } }, diff --git a/flake.nix b/flake.nix index ba0f6fd..7e320df 100644 --- a/flake.nix +++ b/flake.nix @@ -9,7 +9,9 @@ inputs.ez = { url = "github:Emerging-Patterns/ez"; inputs.nixpkgs.follows = "nixpkgs"; - inputs.bend.follows = "bend"; + # not `inputs.bend.follows = "bend"`: ez 1.2.0 does not build on bend + # 2.0.28, so ez (and `ez prove`) keep the bend ez 1.2.0 locks, 2.0.27 + inputs.bend.url = "github:bendlang/bend/d37909174ebd664338ae3194799a9e0899dedd51"; }; outputs = { self, nixpkgs, ... }@inputs: diff --git a/src/LAWS.bend b/src/LAWS.bend index 20fb79d..d0aec00 100644 --- a/src/LAWS.bend +++ b/src/LAWS.bend @@ -35,22 +35,22 @@ law set_level_none: # LAW: a setting of the name, first in file order, is the name's setting # BOLT-CFG-1 law set_level_first: - for sets: List<&2, Config.Set> + for sets: List<&2, Config.LevelSet> for +name: String for +nn: String for ll: Config.Level for h: {String.eq(nn, name) == True{} : Bool} - {Config.set_level(Config.Set{nn, ll} <> sets, name) == Some{ll} : Maybe<&2, Config.Level>} + {Config.set_level(Config.LevelSet{nn, ll} <> sets, name) == Some{ll} : Maybe<&2, Config.Level>} # LAW: a setting of another name is passed over # BOLT-CFG-1 law set_level_skip: - for +sets: List<&2, Config.Set> + for +sets: List<&2, Config.LevelSet> for +name: String for +nn: String for ll: Config.Level for h: {String.eq(nn, name) == False{} : Bool} - {Config.set_level(Config.Set{nn, ll} <> sets, name) == Config.set_level(sets, name) + {Config.set_level(Config.LevelSet{nn, ll} <> sets, name) == Config.set_level(sets, name) : Maybe<&2, Config.Level>} # LAW: a rule's own setting is its level, whatever its group says, an @@ -58,7 +58,7 @@ law set_level_skip: # BOLT-CFG-1 # BOLT-CFG-6 law level_own: - for +sets: List<&2, Config.Set> + for +sets: List<&2, Config.LevelSet> for +group: String for +rule: String for +l: Config.Level @@ -69,7 +69,7 @@ law level_own: # setting # BOLT-CFG-1 law level_group: - for +sets: List<&2, Config.Set> + for +sets: List<&2, Config.LevelSet> for +group: String for +rule: String for +l: Config.Level @@ -82,7 +82,7 @@ law level_group: # setting either, is at its group's default # BOLT-CFG-1 law level_default: - for +sets: List<&2, Config.Set> + for +sets: List<&2, Config.LevelSet> for +group: String for +rule: String for h_rule: {Config.set_level(sets, rule) == None{} : Maybe<&2, Config.Level>} @@ -153,7 +153,7 @@ law default_rest: # says (with one, level_own gives it that setting) # BOLT-CFG-6 law opt_in_off: - for +sets: List<&2, Config.Set> + for +sets: List<&2, Config.LevelSet> for +group: String for +rule: String for h_opt: {Config.opt_in(rule) == True{} : Bool} diff --git a/src/config.bend b/src/config.bend index 9032819..54670ae 100644 --- a/src/config.bend +++ b/src/config.bend @@ -29,12 +29,12 @@ type Level is Data: Error{} # a name (a group's or a rule's) at a level -type Set is Data: - Set{name: String, level: Level} +type LevelSet is Data: + LevelSet{name: String, level: Level} # the settings, in file order type Config is Data: - Config{sets: List<&2, Set>} + Config{sets: List<&2, LevelSet>} # no file: the defaults def none() -> Config: @@ -89,18 +89,18 @@ def first_str(toks: List<&2, Lex.Tok>) -> Maybe<&2, String>: first_str(rest) # a def's name and the string it returns, as a setting -def setting(name: Maybe<&2, String>, word: Maybe<&2, String>) -> List<&2, Set>: +def setting(name: Maybe<&2, String>, word: Maybe<&2, String>) -> List<&2, LevelSet>: match name word: case Some{n} Some{w}: - [Set{n, of_word(w)}] + [LevelSet{n, of_word(w)}] case a b: [] # every `def x(): "level"` of a tree -def sets(root: Tree.Node) -> List<&2, Set>: +def sets(root: Tree.Node) -> List<&2, LevelSet>: match root: case Tree.NCons{Tree.Stmt{Tree.SDef{}, kids, body}, rest}: - List.append(&2, Set, setting(Bind.declared(kids), first_str(Tree.leaves(body))), sets(rest)) + List.append(&2, LevelSet, setting(Bind.declared(kids), first_str(Tree.leaves(body))), sets(rest)) case Tree.NCons{h, rest}: sets(rest) case other: @@ -203,11 +203,11 @@ def nearest(rs: List<&2, Maybe<&2, String>>) -> Config: # ------ # the level a name is set to, when it is -def set_level(sets: List<&2, Set>, +name: String) -> Maybe<&2, Level>: +def set_level(sets: List<&2, LevelSet>, +name: String) -> Maybe<&2, Level>: match sets: case Nil{}: None{} - case Con{Set{+n, l}, rest}: + case Con{LevelSet{+n, l}, rest}: +more = set_level(rest, name) Bool.pick(Maybe<&2, Level>, String.eq(n, name), Some{l}, more) @@ -223,7 +223,7 @@ def opt_in(+rule: String) -> Bool: # the rule's own setting, else its group's, else the group's default; an # opt-in rule's own setting, else off -def level.of(+sets: List<&2, Set>, +group: String, +rule: String) -> Level: +def level.of(+sets: List<&2, LevelSet>, +group: String, +rule: String) -> Level: Maybe.default(&2, Level, set_level(sets, rule), Lazy.stop(Level, opt_in(rule), Off{}, _u => Maybe.default(&2, Level, set_level(sets, group), default(group)))) diff --git a/src/lsp/checker/exec.c b/src/lsp/checker/exec.c index 11a9648..db7c0f4 100644 --- a/src/lsp/checker/exec.c +++ b/src/lsp/checker/exec.c @@ -74,7 +74,7 @@ Term bendcheck_exec_run(Env e, Term* f, IoWork* w) { } static void __attribute__((constructor)) bendcheck_exec_use(void) { - io_eff(CID_BENDCHECK_EXEC, bendcheck_exec_run, 0); + io_eff(CID(bendcheck.exec), bendcheck_exec_run, 0); } // `bolt lsp` with no `--gpu` is `--gpu off`. The runtime chooses the device diff --git a/src/lsp/checker/exec.js b/src/lsp/checker/exec.js index 7509ab5..26b991b 100644 --- a/src/lsp/checker/exec.js +++ b/src/lsp/checker/exec.js @@ -9,3 +9,5 @@ function bendcheck_exec(path, flag) { const tag = r.status === 127 || (r.error && r.status === null && r.signal === null) ? "x" : r.signal ? "s" : "r"; return tag + (r.stdout ?? "") + (r.stderr ?? ""); } + +io_eff(CID(bendcheck.exec), bendcheck_exec); diff --git a/src/lsp/transport/fd.c b/src/lsp/transport/fd.c index 50e13ed..4d9ea6f 100644 --- a/src/lsp/transport/fd.c +++ b/src/lsp/transport/fd.c @@ -6,5 +6,5 @@ Term stdio_fd_run(Env e, Term* f, IoWork* w) { } static void __attribute__((constructor)) stdio_fd_use(void) { - io_eff(CID_STDIO_FD, stdio_fd_run, 0); + io_eff(CID(stdio.fd), stdio_fd_run, 0); } diff --git a/src/lsp/transport/fd.js b/src/lsp/transport/fd.js index 65d6c85..6f39fe1 100644 --- a/src/lsp/transport/fd.js +++ b/src/lsp/transport/fd.js @@ -2,3 +2,5 @@ function stdio_fd(n) { return n; } + +io_eff(CID(stdio.fd), stdio_fd); diff --git a/src/walk/cwd.c b/src/walk/cwd.c index dab0518..1cfb7a1 100644 --- a/src/walk/cwd.c +++ b/src/walk/cwd.c @@ -13,5 +13,5 @@ Term walkdir_cwd_run(Env e, Term* f, IoWork* w) { } static void __attribute__((constructor)) walkdir_cwd_use(void) { - io_eff(CID_WALKDIR_CWD, walkdir_cwd_run, 0); + io_eff(CID(walkdir.cwd), walkdir_cwd_run, 0); } diff --git a/src/walk/cwd.js b/src/walk/cwd.js index a914a20..218efe4 100644 --- a/src/walk/cwd.js +++ b/src/walk/cwd.js @@ -7,3 +7,5 @@ function walkdir_cwd() { return ""; } } + +io_eff(CID(walkdir.cwd), walkdir_cwd); diff --git a/src/walk/dir.c b/src/walk/dir.c index 2960492..b3fa8b4 100644 --- a/src/walk/dir.c +++ b/src/walk/dir.c @@ -59,5 +59,5 @@ Term walkdir_entries_run(Env e, Term* f, IoWork* w) { } static void __attribute__((constructor)) walkdir_entries_use(void) { - io_eff(CID_WALKDIR_ENTRIES, walkdir_entries_run, 0); + io_eff(CID(walkdir.entries), walkdir_entries_run, 0); } diff --git a/src/walk/dir.js b/src/walk/dir.js index 115bc32..d69956b 100644 --- a/src/walk/dir.js +++ b/src/walk/dir.js @@ -12,3 +12,5 @@ function walkdir_entries(dir) { } return entries.map((e) => e.name + (e.isDirectory() ? "/" : "") + "\n").join(""); } + +io_eff(CID(walkdir.entries), walkdir_entries); diff --git a/tests/bare.bend b/tests/bare.bend index f714e34..4608209 100644 --- a/tests/bare.bend +++ b/tests/bare.bend @@ -18,7 +18,7 @@ # it, and it is the slow one, because the compile it drives is a whole build of # bolt. import Base -import 0x103d0af04de36ab98b311e537366ec67/main.bend as Snap +import 0xabe575924687afad4cee1a2c1194d639/main.bend as Snap # `ok name` when the two strings are equal, `FAIL name` when they are not def eq_str(name: String, got: String, want: String) -> IO(Unit): @@ -32,9 +32,9 @@ def shake.hash() -> String: def ezjson.hash() -> String: "0x81c67699424929b5c44cd8577e18117f" -# the 0x name ez computed for snap v1.0.0 +# the 0x name ez computed for snap v1.1.0 def snap.hash() -> String: - "0x103d0af04de36ab98b311e537366ec67" + "0xabe575924687afad4cee1a2c1194d639" # the build, with ez taken out of the environment. BEND_LIB is the # checkouts this test laid out, not ez's.