Skip to content

Commit 1235be7

Browse files
committed
Restructure the generated code logic a bit to avoid digging into Expr objs
1 parent 27df02b commit 1235be7

File tree

1 file changed

+39
-34
lines changed

1 file changed

+39
-34
lines changed

src/gentypes.jl

Lines changed: 39 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -430,13 +430,21 @@ function buildtype(mod::ROSSrvModule, typename::String)
430430
[reqexprs; respexprs; srvexprs]
431431
end
432432

433+
# Container for the generated expressions for each type
434+
struct ROSTypeExprs
435+
# The contents of the 'struct ... end' block
436+
member_decls::Vector{Expr}
437+
# The default values used for defining a no argument constructor
438+
constructor_defs::Vector{Any}
439+
# The conversions to PyObject
440+
conv_to_pyobj_args::Vector{Expr}
441+
# The conversion from PyObject
442+
conv_from_pyobj_args::Vector{Expr}
443+
end
444+
ROSTypeExprs() = ROSTypeExprs(Expr[], Expr[], Expr[], Expr[])
445+
433446
#Create the core generated expressions for a native Julia message type that has
434-
#data fields and interchanges with a python counterpart:
435-
# (1) the 'type ... end' block
436-
# (2) Default outer constructer with no arguments
437-
# (3) convert(PyObject, ...)
438-
# (4) convert(..., o::PyObject)
439-
# (5) getproperty for accessing member constants
447+
#data fields and interchanges with a python counterpart
440448
function typecode(rosname::String, super::Symbol, members::Vector)
441449
tname = _splittypestr(rosname)[2]
442450
@debug("Type: ", tname)
@@ -448,44 +456,52 @@ function typecode(rosname::String, super::Symbol, members::Vector)
448456
else; "ROS" end
449457
jlsym = Symbol(_jl_safe_name(tname,suffix))
450458

459+
#First generate the interior expressions for each member separately
460+
member_exprs = ROSTypeExprs()
461+
for (namestr,typ) in members
462+
@debug_addindent
463+
_addtypemember!(member_exprs, namestr, typ)
464+
@debug_subindent
465+
end
466+
467+
#Now build the full expressions
451468
exprs = Expr[]
452-
#First the empty expressions
453-
#(1) Type declaration
469+
# Type declaration
454470
push!(exprs, :(
455471
mutable struct $jlsym <: $super
456-
#Generated code here
472+
$(member_exprs.member_decls...)
457473
end
458474
))
459-
#(2) Default constructor, but only if the type has members
475+
# Default constructor, but only if the type has members
460476
if length(members) > 0
461477
push!(exprs, :(
462478
function $jlsym()
463-
$jlsym() #Generated code inside parens here
479+
$jlsym($(member_exprs.constructor_defs...))
464480
end
465481
))
466482
else
467483
push!(exprs, :())
468484
end
469-
#(3) Convert to PyObject
485+
# Convert to PyObject
470486
push!(exprs, :(
471487
function convert(::Type{PyObject}, o::$jlsym)
472488
py = pycall(RobotOS._rospy_objects[$rosname], PyObject)
473-
#Generated code here
489+
$(member_exprs.conv_to_pyobj_args...)
474490
py
475491
end
476492
))
477-
#(4) Convert from PyObject
493+
# Convert from PyObject
478494
push!(exprs, :(
479495
function convert(jlt::Type{$jlsym}, o::PyObject)
480496
if convert(String, o."_type") != _typerepr(jlt)
481497
throw(InexactError(:convert, $jlsym, o))
482498
end
483499
jl = $jlsym()
484-
#Generated code here
500+
$(member_exprs.conv_from_pyobj_args...)
485501
jl
486502
end
487503
))
488-
#(5) Accessing member variables through getproperty
504+
# Accessing member variables through getproperty
489505
push!(exprs, :(
490506
function getproperty(::Type{$jlsym}, s::Symbol)
491507
try getproperty(RobotOS._rospy_objects[$rosname], s)
@@ -499,28 +515,16 @@ function typecode(rosname::String, super::Symbol, members::Vector)
499515
end
500516
end
501517
))
502-
503-
#Now add the meat to the empty expressions above
504-
for (namestr,typ) in members
505-
@debug_addindent
506-
_addtypemember!(exprs, namestr, typ)
507-
@debug_subindent
508-
end
509518
push!(exprs, :(_typerepr(::Type{$jlsym}) = $rosname))
519+
510520
exprs
511521
end
512522

513-
514523
#Add the generated expression from a single member of a type, either built-in
515524
#or ROS type. `exprs` is the Expr objects of the items created in `typecode`.
516525
#Maybe this can be factored into something nicer.
517-
function _addtypemember!(exprs, namestr, typestr)
526+
function _addtypemember!(exprs::ROSTypeExprs, namestr, typestr)
518527
@debug("$namestr :: $typestr")
519-
typeargs = exprs[1].args[3].args
520-
consargs = exprs[2].args[2].args[2].args
521-
pyconargs = exprs[3].args[2].args
522-
jlconargs = exprs[4].args[2].args
523-
524528
if typestr == "char" || typestr == "byte"
525529
@warn("Use of type '$typestr' is deprecated in message definitions, " *
526530
"use '$(lowercase(string(_ros_builtin_types[typestr])))' instead.")
@@ -564,10 +568,11 @@ function _addtypemember!(exprs, namestr, typestr)
564568
jlconexpr = :(jl.$namesym = convert($j_typ, o.$namestr))
565569
pyconexpr = :(py.$namestr = convert(PyObject, o.$namesym))
566570
end
567-
push!(typeargs, memexpr)
568-
insert!(jlconargs, length(jlconargs), jlconexpr)
569-
insert!(pyconargs, length(pyconargs), pyconexpr)
570-
push!(consargs, defexpr)
571+
572+
push!(exprs.member_decls, memexpr)
573+
push!(exprs.constructor_defs, defexpr)
574+
push!(exprs.conv_to_pyobj_args, pyconexpr)
575+
push!(exprs.conv_from_pyobj_args, jlconexpr)
571576
end
572577

573578
#Build a String => Iterable{String} object from the individual package

0 commit comments

Comments
 (0)