‮Сдвиг по фазе (kincajou) wrote,
‮Сдвиг по фазе
kincajou

  • Music:

Кодогенерация

Вконец уколебавшись вручную писать и выверять конструкции вроде такой:

        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)

Разница, по-моему, есть.
Tags: uncommon lisp
Subscribe

  • Post a new comment

    Error

    Anonymous comments are disabled in this journal

    default userpic

    Your reply will be screened

    Your IP address will be recorded 

  • 1 comment