diff --git a/README.md b/README.md index efc8b0e..2e1d82c 100644 --- a/README.md +++ b/README.md @@ -20,6 +20,6 @@ name resolution (`@source/sema`) runs after parsing. it predeclares package name type checking (`@source/sema/check`) runs after name resolution. `check.check` borrows the AST and binding table and returns owned per-node types; query with `check.type_of` and release with `check.deinit`. declarations infer their initializer types, including forward references and function aliases; function types identify the declaration supplying the callable signature. annotations must name builtin types; type names are not ordinary values. `void` is valid as a function result, not as a parameter or stored value. -numeric typing follows Bro's contextual rules within Honey's current `int` and `float` families. integer literals can adopt either family; float literals remain float. numeric demands propagate through arithmetic and inferred bindings before undemanded integers default to `int`. conflicting demands are errors; fixed `int` values do not implicitly convert to `float`. `+`, `-`, `*` and unary `-` require compatible numeric operands; `/` is float-only. `3 / 2` is invalid without float context, while `3.0 / 2` and `ratio float :: 3 / 2` are valid. +numeric typing follows contextual rules within Honey's current `int` and `float` families. integer literals can adopt either family; float literals remain float. numeric demands propagate through arithmetic and inferred bindings before undemanded integers default to `int`. conflicting demands are errors; fixed `int` values do not implicitly convert to `float`. `+`, `-`, `*` and unary `-` require compatible numeric operands; `/` requires and supplies float context. `3 / 2`, `3.0 / 2`, and `ratio float :: 3 / 2` are valid; division involving fixed `int` values requires explicit conversion. type errors carry source spans and diagnostic identities; invalid operands propagate their existing identity without duplicate errors, while independent expressions and arguments are still checked. inference cycles without a type anchor are diagnosed. read-before-initialization and runtime initialization-cycle checks remain separate, unimplemented work. function signatures are checked independently of their bodies; since return statements are not yet parsed, nonvoid functions currently report missing-return diagnostics. lowering and executable generation remain unimplemented. diff --git a/source/main.hon b/source/main.hon index fad8175..e44064a 100644 --- a/source/main.hon +++ b/source/main.hon @@ -34,7 +34,7 @@ program :: `z :: "hello" ` `a := 1 + 2 * 3 - `b :: -3.0 / 2 + 1 + `b :: -3 / 2 + 1 ` `grouped proc(left, right int, extra float) void { ` value int :: later + left diff --git a/source/sema/check/check.hon b/source/sema/check/check.hon index a560ada..63f4341 100644 --- a/source/sema/check/check.hon +++ b/source/sema/check/check.hon @@ -179,6 +179,9 @@ check proc( expression :: ast.binary_expr(tree, id) try numeric_operand(&state, id, expression.left) try numeric_operand(&state, id, expression.right) + if (expression.operator == .divide) { + try impose(&state, id, .float, .integer_division, expression.span) + } } else: {} } diff --git a/source/sema/check/check.test.hon b/source/sema/check/check.test.hon index 2ecbf6c..e619d7e 100644 --- a/source/sema/check/check.test.hon +++ b/source/sema/check/check.test.hon @@ -56,8 +56,8 @@ propagates_numeric_context_before_defaulting_forward_and_mutable_aliases test { `seed := 3 `backward :: 4 `demand float :: backward - `quotient float :: 3 / 2 - `mixed :: 3.0 / 2 + `quotient :: -3 / 2 + 1 + `mixed :: 3 / 2 `plain :: -3 + 2 * 4 `fraction :: 1.5 `text :: "honey" @@ -112,7 +112,7 @@ rejects_fixed_family_conversion_integer_division_and_conflicting_demands test { `widen float :: fixed `narrow int :: 1.5 `cross :: fixed + real - `division :: 3 / 2 + `division :: fixed / 2 `negated :: -"x" `strings :: "a" + "b" `first_int int :: conflict_a