Skip to content

Commit

Permalink
Implement Int512
Browse files Browse the repository at this point in the history
Yeah I'm done
  • Loading branch information
SomeGuyWhoLovesCoding committed Nov 9, 2024
1 parent dbfdac1 commit 7609332
Show file tree
Hide file tree
Showing 9 changed files with 706 additions and 11 deletions.
2 changes: 1 addition & 1 deletion src/macro/macroApi.ml
Original file line number Diff line number Diff line change
Expand Up @@ -672,7 +672,7 @@ let decode_const c =
| 0, [s;suffix] ->
let decoded_suffix = opt decode_string suffix in
(match decoded_suffix with
| None | Some "i32" | Some "i64" | Some "i128" | Some "i256" | Some "u32" ->
| None | Some "i32" | Some "i64" | Some "i128" | Some "i256" | Some "i512" | Some "u32" ->
Int (decode_string s, decoded_suffix)
| Some other ->
raise Invalid_expr)
Expand Down
2 changes: 2 additions & 0 deletions src/syntax/reification.ml
Original file line number Diff line number Diff line change
Expand Up @@ -370,6 +370,8 @@ let reify in_macro =
expr "EConst" [mk_enum "Constant" "CInt" [ (EConst(String (s, SDoubleQuotes)),(pos e1)); (EConst(String ("i128", SDoubleQuotes)),(pos e1)) ] (pos e1)]
| EConst (Int (s, Some "i256")) ->
expr "EConst" [mk_enum "Constant" "CInt" [ (EConst(String (s, SDoubleQuotes)),(pos e1)); (EConst(String ("i256", SDoubleQuotes)),(pos e1)) ] (pos e1)]
| EConst (Int (s, Some "i512")) ->
expr "EConst" [mk_enum "Constant" "CInt" [ (EConst(String (s, SDoubleQuotes)),(pos e1)); (EConst(String ("i512", SDoubleQuotes)),(pos e1)) ] (pos e1)]
| _ ->
(ECall ((efield ((efield ((efield ((EConst (Ident "haxe"),p),"macro"),p),"Context"),p),"makeExpr"),p),[e1; to_enc_pos (pos e1)]),p)
end
Expand Down
35 changes: 32 additions & 3 deletions src/typing/typer.ml
Original file line number Diff line number Diff line change
Expand Up @@ -1856,7 +1856,7 @@ and type_expr ?(mode=MGet) ctx (e,p) (with_type:WithType.t) =
let arg_high = EConst (Int (Int64.to_string(high), Some "i64")), p in
let arg_low = EConst (Int (Int64.to_string(low), Some "i64")), p in
let call = ECall (field, [ arg_high; arg_low ]), p in
type_expr ctx call with_type
type_expr ctx call with_type
| "i256" ->
if String.length s > 66 && String.sub s 0 2 = "0x" then raise_typing_error "Invalid hexadecimal integer" p;

Expand All @@ -1866,14 +1866,43 @@ and type_expr ?(mode=MGet) ctx (e,p) (with_type:WithType.t) =
let low_low = Int64.of_string (String.sub s 50 66) in

let ident = EConst (Ident "haxe"), p in
let field = efield ((efield (ident, "Int128"), p), "make"), p in
let field = efield ((efield (ident, "Int256"), p), "make"), p in
let field2 = efield ((efield (ident, "Int128"), p), "make"), p in

let arg_high_high = EConst (Int (Int64.to_string(high_high), Some "i64")), p in
let arg_high_low = EConst (Int (Int64.to_string(high_low), Some "i64")), p in
let arg_low_high = EConst (Int (Int64.to_string(low_high), Some "i64")), p in
let arg_low_low = EConst (Int (Int64.to_string(low_low), Some "i64")), p in

let call = ECall ( field, [ ECall ( field, [ arg_high_high, arg_high_low ] ), ECall ( field, [ arg_low_high, arg_low_low ] ) ]), p in
let call = ECall ( field, [ ECall ( field2, [ arg_high_high, arg_high_low ] ), ECall ( field2, [ arg_low_high, arg_low_low ] ) ]), p in
type_expr ctx call with_type
| "i512" ->
if String.length s > 130 && String.sub s 0 2 = "0x" then raise_typing_error "Invalid hexadecimal integer" p;

let high_high_high = Int64.of_string (String.sub s 2 18) in
let high_high_low = Int64.of_string (String.sub s 20 34) in
let high_low_high = Int64.of_string (String.sub s 34 50) in
let high_low_low = Int64.of_string (String.sub s 50 66) in
let low_high_high = Int64.of_string (String.sub s 66 82) in
let low_high_low = Int64.of_string (String.sub s 82 98) in
let low_low_high = Int64.of_string (String.sub s 98 114) in
let low_low_low = Int64.of_string (String.sub s 114 130) in

