Created
July 7, 2015 02:24
-
-
Save vermiculus/76f984e7cc3cfcefa05f 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 { obj2 } | |
\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 {BEGIN-BEGIN} | |
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
\msg_term:n { Testing~ball... } | |
\obj_new:nn { ball } | |
{ | |
bounce-factor: int = 4, | |
name: tl, | |
color: color = blue, | |
} | |
\msg_term:n {hehehe} | |
\obj_show:n { ball } | |
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
\msg_term:n { Creating~a~ball... } | |
\ball_new:Nn \l_my_ball | |
{ | |
name = hello, | |
color = red, | |
} | |
\msg_term:n { ?~a~ball... } | |
\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 | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment