Skip to content

Commit 970580d

Browse files
committed
Implements a few improvements to the code generation of if-expressions.
1 parent 1818c7a commit 970580d

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

67 files changed

+784
-918
lines changed

src/core/passes.ml

Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -249,6 +249,21 @@ module Location = struct
249249
end
250250

251251
module IfExpressions = struct
252+
(* Check if an expression is simple enough to remain as a ternary operator *)
253+
let rec isSimpleValue (e : exp) =
254+
match e.e with
255+
| EUnit | EBool _ | EInt _ | EReal _ | EFixed _ | EString _ -> true
256+
| EId _ | EMember _ -> true
257+
| EUnOp (_, e) -> isSimpleValue e
258+
| _ -> false
259+
260+
261+
let isSimpleIf (e : exp) =
262+
match e.e with
263+
| EIf { cond; then_; else_ } -> isSimpleValue cond && isSimpleValue then_ && isSimpleValue else_
264+
| _ -> false
265+
266+
252267
let stmt_env =
253268
Mapper.makeEnv
254269
@@ fun env (s : stmt) ->
@@ -291,6 +306,8 @@ module IfExpressions = struct
291306
then_
292307
else
293308
else_ )
309+
(* Preserve simple if-expressions as ternary operators *)
310+
| { e = EIf _; _ } when isSimpleIf e -> state, e
294311
(* Bind if-expressions to a variable in function context *)
295312
| { e = EIf _; t; loc } when (not env.in_if_exp) && (not env.bound_if) && env.in_function ->
296313
let tick = getTick env state in
@@ -929,12 +946,30 @@ module StrengthReduction = struct
929946
| TReal -> reapply state, C.ereal ~loc:e.loc 0.0
930947
| TFix16 -> reapply state, C.efix16 ~loc:e.loc 0.0
931948
| _ -> state, e)
949+
(* x * -1 -> -x *)
950+
| { e = EOp (OpMul, e1, { e = EInt -1; _ }); _ } -> reapply state, { e with e = EUnOp (UOpNeg, e1) }
951+
| { e = EOp (OpMul, { e = EInt -1; _ }, e2); _ } -> reapply state, { e with e = EUnOp (UOpNeg, e2) }
952+
(* x % 1 -> 0 *)
953+
| { e = EOp (OpMod, _, { e = EInt 1; _ }); loc; _ } -> reapply state, C.eint ~loc 0
954+
(* NOTE: x % 2^n -> x & (2^n - 1) optimization removed because Lua 5.1/LuaJIT
955+
doesn't support native bitwise operators, and modulo works correctly *)
956+
(* 0 / x -> 0 *)
957+
| { e = EOp (OpDiv, { e = EInt 0; _ }, _); loc; _ } -> reapply state, C.eint ~loc 0
958+
(* 0 - x -> -x *)
959+
| { e = EOp (OpSub, { e = EInt 0; _ }, e2); _ } -> reapply state, { e with e = EUnOp (UOpNeg, e2) }
932960
(* ========== FLOATING POINT ARITHMETIC OPTIMIZATIONS ========== *)
933961
(* x * 0.0 -> 0.0, x * 1.0 -> x *)
934962
| { e = EOp (OpMul, _, { e = EReal 0.0; _ }); _ } | { e = EOp (OpMul, { e = EReal 0.0; _ }, _); _ } ->
935963
reapply state, { e with e = EReal 0.0 }
936964
| { e = EOp (OpMul, e1, { e = EReal 1.0; _ }); _ } -> reapply state, e1
937965
| { e = EOp (OpMul, { e = EReal 1.0; _ }, e2); _ } -> reapply state, e2
966+
(* x * -1.0 -> -x *)
967+
| { e = EOp (OpMul, e1, { e = EReal -1.0; _ }); _ } -> reapply state, { e with e = EUnOp (UOpNeg, e1) }
968+
| { e = EOp (OpMul, { e = EReal -1.0; _ }, e2); _ } -> reapply state, { e with e = EUnOp (UOpNeg, e2) }
969+
(* 0.0 / x -> 0.0 *)
970+
| { e = EOp (OpDiv, { e = EReal 0.0; _ }, _); loc; _ } -> reapply state, C.ereal ~loc 0.0
971+
(* 0.0 - x -> -x *)
972+
| { e = EOp (OpSub, { e = EReal 0.0; _ }, e2); _ } -> reapply state, { e with e = EUnOp (UOpNeg, e2) }
938973
(* Removed x * 2.0 -> x + x transformation as it interferes with constant folding *)
939974
(* Removed x * 0.5 <-> x / 2.0 transformations as they create cycles with other passes *)
940975
(* Removed problematic power-of-2 real multiplication transformation *)
@@ -945,6 +980,18 @@ module StrengthReduction = struct
945980
| { e = EOp (OpMul, e1, { e = EFixed 1.0; _ }); _ } -> reapply state, e1
946981
| { e = EOp (OpMul, { e = EFixed 1.0; _ }, e2); _ } ->
947982
reapply state, e2 (* Removed x * 2.0 -> x + x for fixed point as it interferes with constant folding *)
983+
(* x * -1.0 -> -x (fixed) *)
984+
| { e = EOp (OpMul, e1, { e = EFixed -1.0; _ }); _ } -> reapply state, { e with e = EUnOp (UOpNeg, e1) }
985+
| { e = EOp (OpMul, { e = EFixed -1.0; _ }, e2); _ } -> reapply state, { e with e = EUnOp (UOpNeg, e2) }
986+
(* 0.0 / x -> 0.0 (fixed) *)
987+
| { e = EOp (OpDiv, { e = EFixed 0.0; _ }, _); loc; _ } -> reapply state, C.efix16 ~loc 0.0
988+
(* 0.0 - x -> -x (fixed) *)
989+
| { e = EOp (OpSub, { e = EFixed 0.0; _ }, e2); _ } -> reapply state, { e with e = EUnOp (UOpNeg, e2) }
990+
(* ========== DIVISION BY 1 OPTIMIZATIONS ========== *)
991+
(* x / 1 -> x (for all numeric types) *)
992+
| { e = EOp (OpDiv, e1, { e = EInt 1; _ }); _ } -> reapply state, e1
993+
| { e = EOp (OpDiv, e1, { e = EReal 1.0; _ }); _ } -> reapply state, e1
994+
| { e = EOp (OpDiv, e1, { e = EFixed 1.0; _ }); _ } -> reapply state, e1
948995
(* ========== FUNCTION CALL OPTIMIZATIONS ========== *)
949996
(* pow(x, 2) -> x * x *)
950997
| { e = ECall { path = "pow"; args = [ x; { e = EReal 2.0; _ } ] }; _ } ->
@@ -975,6 +1022,13 @@ module StrengthReduction = struct
9751022
reapply state, { e with e = EOp (OpDiv, C.ereal ~loc 1.0, x) }
9761023
| { e = ECall { path = "pow"; args = [ x; { e = EInt -1; _ } ] }; loc; _ } ->
9771024
reapply state, { e with e = EOp (OpDiv, C.ereal ~loc 1.0, x) }
1025+
(* pow(x, -2) -> 1.0 / (x * x) *)
1026+
| { e = ECall { path = "pow"; args = [ x; { e = EReal -2.0; _ } ] }; loc; _ } ->
1027+
let x_squared = { e with e = EOp (OpMul, x, x) } in
1028+
reapply state, { e with e = EOp (OpDiv, C.ereal ~loc 1.0, x_squared) }
1029+
| { e = ECall { path = "pow"; args = [ x; { e = EInt -2; _ } ] }; loc; _ } ->
1030+
let x_squared = { e with e = EOp (OpMul, x, x) } in
1031+
reapply state, { e with e = EOp (OpDiv, C.ereal ~loc 1.0, x_squared) }
9781032
(* pow(x, 1) -> x *)
9791033
| { e = ECall { path = "pow"; args = [ x; { e = EReal 1.0; _ } ] }; _ } -> reapply state, x
9801034
| { e = ECall { path = "pow"; args = [ x; { e = EInt 1; _ } ] }; _ } -> reapply state, x
@@ -1013,6 +1067,46 @@ module StrengthReduction = struct
10131067
(* x << 0 -> x, x >> 0 -> x *)
10141068
| { e = EOp (OpLsh, e1, { e = EInt 0; _ }); _ } -> reapply state, e1
10151069
| { e = EOp (OpRsh, e1, { e = EInt 0; _ }); _ } -> reapply state, e1
1070+
(* x & x -> x, x | x -> x *)
1071+
| { e = EOp (OpBand, e1, e2); _ } when Compare.exp e1 e2 = 0 -> reapply state, e1
1072+
| { e = EOp (OpBor, e1, e2); _ } when Compare.exp e1 e2 = 0 -> reapply state, e1
1073+
(* x & -1 -> x (all bits set) *)
1074+
| { e = EOp (OpBand, e1, { e = EInt -1; _ }); _ } -> reapply state, e1
1075+
| { e = EOp (OpBand, { e = EInt -1; _ }, e2); _ } -> reapply state, e2
1076+
(* ========== NEGATION OPTIMIZATIONS ========== *)
1077+
(* -(-x) -> x *)
1078+
| { e = EUnOp (UOpNeg, { e = EUnOp (UOpNeg, x); _ }); _ } -> reapply state, x
1079+
(* not(not(x)) -> x *)
1080+
| { e = EUnOp (UOpNot, { e = EUnOp (UOpNot, x); _ }); _ } -> reapply state, x
1081+
(* ========== BOOLEAN LOGIC OPTIMIZATIONS ========== *)
1082+
(* x && true -> x *)
1083+
| { e = EOp (OpLand, e1, { e = EBool true; _ }); _ } -> reapply state, e1
1084+
| { e = EOp (OpLand, { e = EBool true; _ }, e2); _ } -> reapply state, e2
1085+
(* x && false -> false *)
1086+
| { e = EOp (OpLand, _, { e = EBool false; loc; _ }); _ } -> reapply state, C.ebool ~loc false
1087+
| { e = EOp (OpLand, { e = EBool false; loc; _ }, _); _ } -> reapply state, C.ebool ~loc false
1088+
(* x || false -> x *)
1089+
| { e = EOp (OpLor, e1, { e = EBool false; _ }); _ } -> reapply state, e1
1090+
| { e = EOp (OpLor, { e = EBool false; _ }, e2); _ } -> reapply state, e2
1091+
(* x || true -> true *)
1092+
| { e = EOp (OpLor, _, { e = EBool true; loc; _ }); _ } -> reapply state, C.ebool ~loc true
1093+
| { e = EOp (OpLor, { e = EBool true; loc; _ }, _); _ } -> reapply state, C.ebool ~loc true
1094+
(* ========== COMPARISON SELF-IDENTITIES ========== *)
1095+
(* x == x -> true (int only, floats have NaN) *)
1096+
| { e = EOp (OpEq, e1, e2); loc; _ } when Compare.exp e1 e2 = 0 && e1.t.t = TInt -> reapply state, C.ebool ~loc true
1097+
(* x != x -> false (int only) *)
1098+
| { e = EOp (OpNe, e1, e2); loc; _ } when Compare.exp e1 e2 = 0 && e1.t.t = TInt ->
1099+
reapply state, C.ebool ~loc false
1100+
(* x < x -> false, x > x -> false *)
1101+
| { e = EOp (OpLt, e1, e2); loc; _ } when Compare.exp e1 e2 = 0 -> reapply state, C.ebool ~loc false
1102+
| { e = EOp (OpGt, e1, e2); loc; _ } when Compare.exp e1 e2 = 0 -> reapply state, C.ebool ~loc false
1103+
(* x <= x -> true, x >= x -> true (int only) *)
1104+
| { e = EOp (OpLe, e1, e2); loc; _ } when Compare.exp e1 e2 = 0 && e1.t.t = TInt -> reapply state, C.ebool ~loc true
1105+
| { e = EOp (OpGe, e1, e2); loc; _ } when Compare.exp e1 e2 = 0 && e1.t.t = TInt -> reapply state, C.ebool ~loc true
1106+
(* ========== MIN/MAX OPTIMIZATIONS ========== *)
1107+
(* min(x, x) -> x, max(x, x) -> x *)
1108+
| { e = ECall { path = "min"; args = [ x1; x2 ] }; _ } when Compare.exp x1 x2 = 0 -> reapply state, x1
1109+
| { e = ECall { path = "max"; args = [ x1; x2 ] }; _ } when Compare.exp x1 x2 = 0 -> reapply state, x1
10161110
(* No optimization found *)
10171111
| _ -> state, e
10181112

src/generators/lua.ml

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -126,8 +126,10 @@ function list_clear(t) for k in pairs(t) do t[k] = nil end end
126126

127127
let rec isValueOrIf (e : exp) =
128128
match e.e with
129-
| EUnit | EBool _ | EInt _ | EReal _ | EString _ | EId _ | EMember _ -> true
129+
| EUnit | EBool _ | EInt _ | EReal _ | EString _ | EId _ | EMember _ | EFixed _ -> true
130130
| EUnOp (_, e) -> isValueOrIf e
131+
| EOp (_, e1, e2) -> isValueOrIf e1 && isValueOrIf e2
132+
| EIndex { e; index } -> isValueOrIf e && isValueOrIf index
131133
| EIf { then_; else_; _ } -> isValueOrIf then_ && isValueOrIf else_
132134
| _ -> false
133135

@@ -182,7 +184,7 @@ let rec print_exp e =
182184
| EIndex { e; index } ->
183185
let e = print_exp e in
184186
let index = print_exp index in
185-
{%pla|<#e#>[<#index#> + 1]|}
187+
{%pla|get(<#e#>, <#index#>)|}
186188
| EArray l -> Pla.wrap (Pla.string "{") (Pla.string "}") (Pla.map_sep Pla.commaspace print_exp l)
187189
| ECall { path; args } -> (
188190
(* Use optimized functions when available *)
@@ -225,8 +227,8 @@ let rec print_exp e =
225227
| "list_get", [ l; i ] ->
226228
let l = print_exp l in
227229
let i = print_exp i in
228-
(* Lua is 1-based *)
229-
{%pla|<#l#>[<#i#> + 1]|}
230+
(* Use get() helper for 1-based indexing *)
231+
{%pla|get(<#l#>, <#i#>)|}
230232
| "list_set", [ l; i; v ] ->
231233
let l = print_exp l in
232234
let i = print_exp i in

test/code/ConstSpecialization.lua.base

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -264,7 +264,7 @@ function ConstSpecialization_setMatrix2(m, row, col, value)
264264
end
265265

266266
function ConstSpecialization_getMatrix2(m, row, col)
267-
return m[(row + lshift(col, 1)) + 1]
267+
return get(m, (row + lshift(col, 1)))
268268
end
269269

270270
function ConstSpecialization_test_matrix_mutation(m, x)

test/code/FixedAndFloat.lua.base

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -112,57 +112,57 @@ end
112112
FixedAndFloat_take_fix_return_fixed_c0 = {};
113113
FixedAndFloat_take_fix_return_fixed_c1 = {};
114114
function FixedAndFloat_take_fix_return_fixed_raw_c0(index)
115-
return FixedAndFloat_take_fix_return_fixed_c0[index + 1]
115+
return get(FixedAndFloat_take_fix_return_fixed_c0, index)
116116
end
117117

118118
function FixedAndFloat_take_fix_return_fixed_raw_c1(index)
119-
return FixedAndFloat_take_fix_return_fixed_c1[index + 1]
119+
return get(FixedAndFloat_take_fix_return_fixed_c1, index)
120120
end
121121

122122
function FixedAndFloat_take_fix_return_fixed(x)
123123
local value = clip((x * 32.0), 0.0, 32.0)
124124
local index = int(value)
125125
local decimal = (value - floor(value))
126-
return (FixedAndFloat_take_fix_return_fixed_c0[index + 1] + (FixedAndFloat_take_fix_return_fixed_c1[index + 1] * decimal))
126+
return (get(FixedAndFloat_take_fix_return_fixed_c0, index) + (get(FixedAndFloat_take_fix_return_fixed_c1, index) * decimal))
127127
end
128128

129129
FixedAndFloat_take_fix_return_real_c0 = {};
130130
FixedAndFloat_take_fix_return_real_c1 = {};
131131
FixedAndFloat_take_fix_return_real_c2 = {};
132132
function FixedAndFloat_take_fix_return_real_raw_c0(index)
133-
return FixedAndFloat_take_fix_return_real_c0[index + 1]
133+
return get(FixedAndFloat_take_fix_return_real_c0, index)
134134
end
135135

136136
function FixedAndFloat_take_fix_return_real_raw_c1(index)
137-
return FixedAndFloat_take_fix_return_real_c1[index + 1]
137+
return get(FixedAndFloat_take_fix_return_real_c1, index)
138138
end
139139

140140
function FixedAndFloat_take_fix_return_real_raw_c2(index)
141-
return FixedAndFloat_take_fix_return_real_c2[index + 1]
141+
return get(FixedAndFloat_take_fix_return_real_c2, index)
142142
end
143143

144144
function FixedAndFloat_take_fix_return_real(x)
145145
local index = clip(fix_to_int((x * 31.0)), 0, 31)
146-
return (FixedAndFloat_take_fix_return_real_c0[index + 1] + (fix_to_float(x) * (FixedAndFloat_take_fix_return_real_c1[index + 1] + (FixedAndFloat_take_fix_return_real_c2[index + 1] * fix_to_float(x)))))
146+
return (get(FixedAndFloat_take_fix_return_real_c0, index) + (fix_to_float(x) * (get(FixedAndFloat_take_fix_return_real_c1, index) + (get(FixedAndFloat_take_fix_return_real_c2, index) * fix_to_float(x)))))
147147
end
148148

149149
FixedAndFloat_take_real_return_fixed_c0 = {};
150150
FixedAndFloat_take_real_return_fixed_c1 = {};
151151
FixedAndFloat_take_real_return_fixed_c2 = {};
152152
function FixedAndFloat_take_real_return_fixed_raw_c0(index)
153-
return FixedAndFloat_take_real_return_fixed_c0[index + 1]
153+
return get(FixedAndFloat_take_real_return_fixed_c0, index)
154154
end
155155

156156
function FixedAndFloat_take_real_return_fixed_raw_c1(index)
157-
return FixedAndFloat_take_real_return_fixed_c1[index + 1]
157+
return get(FixedAndFloat_take_real_return_fixed_c1, index)
158158
end
159159

160160
function FixedAndFloat_take_real_return_fixed_raw_c2(index)
161-
return FixedAndFloat_take_real_return_fixed_c2[index + 1]
161+
return get(FixedAndFloat_take_real_return_fixed_c2, index)
162162
end
163163

164164
function FixedAndFloat_take_real_return_fixed(x)
165165
local index = clip(math.floor((x * 31.0)), 0, 31)
166-
return (FixedAndFloat_take_real_return_fixed_c0[index + 1] + (float_to_fix(x) * (FixedAndFloat_take_real_return_fixed_c1[index + 1] + (FixedAndFloat_take_real_return_fixed_c2[index + 1] * float_to_fix(x)))))
166+
return (get(FixedAndFloat_take_real_return_fixed_c0, index) + (float_to_fix(x) * (get(FixedAndFloat_take_real_return_fixed_c1, index) + (get(FixedAndFloat_take_real_return_fixed_c2, index) * float_to_fix(x)))))
167167
end
168168

test/code/GenericArrays.lua.base

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,7 @@ function GenericArrays_sum(data)
9494
local i__1 = 0
9595
while (i__1 < size(data)) do
9696
do
97-
total = (total + data[i__1 + 1])
97+
total = (total + get(data, i__1))
9898
i__1 = (1 + i__1)
9999
end
100100
end

test/code/InstanceArray.lua.base

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -126,7 +126,7 @@ function InstanceArray_test1(_ctx)
126126
local i__1 = 0
127127
while (i__1 < 4) do
128128
do
129-
sum = (sum + InstanceArray_counter(_ctx.instances[i__1 + 1]))
129+
sum = (sum + InstanceArray_counter(get(_ctx.instances, i__1)))
130130
i__1 = (1 + i__1)
131131
end
132132
end

test/code/SaveState.lua.base

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -166,7 +166,7 @@ function SaveState_main_type_serialize_data(buffer, index, _ctx)
166166
local i_0 = 0
167167
while (i_0 < 3) do
168168
do
169-
index = SaveState_point_serialize_data(buffer, index, _ctx.point_array[i_0 + 1])
169+
index = SaveState_point_serialize_data(buffer, index, get(_ctx.point_array, i_0))
170170
i_0 = (1 + i_0)
171171
end
172172
end
@@ -261,7 +261,7 @@ function SaveState_main_type_deserialize_data(buffer, type_descr, index, _ctx)
261261
local i_5 = 0
262262
while (i_5 < 3) do
263263
do
264-
SaveState_point_deserialize_data(buffer, field_descr_4, field_index, _ctx.point_array[i_5 + 1])
264+
SaveState_point_deserialize_data(buffer, field_descr_4, field_index, get(_ctx.point_array, i_5))
265265
i_5 = (1 + i_5)
266266
field_index = next_object(buffer, field_index)
267267
end

test/code/Tables.lua.base

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -93,66 +93,66 @@ Tables_sineTable1_c0 = {};
9393
Tables_sineTable1_c1 = {};
9494
Tables_sineTable1_c2 = {};
9595
function Tables_sineTable1_raw_c0(index)
96-
return Tables_sineTable1_c0[index + 1]
96+
return get(Tables_sineTable1_c0, index)
9797
end
9898

9999
function Tables_sineTable1_raw_c1(index)
100-
return Tables_sineTable1_c1[index + 1]
100+
return get(Tables_sineTable1_c1, index)
101101
end
102102

103103
function Tables_sineTable1_raw_c2(index)
104-
return Tables_sineTable1_c2[index + 1]
104+
return get(Tables_sineTable1_c2, index)
105105
end
106106

107107
function Tables_sineTable1(x)
108108
local index = clip(math.floor((x * 31.0)), 0, 31)
109-
return (Tables_sineTable1_c0[index + 1] + (x * (Tables_sineTable1_c1[index + 1] + (Tables_sineTable1_c2[index + 1] * x))))
109+
return (get(Tables_sineTable1_c0, index) + (x * (get(Tables_sineTable1_c1, index) + (get(Tables_sineTable1_c2, index) * x))))
110110
end
111111

112112
Tables_sineTable2_c0 = {};
113113
Tables_sineTable2_c1 = {};
114114
function Tables_sineTable2_raw_c0(index)
115-
return Tables_sineTable2_c0[index + 1]
115+
return get(Tables_sineTable2_c0, index)
116116
end
117117

118118
function Tables_sineTable2_raw_c1(index)
119-
return Tables_sineTable2_c1[index + 1]
119+
return get(Tables_sineTable2_c1, index)
120120
end
121121

122122
function Tables_sineTable2(x)
123123
local index = clip(math.floor((x * 31.0)), 0, 31)
124-
return (Tables_sineTable2_c0[index + 1] + (x * Tables_sineTable2_c1[index + 1]))
124+
return (get(Tables_sineTable2_c0, index) + (x * get(Tables_sineTable2_c1, index)))
125125
end
126126

127127
Tables_sineTable3_c0 = {};
128128
Tables_sineTable3_c1 = {};
129129
function Tables_sineTable3_raw_c0(index)
130-
return Tables_sineTable3_c0[index + 1]
130+
return get(Tables_sineTable3_c0, index)
131131
end
132132

133133
function Tables_sineTable3_raw_c1(index)
134-
return Tables_sineTable3_c1[index + 1]
134+
return get(Tables_sineTable3_c1, index)
135135
end
136136

137137
function Tables_sineTable3(x)
138138
local value = clip((x * 32.0), 0.0, 32.0)
139139
local index = int(value)
140140
local decimal = (value - floor(value))
141-
return (Tables_sineTable3_c0[index + 1] + (Tables_sineTable3_c1[index + 1] * decimal))
141+
return (get(Tables_sineTable3_c0, index) + (get(Tables_sineTable3_c1, index) * decimal))
142142
end
143143

144144
Tables_power2_table = {};
145145
function Tables_power2(x)
146-
return Tables_power2_table[(int_clip(x, -4, 4) + 4) + 1]
146+
return get(Tables_power2_table, (int_clip(x, -4, 4) + 4))
147147
end
148148

149149
Tables_square_table = {};
150150
function Tables_square(x)
151-
return Tables_square_table[(int_clip(x, -4, 4) + 4) + 1]
151+
return get(Tables_square_table, (int_clip(x, -4, 4) + 4))
152152
end
153153

154154
Tables_square16_table = {};
155155
function Tables_square16(x)
156-
return Tables_square16_table[(int_clip(x, -4, 4) + 4) + 1]
156+
return get(Tables_square16_table, (int_clip(x, -4, 4) + 4))
157157
end
158158

0 commit comments

Comments
 (0)