From 5f1b572f90287ce23283632ff6b11760c47aac27 Mon Sep 17 00:00:00 2001 From: Henry <77937076+yung-turabian@users.noreply.github.com> Date: Sat, 8 Feb 2025 19:02:22 -0500 Subject: [PATCH] Did a few things: + Added build scripts; Offered a fix for emacs mode; + Added a TODO markdown for keeping track of things; + In `irCheck.ml` a variable named effect needed to be renamed as that is reserved in ocaml now + Moved `abs` from Prelude to `lib.ml` to take advantage of pattern matching related OCaml types so it can be ad hoc + And started writing some tests --- TODO.md | 7 +++++++ bld.sh | 5 +++++ core/irCheck.ml | 6 +++--- core/lib.ml | 28 +++++++++++++++++--------- ins.sh | 4 ++++ links-mode.el | 17 ++++++++++++++-- prelude.links | 3 --- tests/numeric-operations.tests | 36 ++++++++++++++++++++++++++++++++++ 8 files changed, 89 insertions(+), 17 deletions(-) create mode 100644 TODO.md create mode 100755 bld.sh create mode 100755 ins.sh create mode 100644 tests/numeric-operations.tests diff --git a/TODO.md b/TODO.md new file mode 100644 index 000000000..2441eb70b --- /dev/null +++ b/TODO.md @@ -0,0 +1,7 @@ +# TODO (yung-turabian) + +- [-] Add some test cases. +- [ ] Have type inference convert, for example, int to float in a operation like 2.0 + 2? Hide behind an experimental guard if so. +- [ ] Singleton kinds, they classify type cons by reavling their identity. + - [ ] Higher singletons, S(c :: k) where k is a kind and c is a constructor of kind k. +- [ ] If given the ability to create new subkinds, then just force the creation to derive from one of the three 'base' (Type, Row, Presnece) or even one of their subkinds such as "Base." \ No newline at end of file diff --git a/bld.sh b/bld.sh new file mode 100755 index 000000000..874c838d6 --- /dev/null +++ b/bld.sh @@ -0,0 +1,5 @@ +#!/usr/bin/bash + +dune build +mv _build/default/bin/links.exe links + diff --git a/core/irCheck.ml b/core/irCheck.ml index f3f6df4de..52fdc3612 100644 --- a/core/irCheck.ml +++ b/core/irCheck.ml @@ -1053,11 +1053,11 @@ struct (* For each case branch, the corresponding entry goes directly into the field spec map of the inner effect row *) let inner_effects_map_from_branches = StringMap.map (fun x -> Present x) branch_presence_spec_types in (* We now add all entries from the outer effects that were not touched by the handler to the inner effects *) - let inner_effects_map = StringMap.fold (fun effect outer_presence_spec map -> - if StringMap.mem effect inner_effects_map_from_branches then + let inner_effects_map = StringMap.fold (fun effect' outer_presence_spec map -> + if StringMap.mem effect' inner_effects_map_from_branches then map else - StringMap.add effect outer_presence_spec map + StringMap.add effect' outer_presence_spec map ) inner_effects_map_from_branches outer_effects_map in let inner_effects = Row (inner_effects_map, outer_effects_var, outer_effects_dualized) in diff --git a/core/lib.ml b/core/lib.ml index 96dbca191..da390ecda 100644 --- a/core/lib.ml +++ b/core/lib.ml @@ -243,11 +243,11 @@ let project_datetime (f: CalendarShow.t -> int) : located_primitive * Types.data let env : (string * (located_primitive * Types.datatype * pure)) list = [ - "+", numeric_op ( + ) ( +. ) PURE PURE; - "-", numeric_op ( - ) ( -. ) PURE PURE; - "*", numeric_op ( * ) ( *. ) PURE PURE; - "/", numeric_op ( / ) ( /. ) IMPURE PURE; - "^", numeric_op (pow) ( ** ) PURE PURE; + "+", numeric_op ( + ) ( +. ) PURE PURE; + "-", numeric_op ( - ) ( -. ) PURE PURE; + "*", numeric_op ( * ) ( *. ) PURE PURE; + "/", numeric_op ( / ) ( /. ) IMPURE PURE; + "^", numeric_op (pow) ( ** ) PURE PURE; "mod", int_op ( mod ) IMPURE; @@ -260,6 +260,16 @@ let env : (string * (located_primitive * Types.datatype * pure)) list = [ "^^", string_op ( ^ ) PURE; + (* moved abs to make use of ad hoc ability, + ideally there could be a way to bootstrap prelude similar to #786 *) + "abs", + (p1 (fun n -> match n with + | `Int _ -> Value.box_int ( let x = (Value.unbox_int n) in if x > 0 then x else -x ) + | `Float _ -> Value.box_float ( let x = (Value.unbox_float n) in if x > 0.0 then x else -.x ) + | _ -> raise (runtime_type_error ("Cannot computer absolute value: " ^ Value.string_of_value n))), + datatype "(a::Numeric) -> a", + PURE); + "max_int", (Value.box_int max_int, datatype "Int", @@ -750,10 +760,10 @@ let env : (string * (located_primitive * Types.datatype * pure)) list = [ PURE); "negate", - (p1 (fun i -> match i with - | `Int _ -> Value.box_int (- (Value.unbox_int i)) - | `Float _ -> Value.box_float (-. (Value.unbox_float i)) - | _ -> raise (runtime_type_error ("Cannot negate: " ^ Value.string_of_value i))), + (p1 (fun n -> match n with + | `Int _ -> Value.box_int (- (Value.unbox_int n)) + | `Float _ -> Value.box_float (-. (Value.unbox_float n)) + | _ -> raise (runtime_type_error ("Cannot negate: " ^ Value.string_of_value n))), datatype "(a::Numeric) -> a", PURE); diff --git a/ins.sh b/ins.sh new file mode 100755 index 000000000..56d875268 --- /dev/null +++ b/ins.sh @@ -0,0 +1,4 @@ +#!/usr/bin/bash + +dune build +sudo mv _build/default/bin/links.exe /usr/local/bin/links diff --git a/links-mode.el b/links-mode.el index fe45518a5..239245641 100644 --- a/links-mode.el +++ b/links-mode.el @@ -45,8 +45,7 @@ st)) ;; Can be generated with `links --print-keywords`. -;; TODO We should do that automatically as part of the build process somehow. -(defconst links-keywords +(defconst links-backup-keywords '( "alien" "as" @@ -121,6 +120,20 @@ "with" )) +;;; Added by yung-turabian 2025 +(defconst links-keywords + ; Not the best test + (if (string-equal + (shell-command-to-string (concat links-executable " --version")) + "Links version 0.9.9 (Burghmuirhead)\n" + ) + (split-string + (shell-command-to-string (concat links-executable " --print-keywords")) + "\n" " ") + links-backup-keywords) + ) + + (defconst links-font-lock-keywords (list ;; comments diff --git a/prelude.links b/prelude.links index c210282d8..7d7fca74d 100644 --- a/prelude.links +++ b/prelude.links @@ -307,9 +307,6 @@ fun dropWhile(pred, list) { # else 0 # } -fun abs(i) { - if (i < 0) -i else i -} sig init : ([a]) ~> [a] fun init(list) { diff --git a/tests/numeric-operations.tests b/tests/numeric-operations.tests new file mode 100644 index 000000000..ee2ae2a5a --- /dev/null +++ b/tests/numeric-operations.tests @@ -0,0 +1,36 @@ +Addition and multiplication [1] +10 + 20 * 30 +stdout : 610 : Int + +Addition and multiplication [2] +20.0 * 30.0 + 10.0 +stdout : 610.0 : Float + +Addition, division, subtraction, and multiplication +100.50 + 200.20 / 10.10 - 3.10 * 10.10 +stdout : 89.0117821782 : Float + +Inproper usage +2 - 3.3 +stderr : @..* +exit : 1 + +Absolute value of integer +abs(-9) +stdout : 9 : Int + +Absolute value of float +abs(-9.54) +stdout : 9.54 : Float + +Prefix notation +{var plus = (+); plus(1.5, (+)(2.5,3.5))} +stdout : 7.5 : Float + +Unary minus +(-1) +stdout : -1 : Int + +Unary float minus +(-1.0) +stdout : -1.0 : Float \ No newline at end of file