Last active
August 29, 2015 14:24
-
-
Save vermiculus/a3f92ff127745eb21773 to your computer and use it in GitHub Desktop.
This file contains 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 characters
\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 } | |
\rectangle_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 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 characters
% -*- 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 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 characters
% -*- 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 | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment