Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 0 additions & 28 deletions crates/jett_comptime/src/interpreter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8708,34 +8708,6 @@ impl Interpreter {
_ => Some(Err(format!("{name} expects two int64 arguments"))),
}
}
"math.sum" => {
require_args!(name, 1, args);
match &args[0] {
Value::List(items) => {
let mut total: i64 = 0;
for item in items {
match item {
Value::Int64(n) => {
let Some(next_total) = total.checked_add(*n) else {
return Some(Err(format!(
"math.sum: integer overflow: {total} + {n}"
)));
};
total = next_total;
}
_ => {
return Some(Err(
"math.sum: list must contain int64 values".to_string()
));
}
}
}
Some(Ok(Value::Int64(total)))
}
_ => Some(Err(format!("{name} expects a list argument"))),
}
}

"math.gcd" => {
require_args!(name, 2, args);
match (&args[0], &args[1]) {
Expand Down
1 change: 1 addition & 0 deletions crates/jett_driver/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3447,6 +3447,7 @@ mod tests {
("math.sign", "int64", "int64"),
("math.to_radians", "float64", "float64"),
("math.to_degrees", "float64", "float64"),
("math.sum", "list[int64]", "int64"),
];

for (name, param_type, return_type) in expected {
Expand Down
11 changes: 10 additions & 1 deletion crates/jett_driver/tests/fixture_suite.rs
Original file line number Diff line number Diff line change
Expand Up @@ -392,7 +392,7 @@ fn sized_integer_runtime_bounds_reject_variable_arithmetic() {
fn math_sum_reports_overflow() {
assert_runtime_fail(
"math_sum_overflow.jett",
"runtime error: math.sum: integer overflow: 9223372036854775807 + 1",
"runtime error: integer overflow: 9223372036854775807 + 1",
);
}

Expand Down Expand Up @@ -755,6 +755,7 @@ compile_fail_fixture!(
run_pass_fixture!(run_pass_string_search, "string_search.jett");
run_pass_fixture!(run_pass_time_and_os, "time_and_os.jett");
run_pass_fixture!(run_pass_math_trig, "math_trig.jett");
run_pass_fixture!(run_pass_math_sum_source, "math_sum_source.jett");
run_pass_fixture!(run_pass_logical_ops, "logical_ops.jett");
run_pass_fixture!(run_pass_trace_basic, "trace_basic.jett");
run_pass_fixture!(run_pass_breakpoint_basic, "breakpoint_basic.jett");
Expand Down Expand Up @@ -882,6 +883,14 @@ compile_fail_fixture!(
compile_fail_ownership_branch_partial_move,
"ownership_branch_partial_move.jett"
);
compile_fail_fixture!(
compile_fail_math_sum_consumes_list,
"math_sum_consumes_list.jett"
);
compile_fail_fixture!(
compile_fail_math_sum_argument_shape,
"math_sum_argument_shape.jett"
);
compile_fail_fixture!(
compile_fail_pipeline_builtin_input_mismatch,
"pipeline_builtin_input_mismatch.jett"
Expand Down
5 changes: 0 additions & 5 deletions crates/jett_typecheck/src/checker.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3381,11 +3381,6 @@ impl<'a> TypeChecker<'a> {
vec![TypeInterner::INT64],
TypeInterner::INT64,
),
"math.sum" => {
self.expect_no_type_args(&name, type_args, span);
let list_int = self.interner.intern(Type::List(TypeInterner::INT64));
Some((vec![list_int], TypeInterner::INT64))
}
// string extras
"string.reverse" | "string.trim_start" | "string.trim_end" => self
.no_type_args_signature(
Expand Down
8 changes: 5 additions & 3 deletions docs/architecture.md
Original file line number Diff line number Diff line change
Expand Up @@ -1226,9 +1226,11 @@ The compiler does not have hardcoded knowledge of these functions. They are reso
The current math extraction is intentionally narrower than that end state.
`math.is_even`, `math.is_odd`, `math.sign`, `math.to_radians`, and
`math.to_degrees` are ordinary source-defined functions in `stdlib/math.jett`.
Their primitive dependencies, `math.mod` and `math.pi`, remain compiler-owned
Rust kernels, and the other supported math builtins remain Rust-backed pending
separate extraction work.
The consuming `math.sum(list[int64])` helper is source-defined there as well and
accumulates with checked Jett `int64` addition. The primitive dependencies
`math.mod` and `math.pi` remain compiler-owned Rust kernels. Exact numeric
overloads such as `math.abs`, `math.min`, and `math.max`, and the other supported
math builtins remain Rust-backed pending separate extraction work.

**3. Runtime-backed stdlib** — Jett functions that call into the runtime:

Expand Down
22 changes: 13 additions & 9 deletions docs/design.md
Original file line number Diff line number Diff line change
Expand Up @@ -609,12 +609,13 @@ function fetch_data(view net: Network, url: string) returns result[map[string, s
return fail(parse_error)
return ok(data)

function compute_stats(values: list[float64]) returns float64:
function compute_stats(values: list[int64]) returns float64:
use math
float64 total = math.sum(values)
int64 count = list.length[float64](values)
int64 count = list.length[int64](view values)
int64 total = math.sum(values)
float64 total_f = float64.from_int64(total)
float64 count_f = float64.from_int64(count)
return total / count_f
return total_f / count_f
```

**What this achieves:**
Expand Down Expand Up @@ -1371,11 +1372,14 @@ float64 power = math.pow(base, exponent)

Compositional math helpers should be ordinary Jett source when the language can
express them without losing numeric semantics. `math.is_even`, `math.is_odd`,
`math.sign`, `math.to_radians`, and `math.to_degrees` are therefore defined in
`stdlib/math.jett` and resolved like user functions. `math.mod` and `math.pi`
remain compiler-owned Rust primitive kernels used by those definitions; the
other currently supported math builtins also remain Rust-backed until they are
separately extracted.
`math.sign`, `math.to_radians`, `math.to_degrees`, and the consuming
`math.sum(list[int64])` helper are therefore defined in `stdlib/math.jett` and
resolved like user functions. `math.sum` uses ordinary checked source addition,
so overflow reports the same deterministic arithmetic error as other Jett
`int64` expressions. `math.mod` and `math.pi` remain compiler-owned Rust
primitive kernels used by those definitions. Exact numeric overloads such as
`math.abs`, `math.min`, and `math.max`, along with the other supported math
builtins, remain Rust-backed until they are separately extracted.

**Hashing and encoding — no third-party dependencies:**

Expand Down
4 changes: 2 additions & 2 deletions docs/progress.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@
| MIR (control flow graph) | `jett_mir` | — | Not started ([Tracked by #22](https://github.com/vycdev/jett/issues/22)) |
| LLVM native codegen | `jett_codegen_llvm` | — | Not started |
| Runtime library | `jett_runtime` | — | Not started |
| Core stdlib (.jett files) | `stdlib/` | — | Partial (bootstrap loader plus marker module and extracted `json` module; `math.is_even`, `math.is_odd`, `math.sign`, `math.to_radians`, and `math.to_degrees` are source-defined in `stdlib/math.jett`; `math.sum` source extraction is [tracked by #63](https://github.com/vycdev/jett/issues/63); many other modules and math operations remain Rust-backed) |
| Core stdlib (.jett files) | `stdlib/` | — | Partial (bootstrap loader plus marker module and extracted `json` module; `math.is_even`, `math.is_odd`, `math.sign`, `math.to_radians`, `math.to_degrees`, and consuming `math.sum(list[int64])` are source-defined in `stdlib/math.jett`; many other modules and math operations remain Rust-backed) |

### Phase E: Comptime and Verification — COMPLETE

Expand Down Expand Up @@ -158,7 +158,7 @@
| `list` | Partial (40+ builtins: new, length, append, get, first, last, is_empty, skip, take, reverse, sort, contains, index_of, remove, concat, flatten, unique, zip, chunk, sort_by_index, is_sorted, all_elements_in, enumerate, from_set, repeat, range, last_index_of, insert_at, remove_at, swap + higher-order: filter, map, find, sort_by, all, any, count, sum, group_by, reduce, flat_map) |
| `set` | Partial (12 builtins: new, add, remove, contains, length, is_empty, to_list, union, intersection, difference) |
| `map` | Partial (17+ builtins: new, length, has/contains_key, get, get_or, insert/set, remove, keys, values, is_empty, merge, from_lists, entries + higher-order filter, map_values, for_each) |
| `math` | Partial (`is_even`, `is_odd`, `sign`, `to_radians`, and `to_degrees` are source-defined in `stdlib/math.jett`; `mod` and `pi` remain primitive Rust kernels used by those helpers; other supported operations such as abs, sqrt, pow, floor, ceil, round, clamp, log, log2, log10, min, max, average, median, e, sin, cos, tan, and sum remain Rust-backed; `math.sum` source extraction is [tracked by #63](https://github.com/vycdev/jett/issues/63)) |
| `math` | Partial (`is_even`, `is_odd`, `sign`, `to_radians`, `to_degrees`, and consuming monomorphic `sum(list[int64])` are source-defined in `stdlib/math.jett`; `sum` uses checked source `int64` addition; `mod` and `pi` remain primitive Rust kernels used by source helpers; other supported operations such as abs, sqrt, pow, floor, ceil, round, clamp, log, log2, log10, min, max, average, median, e, sin, cos, and tan remain Rust-backed) |
| `json` | Partial (json.serialize, json.serialize_public, json.parse_exact, json.parse_raw/JsonValue accessors, compiler-owned public policy for parse/serialization; interpreter `json.parse`, `json.parse_exact`, `json.serialize`, and `json.serialize_public` require trusted stdlib-loaded reflected `.jett` hooks under `namespace json`; typed `json.parse[T]` routes through the stdlib `JsonTree` parser/decoder, including the `json.parse[JsonValue]` compatibility branch, while `json.parse_exact[T]` rejects unknown object fields recursively; stdlib `JsonTree` has a view-native serializer, scalar/array/object parser, exported raw facade wrappers, traversal/scalar-cast helpers, reflected parse/serialize for machine state/payload envelopes, and reflected decoding via `TypeConstruction` for nested structs, enum-annotated bitfields, enums, machines, lists/maps/sets, optionals/results, bytes, sized integer/float primitives, null, secret wrappers, aliases/refinements, and missing optional-field defaults; raw `JsonValue` parsing/access now runs on native `JsonTree` values through trusted stdlib facades with a shared `jett_common` JSON-facade policy for runtime dispatch, trusted hook mapping, and implicit view ownership, typechecker raw facade signatures now come from the exported `json.JsonTree` stdlib surface, with bare `JsonValue` preserved by the stdlib-only root alias to bundled `json.JsonTree`, using checked reflection metadata for direct type reflection builtins, `TypeInfo`, `type.arg`, trusted `comptime type` bindings for args/field/variant/machine-state loops, `TypeField`, `type.field_value`, bitfield metadata, machine metadata, active machine state/field access, enum variant metadata, `type.variant_value`, `type.variant_field_value`, `type.construct_variant_start`, `type.construct_machine_start`, `type.construct_put`, `type.construct_finish`, the runtime `main()` interpreter, and the `json.serialize` secret-containing type gate, with fallback-path audit complete, canonical `TypeId` metadata lookup scaffolding expanded to owner fields/bitfields/machines/variants, and missing checked owner metadata now surfaced for fields/bitfields/machines/variants) |
| `random` | Partial (5 builtins: int64, float64, bool, choice, shuffle; capability and entropy contract [tracked by #67](https://github.com/vycdev/jett/issues/67)) |
| `crypto` | Partial (sha256, md5; stable hashing API, security guarantees, and stdlib/runtime boundary [tracked by #69](https://github.com/vycdev/jett/issues/69)) |
Expand Down
5 changes: 5 additions & 0 deletions stdlib/math.jett
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,8 @@ export function to_radians(degrees: float64) returns float64:
return degrees * math.pi() / 180.0
export function to_degrees(radians: float64) returns float64:
return radians * 180.0 / math.pi()
export function sum(values: list[int64]) returns int64:
mutable int64 total = 0
for value in values:
total = total + value
return total
7 changes: 7 additions & 0 deletions tests/compile_fail/math_sum_argument_shape.jett
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# ERROR: E0303
# ERROR: E0300
namespace test
function sum_requires_one_list() returns int64:
return math.sum()
function sum_requires_int64_items() returns int64:
return math.sum(list("not an integer"))
7 changes: 7 additions & 0 deletions tests/compile_fail/math_sum_consumes_list.jett
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# ERROR: E0400
namespace test
function sum_consumes_list() returns int64:
list[int64] values = list(1, 2, 3)
int64 total = math.sum(values)
int64 length = list.length[int64](values)
return total + length
21 changes: 21 additions & 0 deletions tests/run_pass/math_sum_source.jett
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
namespace app
function sum_positive_test() returns int64:
return math.sum(list(1, 2, 3, 4, 5))
verify sum_positive_test:
assert sum_positive_test() == 15
function sum_empty_test() returns int64:
return math.sum(list())
verify sum_empty_test:
assert sum_empty_test() == 0
function sum_singleton_test() returns int64:
return math.sum(list(-7))
verify sum_singleton_test:
assert sum_singleton_test() == -7
function sum_negative_test() returns int64:
return math.sum(list(-1, -2, -3, -4))
verify sum_negative_test:
assert sum_negative_test() == -10
function sum_cancellation_test() returns int64:
return math.sum(list(9223372036854775807, -9223372036854775807, 1))
verify sum_cancellation_test:
assert sum_cancellation_test() == 1