Created
July 7, 2015 03:50
-
-
Save vermiculus/a76aa57275033eed7811 to your computer and use it in GitHub Desktop.
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 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 } | |
\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 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 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 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