cell_t *case_list = list_new(); cell_t *case_expr = list_new(); cell_t *case_variants = list_new(); cell_t *case_variant1 = list_new(); cell_t *case_variant1_p = list_new(); cell_t *case_variant1_p_l = list_new(); cell_t *case_variant1_p_args = list_new(); cell_t *case_variant1_p_code = list_new(); cell_t *case_variant1_i = list_new(); cell_t *case_variant2 = list_new(); cell_t *case_variant2_p = list_new(); cell_t *case_variant2_i = list_new(); cell_t *case_variant3 = list_new(); cell_t *case_variant3_p = list_new(); cell_t *case_variant3_p_l = list_new(); cell_t *case_variant3_p_args = list_new(); cell_t *case_variant3_p_code = list_new(); cell_t *case_variant3_i = list_new(); cell_t *case_variant4 = list_new(); cell_t *case_variant4_p = list_new(); cell_t *case_variant4_i = list_new(); cell_t *case_default_variant_i = list_new(); abstract_object_t *op_result; abstract_object_t *expression; case_list = list_append (case_list, abstract_create_method((const void*)"CASE", type_lookup_by_id(TYPE_NAME))); case_list = list_append (case_list, abstract_create_method((const void*)"Beta", type_lookup_by_id(TYPE_STRING))); case_variant1 = list_append (case_variant1, abstract_create_method((const void*)"Kenobi", type_lookup_by_id(TYPE_STRING))); case_variant1 = list_append (case_variant1, abstract_create_method((const void*)"Jedi", type_lookup_by_id(TYPE_STRING))); case_variant2_p = list_append (case_variant2_p, abstract_create_method((const void*)(intptr_t) { 5 }, type_lookup_by_id(TYPE_INTEGER))); case_variant2_p = list_append (case_variant2_p, abstract_create_method((const void*)(intptr_t) { 99 }, type_lookup_by_id(TYPE_INTEGER))); case_variant2_p = list_append (case_variant2_p, abstract_create_method((const void*)(intptr_t) { 1024 }, type_lookup_by_id(TYPE_INTEGER))); case_variant2 = list_append (case_variant2, abstract_create_method((const void*)case_variant2_p, type_lookup_by_id(TYPE_LIST))); case_variant2 = list_append (case_variant2, abstract_create_method((const void*)"Kinda integer", type_lookup_by_id(TYPE_STRING))); case_variant3_p = list_append (case_variant3_p, abstract_create_method((const void*)"Alpha", type_lookup_by_id(TYPE_STRING))); case_variant3_p = list_append (case_variant3_p, abstract_create_method((const void*)(intptr_t) { 1 }, type_lookup_by_id(TYPE_INTEGER))); case_variant3_p = list_append (case_variant3_p, abstract_create_method((const void*)"Beta", type_lookup_by_id(TYPE_STRING))); case_variant3 = list_append (case_variant3, abstract_create_method((const void*)case_variant3_p, type_lookup_by_id(TYPE_LIST))); case_variant3 = list_append (case_variant3, abstract_create_method((const void*)"$$", type_lookup_by_id(TYPE_NAME))); case_variants = list_append (case_variants, abstract_create_method((const void*)case_variant1, type_lookup_by_id(TYPE_LIST))); case_variants = list_append (case_variants, abstract_create_method((const void*)case_variant2, type_lookup_by_id(TYPE_LIST))); case_variants = list_append (case_variants, abstract_create_method((const void*)case_variant3, type_lookup_by_id(TYPE_LIST))); case_list = list_append (case_list, abstract_create_method((const void*)case_variants, type_lookup_by_id(TYPE_LIST))); case_default_variant_i = list_append (case_default_variant_i, abstract_create_method((const void*)"FORMAT", type_lookup_by_id(TYPE_NAME))); case_default_variant_i = list_append (case_default_variant_i, abstract_create_method((const void*)"I dont know what to do with ~a~%", type_lookup_by_id(TYPE_STRING))); case_default_variant_i = list_append (case_default_variant_i, abstract_create_method((const void*)"$", type_lookup_by_id(TYPE_NAME))); case_list = list_append (case_list, abstract_create_method((const void*)case_default_variant_i, type_lookup_by_id(TYPE_LIST))); set_symbol_value ("CASE-TEST", abstract_create_method((const void*)case_list, type_lookup_by_id(TYPE_LIST)), SCOPE_LOCAL); print_symbol("CASE-TEST", SCOPE_LOCAL); expression = abstract_create_method((const void*)case_list, type_lookup_by_id(TYPE_LIST)); op_result = eval(expression); printf ("result: "); abstract_print_method(op_result); printf ("\n"); abstract_delete_method(&op_result); abstract_delete_method(&expression); list_delete_aobj(&case_list); list_delete_aobj(&case_expr); list_delete_aobj(&case_variants); list_delete_aobj(&case_variant1); list_delete_aobj(&case_variant1_p); list_delete_aobj(&case_variant1_p_l); list_delete_aobj(&case_variant1_p_code); list_delete_aobj(&case_variant1_p_args); list_delete_aobj(&case_variant1_i); list_delete_aobj(&case_variant2); list_delete_aobj(&case_variant2_p); list_delete_aobj(&case_variant2_i); list_delete_aobj(&case_variant3); list_delete_aobj(&case_variant3_p); list_delete_aobj(&case_variant3_p_l); list_delete_aobj(&case_variant3_p_code); list_delete_aobj(&case_variant3_p_args); list_delete_aobj(&case_variant3_i); list_delete_aobj(&case_variant4); list_delete_aobj(&case_variant4_p); list_delete_aobj(&case_variant4_i); list_delete_aobj(&case_default_variant_i);
прикрутил лексический анализатор. Очень удобно оказалось для этого использовать Flex, код для "токенайзера" занимает около 150 строк и включает в себя разбор чисел, строк, имён, списков (сейчас ещё впишу распознавание отдельных character), комментариев - как классических лисповых однострочных, так и настоящих многострочных комментов (в синтаксисе известных мне реализаций CL отсутствуют).
Собственно, монстрятина выше это вот что:
(defsym case-test (case "Beta" ( ( "Kenobi" "Jedi" ) ( ( 5 99 1024 ) "Kinda integer" ) ( ( "Alpha" 1 "Beta" ) $$ ) ) ( format "I dont know what to do with ~a~%" $ ) ) ) (format "result: ~a~%" case-test)
Разница, по-моему, есть.