HaxeFoundation / HaxeFoundation/haxe

typing and 64 bit literals

Open
#5,150 10 comments 0 reactions 0 assignees View on GitHub
Dominant language
Haxe
Stars
6.9k
Forks
715
Avg merge
2d 2h
Merged PRs (30d)
11

Description

Given:

``` haxe
var a: Float = 111111111112222222.3333;
var b = 0xFFFFFF;
var c = 281474976710655;
var d = 0xFFFFFFFFFFFF;
```

All of them except for `d` will compile as expected, regardless of the typing of the assignee.

However, `d` errors with: `Invalid hexadecimal integer`

This is a [very specific](https://github.com/HaxeFoundation/haxe/blob/b5a728976ef264f21ca5b500eb5e49832031ddb8/src/generators/codegen.ml#L58) case to disallow explicitly, and I would like to understand why.

A) haxe now has Int64 (even if it is a wrapper).
I know that Int64.make(low, high) to create a value to work around this, but the issue is that the _typing_ rejects the constant explicitly without clear reason.

B) This is strange because it doesn't reject decimal or floating point 64 bit constants. It makes an exception for hexadecimal. If the concern is incorrect use (storing a bigger value in a smaller type), it should be a compiler error not a typing error on the literal to even exist in the source code.

C) This is a problem because there are many places where a 64 bit hexadecimal is needed. Many parts of haxe can be considered pass through, since it targets another language, and this is especially true in the context of externs. `var a = untyped 0xFFFFFFFFFFFF` will also be rejected. There is just no way around this from the haxe syntax, it is treating the literal as invalid syntax.

If I wanted to do bitmasking on a 64 bit value I cannot do it above above 32 bits without resorting to use decimal representation or shifting, which has other problems (Like the compiler converting the constants to 32 bit representations, wrapping them, and then casting them to int anyway! see: `int tmp = (int(id) >> int(((::cpp::Int64)((int)-1))));` )

This is hard to understand, given that in `js`, `c++`, `lua`, `python`, `csharp`, `java`,
None of these languages impose an arbitrary restriction on hexadecimal.
In these languages typically a `L` is appended to the literal if the user is expecting higher than 32 bits or if the literal is intended to be typed higher than 32 bits.

Is there a way to allow a 64 bit hexadecimal constant, please?
I would think the `L` suffix is the most compatible option that is both clear, consistent with many similar languages, and is also fully backward compatible.

Contributor guide

Open the contributing guide

Research direction

Reproduce the hexadecimal and decimal literal examples, then inspect src/generators/codegen.ml at the linked restriction and the surrounding literal handling. Compare how typing and code generation treat 32-bit and larger values. Done means a clearly defined, tested way to represent 64-bit hexadecimal constants without regressing existing literal behavior.

Written by the indexing model from the issue text.

Assessment

Domain
compilers
Issue type
Feature
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.