Created
July 7, 2015 03:50
Revisions
-
vermiculus created this gist
Jul 7, 2015 .There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,69 @@ \nonstopmode \input expl3-generic \relax \ExplSyntaxOn % -*- expl3 -*- %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \file_input:n { obj } \obj_new:nn { rectangle } { size: int = 2, name: tl, } \rectangle_new:Nn \l_my_rect { name = bill } \prop_show:N \l_my_rect \exp_args:No \msg_term:n { name=\rectangle_get:Nn \l_my_rect {name} } \rectangle_set:Nn \l_my_rect { name = bob, other=hi } \exp_args:No \msg_term:n { name=\rectangle_get:Nn \l_my_rect {name} } \obj_show:n { rectangle } %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \msg_term:n { Testing~ball... } \obj_new:nn { ball } { bounce-factor: int = 4, name: tl, color: color = blue, } \obj_show:n { ball } %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \msg_term:n { Creating~a~ball... } \ball_new:Nn \l_my_ball { name = hello, color = red, } \exp_args:No \msg_term:n { \ball_get:Nn \l_my_ball { name } } \ball_show:N \l_my_ball \msg_term:n { Testing~ball...complete. } %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \msg_term:n { Testing~baseball... } \obj_new:nn { ball / baseball } { games-won: int = 0, stiches: int, } \obj_show:n { baseball } \msg_term:n { Testing~baseball...complete. } %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \bye This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,176 @@ % -*- expl3 -*- \file_input:n { parsing } \tl_new:N \l__obj_tmp_tl \seq_new:N \l__obj_tmp_seq \clist_new:N \g__obj_obj__types_clist \clist_set:Nn \g__obj_obj__types_clist { obj, tl, seq, int, color } \msg_new:nnn { obj } { unknown-type } { The~type~you~have~provided~is~not~known~to~exist:~`#1' } \msg_new:nnn { obj } { unknown-field } { The~field~you~have~provided~is~not~known~to~exist~for~this~object:~`#1.#2' } % \section{Methods, Getters, and Setters} \cs_new:Nn \obj_method:nnn { \cs_new:cn { #1_#2 } {#3} } \cs_new:Nn \obj_use_method:nn { \use:c { #1_#2 } } \cs_new:Nn \__obj_make_getter:nn { \obj_method:nnn {#1} { #2:N } { \prop_item:Nn ##1 {#2} } } \cs_new:Nn \__obj_make_setter:nn { \obj_method:nnn {#1} { #2:Nn } { \prop_put:Nnn ##1 {#2} {##2} } } \cs_generate_variant:Nn \__obj_make_getter:nn { VV } \cs_generate_variant:Nn \__obj_make_setter:nn { VV } % \section{Defining New Objects} % \subsection{Internal Storage} \cs_new:Nn \__obj_setup:nNN % with superclass { % { {spec} {proto} } \seq_new:c { g__obj_spec_#1_seq } \seq_put_left:cV { g__obj_spec_#1_seq } #2 \seq_put_right:cV { g__obj_spec_#1_seq } #3 } \cs_new:Nn \__obj_setup:n % no superclass { \__obj_setup:nNN {#1} \c_empty_prop \c_empty_prop } \cs_generate_variant:Nn \__obj_setup:n { V } \cs_generate_variant:Nn \__obj_setup:nNN { V } \cs_new:Nn \__obj_spec:nN { \seq_get_left:cN { g__obj_spec_#1_seq } #2 } % get spec \cs_new:Nn \__obj_proto:nN { \seq_get_right:cN { g__obj_spec_#1_seq } #2 } % get proto \cs_new:Nn \__obj_spec:Nn % set spec { \seq_pop_left:cN { g__obj_spec_#2_seq } \l__obj_tmp_seq \seq_put_left:cV { g__obj_spec_#2_seq } #1 } \cs_new:Nn \__obj_proto:Nn % set proto { \seq_pop_right:cN { g__obj_spec_#2_seq } \l__obj_tmp_seq \seq_put_right:cV { g__obj_spec_#2_seq } #1 } \cs_generate_variant:Nn \__obj_spec:nN { V } \cs_generate_variant:Nn \__obj_proto:nN { V } \cs_generate_variant:Nn \__obj_spec:Nn { NV } \cs_generate_variant:Nn \__obj_proto:Nn { NV } % \subsection{User Interface} \tl_new:N \l__obj_class_name_tl \cs_new:Nn \obj_new:nn { \__obj_define:nnN {#1} {#2} \l__obj_class_name_tl \__obj_process_fields:Vn \l__obj_class_name_tl {#2} \__obj_make_metas:V \l__obj_class_name_tl } \prop_new:N \l__obj_spec_prop \prop_new:N \l__obj_proto_prop \cs_new:Nn \__obj_define:nnN % { { super / class } class-name-tl-var } { \seq_set_split:Nnn \l__obj_tmp_seq { / } {#1} \seq_pop_right:NN \l__obj_tmp_seq #3 % class \seq_pop_right:NN \l__obj_tmp_seq \l__obj_tmp_tl % superclass \quark_if_no_value:NTF \l__obj_tmp_tl { \__obj_setup:V #3 } { % grab superclass spec, prototype \__obj_spec:VN \l__obj_tmp_tl \l__obj_spec_prop \__obj_proto:VN \l__obj_tmp_tl \l__obj_proto_prop % and base the new object off of it \__obj_setup:VNN #3 \l__obj_spec_prop \l__obj_proto_prop % get the prototype for the new class \__obj_proto:VN \l__obj_tmp_tl \l__obj_tmp_prop \parse_dictionary:nn {#2} { \prop_if_in:NVF \l__obj_proto_prop \l_parse_dictionary_key_tl { \prop_put:NVV \l__obj_tmp_prop \l_parse_dictionary_key_tl \l_parse_dictionary_value_tl } } \__obj_proto:NV \l__obj_tmp_prop \l__obj_tmp_tl } } \cs_new:Nn \__obj_process_fields:nn % { {class-name} {fields} } { \parse_dictionary:nn {#2} { % make sure we know about this type \clist_if_in:NVF \g__obj_obj__types_clist \l_parse_dictionary_type_tl { \msg_warning:nnx { obj } { unknown-type } { \tl_use:N \l_parse_dictionary_type_tl } } \__obj_spec:nN {#1} \l__obj_tmp_prop \prop_put:NVV \l__obj_tmp_prop \l_parse_dictionary_key_tl \l_parse_dictionary_type_tl \__obj_spec:Nn \l__obj_tmp_prop {#1} \__obj_proto:nN {#1} \l__obj_tmp_prop \prop_put:NVV \l__obj_tmp_prop \l_parse_dictionary_key_tl \l_parse_dictionary_value_tl \__obj_proto:Nn \l__obj_tmp_prop {#1} } } \cs_generate_variant:Nn \__obj_process_fields:nn { V } \cs_new:Nn \__obj_make_metas:n { \obj_method:nnn {#1} { show:N } { \prop_show:N ##1 } \obj_method:nnn {#1} { new:N } % { obj-var } { \__obj_proto:nN {#1} \l__obj_tmp_prop \prop_set_eq:NN ##1 \l__obj_tmp_prop } \obj_method:nnn {#1} { new:Nn } % { obj-var {values} } { \obj_use_method:nn {#1} { new:N } ##1 \obj_use_method:nn {#1} { set:Nn } ##1 {##2} % put in defaults \__obj_proto:nN {#1} \l__obj_tmp_prop \prop_map_inline:Nn \l__obj_tmp_prop { \prop_put_if_new:Nnn ##1 {####1} {####2} } } \obj_method:nnn {#1} { get:Nn } % { obj-var {field} } { \prop_item:Nn ##1 {##2} } \obj_method:nnn {#1} { set:Nn } { \prop_clear_new:N ##1 \__obj_spec:nN {#1} \l__obj_tmp_prop \parse_prop:nn {##2} { \prop_if_in:NVF \l__obj_tmp_prop \l_parse_prop_key_tl { \msg_warning:nnxx { obj } { unknown-field } {#1} { \tl_use:N \l_parse_prop_key_tl } } \prop_put:NVV ##1 \l_parse_prop_key_tl \l_parse_prop_value_tl } } } \cs_generate_variant:Nn \__obj_make_metas:n { V } \cs_new:Nn \obj_show:n { \__obj_spec:nN {#1} \l__obj_tmp_prop \prop_show:N \l__obj_tmp_prop \__obj_proto:nN {#1} \l__obj_tmp_prop \prop_show:N \l__obj_tmp_prop } This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,44 @@ % -*- expl3 -*- \tl_new:N \l_parse_dictionary_key_tl \tl_new:N \l_parse_dictionary_type_tl \tl_new:N \l_parse_dictionary_value_tl \seq_new:N \l__parse_dictionary_dict_seq \seq_new:N \l__parse_dictionary_field_seq \cs_new:Nn \parse_dictionary:nn { \seq_set_split:Nnn \l__parse_dictionary_dict_seq { , } {#1} \seq_map_inline:Nn \l__parse_dictionary_dict_seq { \tl_if_empty:nF {##1} { \seq_set_split:Nnn \l__parse_dictionary_field_seq { : } {##1} \seq_pop:NN \l__parse_dictionary_field_seq \l_parse_dictionary_key_tl \seq_pop:NN \l__parse_dictionary_field_seq \l_parse_dictionary_type_tl \seq_set_split:NnV \l__parse_dictionary_field_seq { = } \l_parse_dictionary_type_tl \seq_pop:NN \l__parse_dictionary_field_seq \l_parse_dictionary_type_tl \seq_pop:NNF \l__parse_dictionary_field_seq \l_parse_dictionary_value_tl { \tl_clear:N \l_parse_dictionary_value_tl } #2 } } } \tl_new:N \l_parse_prop_key_tl \tl_new:N \l_parse_prop_value_tl \seq_new:N \l__parse_prop_dict_seq \seq_new:N \l__parse_prop_field_seq \cs_new:Nn \parse_prop:nn { \seq_set_split:Nnn \l__parse_prop_dict_seq { , } {#1} \seq_map_inline:Nn \l__parse_prop_dict_seq { \tl_if_empty:nF {##1} { \seq_set_split:Nnn \l__parse_prop_field_seq { = } {##1} \seq_pop:NN \l__parse_prop_field_seq \l_parse_prop_key_tl \seq_pop:NN \l__parse_prop_field_seq \l_parse_prop_value_tl #2 } } }