A refused dyn view of a global names its own defining form as the fix, and every dyn fix is spelled in the syntax the code was written in
This commit is contained in:
parent
c1b21edaf4
commit
35aa5a8c0f
@ -133,7 +133,7 @@ reply without a daemon behind them, and so that this file names
|
|||||||
;; its span bound of 8 fields
|
;; its span bound of 8 fields
|
||||||
;; (Name A {.f V}) an instance of a generic struct, its type arguments
|
;; (Name A {.f V}) an instance of a generic struct, its type arguments
|
||||||
;; kept on the head (:text) and the name alone as :type
|
;; kept on the head (:text) and the name alone as :type
|
||||||
;; [ V V V] an array or a slice, ` ...' likewise
|
;; [V V V] an array or a slice, ` ...' likewise
|
||||||
;; (some V) / none an option
|
;; (some V) / none an option
|
||||||
;; <ptr> a pointer, never followed
|
;; <ptr> a pointer, never followed
|
||||||
;; <Name> a named type the walk had no structure for
|
;; <Name> a named type the walk had no structure for
|
||||||
|
|||||||
@ -76,7 +76,7 @@
|
|||||||
|
|
||||||
;; A generic struct's instance, its type arguments between the name and the
|
;; A generic struct's instance, its type arguments between the name and the
|
||||||
;; brace, compound ones included. Written back as it was read.
|
;; brace, compound ones included. Written back as it was read.
|
||||||
(let* ((src "(Pair (Option u8) [3 i32] {.a (some 1) .b [ 1 2 3]})")
|
(let* ((src "(Pair (Option u8) [3 i32] {.a (some 1) .b [1 2 3]})")
|
||||||
(n (flan-inspect-parse src)))
|
(n (flan-inspect-parse src)))
|
||||||
(test-flan--check "a generic instance is a struct"
|
(test-flan--check "a generic instance is a struct"
|
||||||
(eq (plist-get n :kind) 'struct))
|
(eq (plist-get n :kind) 'struct))
|
||||||
@ -92,13 +92,13 @@
|
|||||||
:children))
|
:children))
|
||||||
'("a")))
|
'("a")))
|
||||||
|
|
||||||
;; [ 0 42 0] — Types.Slice and Types.Array both write this.
|
;; [0 42 0] — Types.Slice and Types.Array both write this.
|
||||||
(let ((n (flan-inspect-parse "[0 42 0]")))
|
(let ((n (flan-inspect-parse "[0 42 0]")))
|
||||||
(test-flan--check "a sequence is a sequence" (eq (plist-get n :kind) 'seq))
|
(test-flan--check "a sequence is a sequence" (eq (plist-get n :kind) 'seq))
|
||||||
(test-flan--check "indexed from zero"
|
(test-flan--check "indexed from zero"
|
||||||
(equal (mapcar #'car (plist-get n :children)) '(0 1 2))))
|
(equal (mapcar #'car (plist-get n :children)) '(0 1 2))))
|
||||||
|
|
||||||
;; [ [ 0 0] [ 1 ...] ...] — span truncation at both levels, which is what
|
;; [[0 0] [1 ...] ...] — span truncation at both levels, which is what
|
||||||
;; sand's [100 [100 u32]] actually produces.
|
;; sand's [100 [100 u32]] actually produces.
|
||||||
(let* ((n (flan-inspect-parse "[[0 0] [1 ...] ...]"))
|
(let* ((n (flan-inspect-parse "[[0 0] [1 ...] ...]"))
|
||||||
(kids (plist-get n :children)))
|
(kids (plist-get n :children)))
|
||||||
|
|||||||
21
lib/check.ml
21
lib/check.ml
@ -3454,7 +3454,13 @@ let view_elem_lit loc (k : int64) =
|
|||||||
(* A fix is spelled in the syntax of the file the mistake is in: the checker
|
(* A fix is spelled in the syntax of the file the mistake is in: the checker
|
||||||
sees one AST for both, so the location's file is the only thing left that
|
sees one AST for both, so the location's file is the only thing left that
|
||||||
says which one the reader is looking at. *)
|
says which one the reader is looking at. *)
|
||||||
let fln_source (loc : Loc.t) = Filename.check_suffix loc.Loc.file ".fln"
|
let fln_source (loc : Loc.t) = Source.indented_at loc
|
||||||
|
|
||||||
|
(* Which form defined each mutable global, [defonce] or [def], so a fix that
|
||||||
|
rewrites the definition keeps the form the programmer chose. Filled where
|
||||||
|
globals are collected; a name missing from it (a defconst) is given
|
||||||
|
[defonce]. *)
|
||||||
|
let global_forms : (string, Ast.reinit) Hashtbl.t = Hashtbl.create 16
|
||||||
|
|
||||||
(* The function being checked and its parameters, by slot. A stack because
|
(* The function being checked and its parameters, by slot. A stack because
|
||||||
a generic's copy is checked from inside the body that called it. *)
|
a generic's copy is checked from inside the body that called it. *)
|
||||||
@ -3496,6 +3502,18 @@ let view_refusal kind loc (e : Tast.expr) reason =
|
|||||||
( Printf.sprintf "%s is a %s parameter" n ty,
|
( Printf.sprintf "%s is a %s parameter" n ty,
|
||||||
Printf.sprintf "Declare %s as dyn in %s's parameters: %s%s" n f n
|
Printf.sprintf "Declare %s as dyn in %s's parameters: %s%s" n f n
|
||||||
(if fln then ": dyn" else " dyn") )
|
(if fln then ": dyn" else " dyn") )
|
||||||
|
| None, Some n when (match e.Tast.e with Tast.Global _ -> true | _ -> false) ->
|
||||||
|
let every =
|
||||||
|
match e.Tast.e with
|
||||||
|
| Tast.Global g -> Hashtbl.find_opt global_forms g = Some Ast.Every
|
||||||
|
| _ -> false
|
||||||
|
in
|
||||||
|
( Printf.sprintf "%s is a %s" n ty,
|
||||||
|
Printf.sprintf "Define %s as a dyn value, as in %s" n
|
||||||
|
(if fln then
|
||||||
|
Printf.sprintf "%s %s: dyn = [...]" (if every then "def" else "once") n
|
||||||
|
else
|
||||||
|
Printf.sprintf "(%s %s dyn [...])" (if every then "def" else "defonce") n) )
|
||||||
| None, Some n ->
|
| None, Some n ->
|
||||||
( Printf.sprintf "%s is a %s" n ty,
|
( Printf.sprintf "%s is a %s" n ty,
|
||||||
Printf.sprintf "Build %s as a dyn value where it is made, as in %s" n
|
Printf.sprintf "Build %s as a dyn value where it is made, as in %s" n
|
||||||
@ -14601,6 +14619,7 @@ let collect env (decls : Ast.decl list) =
|
|||||||
(match k with Ast.Once -> "defonce" | Ast.Every -> "def") n
|
(match k with Ast.Once -> "defonce" | Ast.Every -> "def") n
|
||||||
in
|
in
|
||||||
Hashtbl.replace env.globals n (ty, false);
|
Hashtbl.replace env.globals n (ty, false);
|
||||||
|
Hashtbl.replace global_forms n k;
|
||||||
Hashtbl.replace env.global_locs n loc
|
Hashtbl.replace env.global_locs n loc
|
||||||
| Ast.Defconst (n, Some t, _) ->
|
| Ast.Defconst (n, Some t, _) ->
|
||||||
Hashtbl.replace env.globals n (resolve env t, true);
|
Hashtbl.replace env.globals n (resolve env t, true);
|
||||||
|
|||||||
@ -610,6 +610,28 @@ let () =
|
|||||||
checks "view-param-fix.fln"
|
checks "view-param-fix.fln"
|
||||||
"fn take(d) -> i32 = 1\n\nfn give(n: i32, v: dyn) -> i32\n take(v)\n\n\
|
"fn take(d) -> i32 = 1\n\nfn give(n: i32, v: dyn) -> i32\n take(v)\n\n\
|
||||||
fn main() -> i32 = 0\n";
|
fn main() -> i32 = 0\n";
|
||||||
|
(* A global's fix redefines it, in the form it was defined with. *)
|
||||||
|
let show_flan = "(defn show [d dyn] i32 1)\n" in
|
||||||
|
refused "view-global.flan"
|
||||||
|
("(defonce gs [2 i32] [1 2])\n" ^ show_flan ^ "(defn main [] i32 (show gs))\n")
|
||||||
|
[ "gs is a [2 i32]"; "as in (defonce gs dyn [...])" ];
|
||||||
|
refused "view-global-def.flan"
|
||||||
|
("(def gs [2 i32] [1 2])\n" ^ show_flan ^ "(defn main [] i32 (show gs))\n")
|
||||||
|
[ "as in (def gs dyn [...])" ];
|
||||||
|
refused "view-global.fln"
|
||||||
|
"once gs: [2 i32] = [1 2]\n\nfn show(d) -> i32 = 1\n\nfn main() -> i32 = show(gs)\n"
|
||||||
|
[ "gs is a [2 i32]"; "as in once gs: dyn = [...]" ];
|
||||||
|
checks "view-global-fix.flan"
|
||||||
|
("(defonce gs dyn [1 2])\n(def hs dyn [1 2])\n" ^ show_flan
|
||||||
|
^ "(defn main [] i32 (show gs) (show hs))\n");
|
||||||
|
checks "view-global-fix.fln"
|
||||||
|
"once gs: dyn = [1 2]\n\nfn show(d) -> i32 = 1\n\nfn main() -> i32 = show(gs)\n";
|
||||||
|
(* The fix is spelled in the syntax the code was sent in, not the one the
|
||||||
|
file's name implies: an editor request from an indented buffer. *)
|
||||||
|
Source.with_code ~syntax:Source.Indented ~at:None (fun () ->
|
||||||
|
refused "unit-tail-request.flan"
|
||||||
|
"(defn f [coll] dyn (let [i 1] (while (< i 3) (++ i))))\n(defn main [] () (f 1))\n"
|
||||||
|
[ "fn f(...) -> ()" ]);
|
||||||
(* The fix both of them name. *)
|
(* The fix both of them name. *)
|
||||||
checks "view-fix.fln"
|
checks "view-fix.fln"
|
||||||
(poke_fln ^ "fn main() -> ()\n let d: dyn = [6 2 4 9]\n poke(d)\n poke(the(dyn, [1 2]))\n");
|
(poke_fln ^ "fn main() -> ()\n let d: dyn = [6 2 4 9]\n poke(d)\n poke(the(dyn, [1 2]))\n");
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user