Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Some compat functions #232

Merged
merged 2 commits into from
May 10, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
89 changes: 89 additions & 0 deletions pkg/GAPJulia/JuliaInterface/julia/gap.jl
Original file line number Diff line number Diff line change
Expand Up @@ -68,3 +68,92 @@ for (left, right) in typecombinations
end
end
end


"""
@gap <obj>
@gap(<obj>)

Executes <obj> directly in GAP, as if `GAP.EvalString("<obj>")` was called.
Can be used for creating GAP literals directly from Julia.

julia> @gap (1,2,3)
GAP: (1,2,3)
julia> @gap SymmetricGroup(3)
GAP: SymmetricGroup( [ 1 .. 3 ] )
julia> @gap(SymmetricGroup)(3)
GAP: SymmetricGroup( [ 1 .. 3 ] )

Note that the last two examples have a slight syntactical, and therefore also
a semantical difference. The first one executes the string `SymmetricGroup(3)`
directly inside GAP. The second example returns the function `SymmetricGroup`
via `@gap(SymmetricGroup)`, then calls that function with the argument `3`.
"""
macro gap(str)
fingolfin marked this conversation as resolved.
Show resolved Hide resolved
return EvalString(string(str))
end

export @gap

"""
LoadPackageAndExposeGlobals(package::String, mod::String; all_globals::Bool = false)
LoadPackageAndExposeGlobals(package::String, mod::Module = Main; all_globals::Bool = false)

`LoadPackageAndExposeGlobals` loads `package` into GAP via `LoadPackage`,
and stores all newly defined GAP globals as globals in the module `mod`. If `mod` is
a string, the function creates a new module, if `mod` is a Module, it uses `mod` directly.

The function is intended to be used for creating mock modules for GAP packages.
If you load the package `CAP` via

LoadPackageAndExposeGlobals( "CAP", "CAP" )

you can use CAP commands via

CAP.PreCompose( a, b )

"""
function LoadPackageAndExposeGlobals(package::String, mod::String; all_globals::Bool = false)
fingolfin marked this conversation as resolved.
Show resolved Hide resolved
mod_sym = Symbol(mod)
Base.MainInclude.eval(:(
module $(mod_sym)
import GAP
end
))
## Adds the new module to the Main module, so it is directly accessible in the julia REPL
mod_mod = Base.MainInclude.eval(:(Main.$(mod_sym)))
fingolfin marked this conversation as resolved.
Show resolved Hide resolved

## We need to call `invokelatest` as the module `mod_mod` was only created during the
## call of this function in a different module, so its world age is higher than the
## function calls world age.
Base.invokelatest(LoadPackageAndExposeGlobals, package, mod_mod; all_globals = all_globals)
end

function LoadPackageAndExposeGlobals(package::String, mod::Module; all_globals::Bool = false)
current_gvar_list = nothing
if !all_globals
current_gvar_list = Globals.ShallowCopy(Globals.NamesGVars())
end
load_package = EvalString("LoadPackage(\"$package\")")
if load_package == Globals.fail
error("cannot load package $package")
end
new_gvar_list = nothing
if all_globals
new_gvar_list = Globals.NamesGVars()
else
new_gvar_list = Globals.Difference(Globals.NamesGVars(),current_gvar_list)
end
new_symbols = gap_to_julia(Array{Symbol,1},new_gvar_list)
for sym in new_symbols
try
mod.eval(:(
$(sym)=GAP.Globals.$(sym)
))
catch
end
end
end

export LoadPackageAndExposeGlobals

12 changes: 12 additions & 0 deletions test/compat.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
@testset "compat" begin

x = @gap (1,2,3)
@test x == GAP.EvalString("(1,2,3)")
x = @gap((1,2,3))
@test x == GAP.EvalString("(1,2,3)")
x = @gap [1,2,3]
@test x == GAP.EvalString("[1,2,3]")
x = @gap(SymmetricGroup)(3)
@test GAP.Globals.Size(x) == 6

end
1 change: 1 addition & 0 deletions test/runtests.jl
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,4 @@ using GAP
include("basics.jl")
include("convenience.jl")
include("conversion.jl")
include("compat.jl")