let ident = EConst (Ident "haxe"), p in
let field = efield ((efield (ident, "Int512"), p), "make"), p in
let field2 = efield ((efield (ident, "Int256"), p), "make"), p in
let field3 = efield ((efield (ident, "Int128"), p), "make"), p in

let arg_high_high_high = EConst (Int (Int64.to_string(high_high_high), Some "i64")), p in
let arg_high_high_low = EConst (Int (Int64.to_string(high_high_low), Some "i64")), p in
let arg_high_low_high = EConst (Int (Int64.to_string(high_low_high), Some "i64")), p in
let arg_high_low_low = EConst (Int (Int64.to_string(high_low_low), Some "i64")), p in
let arg_low_high_high = EConst (Int (Int64.to_string(low_high_high), Some "i64")), p in
let arg_low_high_low = EConst (Int (Int64.to_string(low_high_low), Some "i64")), p in
let arg_low_low_high = EConst (Int (Int64.to_string(low_low_high), Some "i64")), p in
let arg_low_low_low = EConst (Int (Int64.to_string(low_low_low), Some "i64")), p in

let call = ECall ( field, [ ECall ( field2, [ ECall ( field3, [ arg_high_high_high, arg_high_high_low ] ), ECall ( field3, [ arg_high_low_high, arg_high_low_low ] ) ] ), ECall ( field2, [ ECall ( field3, [ arg_low_high_high, arg_low_high_low ] ), ECall ( field3, [ arg_low_low_high, arg_low_low_low ] ) ] ) ] ), p in
type_expr ctx call with_type
| "u32" ->
let check = ECheckType ((EConst (Int (s, None)), p), (make_ptp_th (mk_type_path ([],"UInt")) p)), p in
Expand Down
2 changes: 1 addition & 1 deletion std/haxe/Int128.hx
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ abstract Int128(__Int128) from __Int128 to __Int128 {
public static inline function toInt64(x:Int128):Int64 {
var res:Int64 = x.low;

// This is a completely different and overflow check because we're using Int128's.
// This is a completely different and overflow check because we're using Int256's.
// It can only be triggered if you input an Int128 as the function parameter.
if ((!isNeg(x) && Int128.isNeg(res)) || (x.high != x.low >> 63))
throw "Overflow";
Expand Down
2 changes: 1 addition & 1 deletion std/haxe/Int128Helper.hx
Original file line number Diff line number Diff line change
Expand Up @@ -157,5 +157,5 @@ class Int128Helper {
The maximum unsigned `Int32` value with the type `Int128`.
This is handy for type comparison.
*/
public static var maxValue32U:Int128 = Int128.make(0, -1);
public static var maxValue32U:Int128 = Int64.make(0, -1);
}
6 changes: 3 additions & 3 deletions std/haxe/Int256.hx
Original file line number Diff line number Diff line change
Expand Up @@ -80,15 +80,15 @@ abstract Int256(__Int256) from __Int256 to __Int256 {

/**
Returns an Int with the value of the Int256 `x`.
Throws an exception if `x` cannot be represented in 32 bits.
Throws an exception if `x` cannot be represented in 64 bits.
**/
public static inline function toInt64(x:Int256):Int64 {
return Int128.toInt64(x.low);
}

/**
Returns an Int64 with the value of the Int256 `x`.
Throws an exception if `x` cannot be represented in 64 bits.
Throws an exception if `x` cannot be represented in 128 bits.
**/
public static inline function toInt128(x:Int256):Int128 {
var res:Int128 = x.low;
Expand Down Expand Up @@ -159,7 +159,7 @@ abstract Int256(__Int256) from __Int256 to __Int256 {
var neg = false;
if (i.isNeg()) {
neg = true;
// i = -i; cannot negate here as --170141183460469231731687303715884105728 = -170141183460469231731687303715884105728
// i = -i; cannot negate here as --57896044618658097711785492504343953926634992332820282019728792003956564819968 = -57896044618658097711785492504343953926634992332820282019728792003956564819968
}
var ten:Int256 = Int256.ofInt(10);
while (i != 0) {
Expand Down
4 changes: 2 additions & 2 deletions std/haxe/Int256Helper.hx
Original file line number Diff line number Diff line change
Expand Up @@ -172,8 +172,8 @@ class Int256Helper {
public static var minValue32:Int256 = ~maxValue32;

/**
The maximum unsigned `Int32` value with the type `Int128`.
The maximum unsigned `Int32` value with the type `Int256`.
This is handy for type comparison.
*/
public static var maxValue32U:Int256 = Int128.make(0, -1);
public static var maxValue32U:Int256 = Int64.make(0, -1);
}
Loading

0 comments on commit 7609332

Please sign in to comment.