help-make
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Structures or objects in make


From: Noel Yap
Subject: Re: Structures or objects in make
Date: Thu, 20 Nov 2003 12:39:46 -0500

I just tend to stick to using '.' or '!' as separartors.  For example:

aoeu.field0 := 0        # '.' is used for public consumption, eg the names are 
dictated by the user
aoeu!field1 := 1        # '!' is used for passing things into and out of 
functions, eg the names are dictated by the function creator

Methods are handled the same way:

aoeu.assign := :=

HTH,
Noel

Robert Mecklenburg wrote:
> 
> I was thinking the other day that it would occassionally be nice to
> have structures in make.  They are useful for collecting related
> information and for reducing the number of arguments passed to
> functions.  Computed names are often used this way in a less formal
> fashion.  I've hacked up a set of functions to implement a simple
> structure.  I'd be interested in anyone's reaction.  The code can be
> used like this:
> 
> # Define a structure foo with two slots a and b.  The default value
> # for slot a is 1, for b is hi.
> $(call defstruct,foo,a,1,b,hi)
> 
> # Allocate an instance of struct foo, call it foo1.
> foo1 := $(call new, foo)
> 
> # Set foo1.a to 4.
> $(call set-value,foo1,a,4)
> 
> # Allocate another instance of struct foo, call it foo2.
> foo2 := $(call new,foo)
> $(call set-value,foo2,b,there)
> 
> # Here is another structure with two slots and no default values.
> $(call defstruct,file,path,,type,)
> file1 := $(call new,file)
> $(call set-value,file1,path,/c/home/mecklen/.emacs)
> #$(call set-value,file1,type,lisp)
> 
> x:
>         # foo1   = $(foo1)
>         # foo1.a = $(call get-value,foo1,a)
>         # foo1.b = $(call get-value,foo1,b)
>         # foo1   = $(call print-instance,foo1)
>         # foo1   = $(call dump-instance,foo1)
>         #
>         # foo2   = $(foo2)
>         # foo2.a = $(call get-value,foo2,a)
>         # foo2.b = $(call get-value,foo2,b)
>         # foo2   = $(call print-instance,foo2)
>         # foo2   = $(call dump-instance,foo2)
>         #
>         # file1      = $(file1)
>         # file1.path = $(call get-value,file1,path)
>         # file1.type = $(call get-value,file1,type)
>         # file1      = $(call print-instance,file1)
>         # file1      = $(call dump-instance,file1)
>         #
>         # $(all-instances)
>         # $(all-structs)
>         # $(call print-struct,foo)
>         # $(call print-struct,file)
>         # $(call dump-struct,foo)
>         # $(call dump-struct,file)
> 
> The print-* functions display the user-visible values.  The dump-*
> functions reveal the implementation variables as well.  The code to
> implement this follows the message (not much documentation I'm
> afraid).  This is definitely "proof of concept" quality code.
> 
> Currently, values can be null, but cannot contain blanks (this
> limitation can be fixed).  I think it is clear this technique could be
> extended to include at least single inheritance and obviously it
> already supports a certain amount of reflection.  I'm not so sure how
> methods would be usefully incorporated.
> 
> Comments?
> --
> Robert
> 
> # $(next-id) - return a unique number
> next-id-counter :=
> define next-id
> $(words $(next-id-counter))$(eval next-id-counter += 1)
> endef
> 
> # all-structs - a list of the defined structure names
> all-structs :=
> 
> value-sep := XxSepxX
> 
> # $(call defstruct, struct-name, slot-name, value, ...)
> define defstruct
>   $(eval all-structs += $1)                                             \
>   $(eval $1-def-slotnames :=)                                           \
>   $(foreach v, $2$(value-sep)$3 $4$(value-sep)$5 $6$(value-sep)$7       \
>                $8$(value-sep)$9 $(10)$(value-sep)$(11),                 \
>     $(eval tmp-name  := $(word 1, $(subst $(value-sep), , $v)))         \
>     $(if $(tmp-name),                                                   \
>       $(eval tmp-value := $(word 2, $(subst $(value-sep), , $v)))       \
>       $(eval $1-def-slotnames           += $(tmp-name))                 \
>       $(eval $1-def-$(tmp-name)-default := $(tmp-value))))
> endef
> 
> # all-instances - a list of all the instances of any structure
> all-instances :=
> 
> # $(call new, struct-name)
> define new
> $(strip                                                         \
>   $(if $(filter $1,$(all-structs)),,                            \
>     $(error new on unknown struct '$1'))                        \
>   $(eval struct := $1-$(next-id))                               \
>   $(eval all-instances += $(struct))                            \
>   $(foreach v, $($(strip $1)-def-slotnames),                    \
>     $(eval $(struct)-$v := $($(strip $1)-def-$v-default)))      \
>   $(struct))
> endef
> 
> # $(call struct-name,instance-name)
> define struct-name
> $(firstword $(subst -, ,$($(strip $1))))
> endef
> 
> # $(call check-params, struct-id, slot-name)
> define check-params
>   $(if $(filter $($(strip $1)),$(all-instances)),,              \
>     $(error Invalid instance '$($(strip $1))'))                 \
>   $(if $(filter $2,$($(call struct-name,$1)-def-slotnames)),,   \
>     $(error Instance '$($(strip $1))' does not have slot '$2'))
> endef
> 
> # $(call get-value, struct-id, slot-name)
> define get-value
> $(strip                         \
>   $(call check-params,$1,$2)    \
>   $($($1)-$2))
> endef
> 
> # $(call set-value, struct-id, slot-name)
> define set-value
>   $(call check-params,$1,$2) \
>   $(eval $($(strip $1))-$(strip $2) := $3)
> endef
> 
> # $(call dump-struct, struct-name)
> define dump-struct
> { $1-def-slotnames '$($1-def-slotnames)'        \
>   $(foreach s,                                  \
>     $($1-def-slotnames),$(strip                 \
>     $1-def-$s-default '$($1-def-$s-default)')) }
> endef
> 
> # $(call print-struct, struct-name)
> define print-struct
> { $(foreach s,                  \
>     $($1-def-slotnames),$(strip \
>     { $s $($1-def-$s-default) })) }
> endef
> 
> # $(call dump-instance, instance-name)
> define dump-instance
> { $(eval tmp-name := $(call struct-name,$1))    \
>   $(foreach s,                                  \
>     $($(tmp-name)-def-slotnames),$(strip        \
>     { $($1)-$s '$($($1)-$s)' })) }
> endef
> 
> # $(call print-instance, instance-id)
> define print-instance
> { $(foreach s,                                          \
>     $($(call struct-name,$1)-def-slotnames),$(strip     \
>     $(call get-value,$1,$s))) }
> endef
> 
> _______________________________________________
> Help-make mailing list
> address@hidden
> http://mail.gnu.org/mailman/listinfo/help-make

-- 
NOTICE: If received in error, please destroy and notify sender.  Sender does 
not waive confidentiality or privilege, and use is prohibited.




reply via email to

[Prev in Thread] Current Thread [Next in Thread]