Skip to content

Commit 41a3b6b

Browse files
committed
feat!: add GenTypes module with T enum for GIAC expression types
BREAKING CHANGE: Legacy GIAC_* constants removed - Add src/gen_types.jl with GenTypes submodule and T enum - T enum has all 22 GIAC types matching C++ gen_unary_types - giac_type() now returns T enum instead of Int32 - Remove GIAC_INT, GIAC_DOUBLE, GIAC_VECT, etc. constants - Remove GIAC_SEQ_VECT, GIAC_SET_VECT, GIAC_LIST_VECT subtype constants - Update introspection.jl, conversion.jl to use T enum - Add test/test_gen_types.jl with 70 tests - Update test_output_handling.jl for new enum API - Update documentation for GenTypes usage Migration: Use `using Giac.GenTypes: T, INT, VECT, SYMB, ...` instead of GIAC_INT, GIAC_VECT, GIAC_SYMB, etc.
1 parent b527e07 commit 41a3b6b

10 files changed

Lines changed: 404 additions & 227 deletions

File tree

docs/src/api/core.md

Lines changed: 34 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -274,29 +274,41 @@ Giac.is_string
274274
Giac.is_boolean
275275
```
276276

277-
### Type Constants
277+
### Type Enum (GenTypes)
278278

279-
| Constant | Description |
280-
|----------|-------------|
281-
| `GIAC_INT` | Machine integer (Int64) |
282-
| `GIAC_DOUBLE` | Double-precision float (Float64) |
283-
| `GIAC_ZINT` | Arbitrary-precision integer (BigInt) |
284-
| `GIAC_REAL` | Extended precision real |
285-
| `GIAC_CPLX` | Complex number |
286-
| `GIAC_VECT` | Vector/list/sequence |
287-
| `GIAC_SYMB` | Symbolic expression |
288-
| `GIAC_IDNT` | Identifier/variable |
289-
| `GIAC_STRNG` | String value |
290-
| `GIAC_FRAC` | Rational fraction |
291-
| `GIAC_FUNC` | Function reference |
292-
293-
### Vector Subtype Constants
294-
295-
| Constant | Description |
296-
|----------|-------------|
297-
| `GIAC_SEQ_VECT` | Sequence (function arguments) |
298-
| `GIAC_SET_VECT` | Set (unordered collection) |
299-
| `GIAC_LIST_VECT` | List (ordered collection) |
279+
GIAC expression types are available via the `Giac.GenTypes` module with the `T` enum:
280+
281+
```julia
282+
using Giac.GenTypes: T, INT, DOUBLE, VECT, SYMB
283+
284+
giac_type(expr) == INT # Check if expression is an integer
285+
giac_type(expr) == VECT # Check if expression is a vector
286+
```
287+
288+
| Enum Value | Int | Description |
289+
|------------|-----|-------------|
290+
| `INT` | 0 | Machine integer (Int64) |
291+
| `DOUBLE` | 1 | Double-precision float (Float64) |
292+
| `ZINT` | 2 | Arbitrary-precision integer (BigInt) |
293+
| `REAL` | 3 | Extended precision real |
294+
| `CPLX` | 4 | Complex number |
295+
| `POLY` | 5 | Polynomial |
296+
| `IDNT` | 6 | Identifier/variable |
297+
| `VECT` | 7 | Vector/list/sequence |
298+
| `SYMB` | 8 | Symbolic expression |
299+
| `SPOL1` | 9 | Sparse polynomial |
300+
| `FRAC` | 10 | Rational fraction |
301+
| `EXT` | 11 | Algebraic extension |
302+
| `STRNG` | 12 | String value |
303+
| `FUNC` | 13 | Function reference |
304+
| `ROOT` | 14 | Polynomial root |
305+
| `MOD` | 15 | Modular arithmetic |
306+
| `USER` | 16 | User-defined type |
307+
| `MAP` | 17 | Map/dictionary |
308+
| `EQW` | 18 | Equation writer data |
309+
| `GROB` | 19 | Graphic object |
310+
| `POINTER` | 20 | Raw pointer |
311+
| `FLOAT` | 21 | Float value |
300312

301313
## Component Access
302314

docs/src/domains/signal/continuous_transforms.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -119,5 +119,5 @@ invoke_cmd(:ilaplace, 1/(s+a), s, t)
119119
## See Also
120120

121121
- [Discrete-Time Transforms](discrete_transforms.md) - Z-transform and inverse Z-transform
122-
- [Calculus Operations](../math/calculus.md) - Integration, differentiation, and limits
122+
- [Calculus Operations](../../mathematics/calculus.md) - Integration, differentiation, and limits
123123
- [GIAC Laplace Documentation](https://www-fourier.univ-grenoble-alpes.fr/~parisse/giac/doc/en/cascmd_en/cascmd_en466.html) - Official GIAC documentation

docs/src/domains/signal/discrete_transforms.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -112,5 +112,5 @@ invoke_cmd(:invztrans, z/(z-a), z, n)
112112
## See Also
113113

114114
- [Continuous-Time Transforms](continuous_transforms.md) - Laplace transforms for continuous-time signals
115-
- [Calculus Operations](../math/calculus.md) - Integration, differentiation, and limits
115+
- [Calculus Operations](../../mathematics/calculus.md) - Integration, differentiation, and limits
116116
- [GIAC Z-Transform Documentation](https://www-fourier.univ-grenoble-alpes.fr/~parisse/giac/doc/en/cascmd_en/cascmd_en467.html) - Official GIAC documentation

src/Giac.jl

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,9 @@ include("macros.jl")
7676
include("tables.jl")
7777
include("substitute.jl")
7878

79+
# GenTypes module - Scoped enum for GIAC types (041-scoped-type-enum)
80+
include("gen_types.jl")
81+
7982
# Output handling (029-output-handling)
8083
include("introspection.jl")
8184
include("conversion.jl")
@@ -116,10 +119,8 @@ export commands_table, clear_commands_cache!, CommandsTable
116119
# Substitute function (028-substitute-mechanism)
117120
export substitute
118121

119-
# Type introspection (029-output-handling)
120-
export GIAC_INT, GIAC_DOUBLE, GIAC_ZINT, GIAC_REAL, GIAC_CPLX, GIAC_VECT
121-
export GIAC_SYMB, GIAC_IDNT, GIAC_STRNG, GIAC_FRAC, GIAC_FUNC
122-
export GIAC_SEQ_VECT, GIAC_SET_VECT, GIAC_LIST_VECT
122+
# Type introspection (029-output-handling, 041-scoped-type-enum)
123+
# Legacy GIAC_* constants removed - use Giac.GenTypes: T, INT, DOUBLE, etc.
123124
export giac_type, subtype
124125
export is_integer, is_numeric, is_vector, is_symbolic, is_identifier
125126
export is_fraction, is_complex, is_string, is_boolean

src/conversion.jl

Lines changed: 35 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,9 @@
22
# Provides extended to_julia functionality with vector/complex/fraction support
33
#
44
# Part of feature 029-output-handling, 030-to-julia-bool-conversion
5+
# Updated for 041-scoped-type-enum: Uses GenTypes.T enum instead of GIAC_* constants
6+
7+
using .GenTypes: T, INT, DOUBLE, ZINT, REAL, CPLX, VECT, SYMB, IDNT, FRAC, STRNG, FUNC
58

69
# ============================================================================
710
# Extended to_julia Conversion
@@ -16,14 +19,14 @@ Recursively convert a GIAC expression to native Julia types.
1619
| GIAC Type | Julia Return Type |
1720
|-----------|-------------------|
1821
| Boolean (`true`/`false`) | `Bool` |
19-
| `GIAC_INT` | `Int64` |
20-
| `GIAC_ZINT` | `BigInt` |
21-
| `GIAC_DOUBLE`, `GIAC_REAL` | `Float64` |
22-
| `GIAC_FRAC` | `Rational{Int64}` or `Rational{BigInt}` |
23-
| `GIAC_CPLX` | `Complex{T}` (T promoted from parts) |
24-
| `GIAC_VECT` | `Vector{T}` (T narrowed from elements) |
25-
| `GIAC_STRNG` | `String` |
26-
| `GIAC_SYMB`, `GIAC_IDNT`, `GIAC_FUNC` | `GiacExpr` (unchanged) |
22+
| `INT` | `Int64` |
23+
| `ZINT` | `BigInt` |
24+
| `DOUBLE`, `REAL` | `Float64` |
25+
| `FRAC` | `Rational{Int64}` or `Rational{BigInt}` |
26+
| `CPLX` | `Complex{T}` (T promoted from parts) |
27+
| `VECT` | `Vector{T}` (T narrowed from elements) |
28+
| `STRNG` | `String` |
29+
| `SYMB`, `IDNT`, `FUNC` | `GiacExpr` (unchanged) |
2730
2831
Note: GIAC represents booleans as integers internally, but `to_julia` detects them
2932
via their string representation ("true"/"false") and returns Julia `Bool` values.
@@ -69,27 +72,27 @@ function to_julia(g::GiacExpr)
6972
end
7073

7174
# Internal dispatcher based on type constant
72-
function _convert_by_type(g::GiacExpr, t::Int32)
73-
if t == GIAC_INT
75+
function _convert_by_type(g::GiacExpr, t::T)
76+
if t == INT
7477
# Check for boolean before integer conversion (030-to-julia-bool-conversion)
7578
if is_boolean(g)
7679
return _convert_to_bool(g)
7780
end
7881
return _convert_to_int64(g)
79-
elseif t == GIAC_DOUBLE || t == GIAC_REAL
82+
elseif t == DOUBLE || t == REAL
8083
return _convert_to_float64(g)
81-
elseif t == GIAC_ZINT
84+
elseif t == ZINT
8285
return _convert_to_bigint(g)
83-
elseif t == GIAC_FRAC
86+
elseif t == FRAC
8487
return _convert_to_rational(g)
85-
elseif t == GIAC_CPLX
88+
elseif t == CPLX
8689
return _convert_to_complex(g)
87-
elseif t == GIAC_VECT
90+
elseif t == VECT
8891
return _convert_to_vector(g)
89-
elseif t == GIAC_STRNG
92+
elseif t == STRNG
9093
return _convert_to_string(g)
9194
else
92-
# Symbolic types (GIAC_SYMB, GIAC_IDNT, GIAC_FUNC) - return unchanged
95+
# Symbolic types (SYMB, IDNT, FUNC) - return unchanged
9396
return g
9497
end
9598
end
@@ -143,7 +146,7 @@ function _convert_to_rational(g::GiacExpr)
143146
den_type = giac_type(den_expr)
144147

145148
# Check if either is BigInt (ZINT)
146-
if num_type == GIAC_ZINT || den_type == GIAC_ZINT
149+
if num_type == ZINT || den_type == ZINT
147150
num = to_julia(num_expr)::Union{Int64, BigInt}
148151
den = to_julia(den_expr)::Union{Int64, BigInt}
149152
return Rational{BigInt}(BigInt(num), BigInt(den))
@@ -210,7 +213,7 @@ Check if a GiacExpr can be fully converted to native Julia types
210213
"""
211214
function _can_convert_fully(g::GiacExpr)::Bool
212215
t = giac_type(g)
213-
if t == GIAC_VECT
216+
if t == VECT
214217
# For vectors, recursively check all elements
215218
n = _vector_length(g)
216219
for i in 1:n
@@ -220,11 +223,11 @@ function _can_convert_fully(g::GiacExpr)::Bool
220223
end
221224
end
222225
return true
223-
elseif t in (GIAC_INT, GIAC_DOUBLE, GIAC_REAL, GIAC_ZINT, GIAC_FRAC, GIAC_CPLX, GIAC_STRNG)
226+
elseif t in (INT, DOUBLE, REAL, ZINT, FRAC, CPLX, STRNG)
224227
# Numeric and string types can be fully converted
225228
return true
226229
else
227-
# GIAC_SYMB, GIAC_IDNT, GIAC_FUNC - symbolic, cannot fully convert
230+
# SYMB, IDNT, FUNC - symbolic, cannot fully convert
228231
return false
229232
end
230233
end
@@ -302,9 +305,9 @@ Convert an integer GiacExpr to Int64.
302305
"""
303306
function Base.convert(::Type{Int64}, g::GiacExpr)::Int64
304307
t = giac_type(g)
305-
if t == GIAC_INT
308+
if t == INT
306309
return _convert_to_int64(g)
307-
elseif t == GIAC_ZINT
310+
elseif t == ZINT
308311
big = _convert_to_bigint(g)
309312
if big > typemax(Int64) || big < typemin(Int64)
310313
throw(InexactError(:convert, Int64, big))
@@ -322,13 +325,13 @@ Convert a numeric GiacExpr to Float64.
322325
"""
323326
function Base.convert(::Type{Float64}, g::GiacExpr)::Float64
324327
t = giac_type(g)
325-
if t == GIAC_DOUBLE || t == GIAC_REAL
328+
if t == DOUBLE || t == REAL
326329
return _convert_to_float64(g)
327-
elseif t == GIAC_INT
330+
elseif t == INT
328331
return Float64(_convert_to_int64(g))
329-
elseif t == GIAC_ZINT
332+
elseif t == ZINT
330333
return Float64(_convert_to_bigint(g))
331-
elseif t == GIAC_FRAC
334+
elseif t == FRAC
332335
r = _convert_to_rational(g)
333336
return Float64(r)
334337
else
@@ -355,11 +358,11 @@ Convert a fraction or integer GiacExpr to a Rational.
355358
"""
356359
function Base.convert(::Type{Rational}, g::GiacExpr)::Rational
357360
t = giac_type(g)
358-
if t == GIAC_FRAC
361+
if t == FRAC
359362
return _convert_to_rational(g)
360-
elseif t == GIAC_INT
363+
elseif t == INT
361364
return Rational(_convert_to_int64(g))
362-
elseif t == GIAC_ZINT
365+
elseif t == ZINT
363366
return Rational(_convert_to_bigint(g))
364367
else
365368
throw(MethodError(convert, (Rational, g)))
@@ -373,7 +376,7 @@ Convert a complex GiacExpr to a Julia Complex.
373376
"""
374377
function Base.convert(::Type{Complex}, g::GiacExpr)::Complex
375378
t = giac_type(g)
376-
if t == GIAC_CPLX
379+
if t == CPLX
377380
return _convert_to_complex(g)
378381
elseif is_numeric(g)
379382
# Numeric but not complex - treat as real
@@ -415,7 +418,7 @@ function Base.convert(::Type{Bool}, g::GiacExpr)::Bool
415418

416419
# Allow integer 0/1 to convert to Bool (standard Julia behavior)
417420
t = giac_type(g)
418-
if t == GIAC_INT
421+
if t == INT
419422
val = _convert_to_int64(g)
420423
if val == 0
421424
return false

src/gen_types.jl

Lines changed: 123 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,123 @@
1+
# GenTypes module - Scoped enum for GIAC expression types
2+
# Feature: 041-scoped-type-enum
3+
# Provides type-safe enum matching C++ gen_unary_types
4+
5+
"""
6+
GenTypes
7+
8+
A submodule containing the `T` enum for GIAC expression type constants.
9+
10+
This module provides type-safe, scoped access to GIAC's internal type system,
11+
matching the C++ `gen_unary_types` enum exactly.
12+
13+
# Usage
14+
15+
```julia
16+
using Giac.GenTypes: T, INT, VECT, SYMB
17+
18+
# Access type constants as module values
19+
INT # Machine integer (0)
20+
DOUBLE # Double-precision float (1)
21+
VECT # Vector/list/sequence (7)
22+
SYMB # Symbolic expression (8)
23+
24+
# Or use the T type for construction from integers
25+
T(0) # INT
26+
T(7) # VECT
27+
28+
# Use with giac_type()
29+
expr = giac_eval("42")
30+
giac_type(expr) == INT # true
31+
32+
# Convert to integer
33+
Int(VECT) # 7
34+
```
35+
36+
# Type Values
37+
38+
The enum values match the C++ `gen_unary_types` enum:
39+
- Types 0-1 and 20-21 are "immediate" (no memory allocation)
40+
- Types 2-19 are "pointer" types (require memory allocation)
41+
42+
See also: [`giac_type`](@ref)
43+
"""
44+
module GenTypes
45+
46+
"""
47+
T
48+
49+
Enum representing GIAC expression types, matching C++ `gen_unary_types`.
50+
51+
# Values
52+
53+
| Value | Int | C++ Name | Description |
54+
|-------|-----|----------|-------------|
55+
| `T.INT` | 0 | `_INT_` | Machine integer |
56+
| `T.DOUBLE` | 1 | `_DOUBLE_` | Double-precision float |
57+
| `T.ZINT` | 2 | `_ZINT` | Arbitrary precision integer |
58+
| `T.REAL` | 3 | `_REAL` | Extended precision real |
59+
| `T.CPLX` | 4 | `_CPLX` | Complex number |
60+
| `T.POLY` | 5 | `_POLY` | Polynomial |
61+
| `T.IDNT` | 6 | `_IDNT` | Identifier/variable |
62+
| `T.VECT` | 7 | `_VECT` | Vector/list/sequence |
63+
| `T.SYMB` | 8 | `_SYMB` | Symbolic expression |
64+
| `T.SPOL1` | 9 | `_SPOL1` | Sparse polynomial |
65+
| `T.FRAC` | 10 | `_FRAC` | Rational fraction |
66+
| `T.EXT` | 11 | `_EXT` | Algebraic extension |
67+
| `T.STRNG` | 12 | `_STRNG` | String |
68+
| `T.FUNC` | 13 | `_FUNC` | Function reference |
69+
| `T.ROOT` | 14 | `_ROOT` | Root of polynomial |
70+
| `T.MOD` | 15 | `_MOD` | Modular arithmetic |
71+
| `T.USER` | 16 | `_USER` | User-defined type |
72+
| `T.MAP` | 17 | `_MAP` | Map/dictionary |
73+
| `T.EQW` | 18 | `_EQW` | Equation writer data |
74+
| `T.GROB` | 19 | `_GROB` | Graphic object |
75+
| `T.POINTER` | 20 | `_POINTER_` | Raw pointer |
76+
| `T.FLOAT` | 21 | `_FLOAT_` | Float (immediate) |
77+
78+
# Examples
79+
80+
```julia
81+
using Giac.GenTypes: T, INT, VECT, FLOAT
82+
83+
# Check integer value
84+
Int(INT) == 0 # true
85+
Int(VECT) == 7 # true
86+
Int(FLOAT) == 21 # true
87+
88+
# Create from integer
89+
T(0) == INT # true
90+
T(7) == VECT # true
91+
```
92+
"""
93+
@enum T::Int32 begin
94+
INT = 0 # _INT_ - Machine integer (immediate)
95+
DOUBLE = 1 # _DOUBLE_ - Double-precision float (immediate)
96+
ZINT = 2 # _ZINT - Arbitrary precision integer
97+
REAL = 3 # _REAL - Extended precision real
98+
CPLX = 4 # _CPLX - Complex number
99+
POLY = 5 # _POLY - Polynomial
100+
IDNT = 6 # _IDNT - Identifier/variable
101+
VECT = 7 # _VECT - Vector/list/sequence
102+
SYMB = 8 # _SYMB - Symbolic expression
103+
SPOL1 = 9 # _SPOL1 - Sparse polynomial
104+
FRAC = 10 # _FRAC - Rational fraction
105+
EXT = 11 # _EXT - Algebraic extension
106+
STRNG = 12 # _STRNG - String
107+
FUNC = 13 # _FUNC - Function reference
108+
ROOT = 14 # _ROOT - Root of polynomial
109+
MOD = 15 # _MOD - Modular arithmetic
110+
USER = 16 # _USER - User-defined type
111+
MAP = 17 # _MAP - Map/dictionary
112+
EQW = 18 # _EQW - Equation writer data
113+
GROB = 19 # _GROB - Graphic object
114+
POINTER = 20 # _POINTER_ - Raw pointer (immediate)
115+
FLOAT = 21 # _FLOAT_ - Float (immediate)
116+
end
117+
118+
export T
119+
# Export all enum values for direct access after `using Giac.GenTypes`
120+
export INT, DOUBLE, ZINT, REAL, CPLX, POLY, IDNT, VECT, SYMB
121+
export SPOL1, FRAC, EXT, STRNG, FUNC, ROOT, MOD, USER, MAP, EQW, GROB, POINTER, FLOAT
122+
123+
end # module GenTypes

0 commit comments

Comments
 (0)