- 01
- 02
- 03
- 04
- 05
- 06
- 07
- 08
- 09
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
- 75
- 76
- 77
- 78
- 79
- 80
- 81
- 82
- 83
- 84
- 85
- 86
- 87
- 88
- 89
- 90
- 91
- 92
- 93
- 94
- 95
- 96
- 97
static inline void set0b (const uint8_t at, uint64_t bm[static 4])
{
bm[at / 64] &= ~(1ULL << (at % 64));
}
static inline void set1b (const uint8_t at, uint64_t bm[static 4])
{
bm[at / 64] |= 1ULL << (at % 64);
}
static inline void inv_b (const uint8_t at, uint64_t bm[static 4])
{
bm[at / 64] ^= 1ULL << (at % 64);
}
static inline uint8_t find_empt_pos (const uint64_t bm[static 4])
{
if (bm[0] != UINT64_MAX)
{
return __builtin_ctzll(~bm[0]) + 64 * 0; // __builtin_ctzll - https://gcc.gnu.org/onlinedocs/gcc/Other-Builtins.html
}
if (bm[1] != UINT64_MAX)
{
return __builtin_ctzll(~bm[1]) + 64 * 1;
}
if (bm[2] != UINT64_MAX)
{
return __builtin_ctzll(~bm[2]) + 64 * 2;
}
if (bm[3] != UINT64_MAX)
{
return __builtin_ctzll(~bm[3]) + 64 * 3;
}
fprintf(stderr, "ERROR! No empty space!\n");
exit (-1);
}
static inline uint8_t allocate_ll (uint64_t bm[static 4])
{
uint8_t tmp = find_empt_pos (bm);
set1b (tmp, bm);
return tmp;
}
static inline void inject(const uint8_t prev_p, const uint8_t next_p, const uint8_t at, struct ll_data a[static 256])
{
a[next_p].ll.prev = at;
a[prev_p].ll.next = at;
a[at].ll.prev = prev_p;
a[at].ll.next = next_p;
}
static inline void remove_betw(const uint8_t prev_p, const uint8_t next_p, struct ll_data a[static 256])
{
a[prev_p].ll.next = next_p;
a[next_p].ll.prev = prev_p;
}
static inline void remove_at(const uint8_t at, struct ll_data a[static 256], uint64_t bm[static 4])
{
uint8_t prev_t = a[at].ll.prev;
uint8_t next_t = a[at].ll.next;
set0b (at, bm);
a[at].ll.prev = next_t;
a[at].ll.next = prev_t;
}
void add_elem_next (struct ll_all *a, const uint8_t elm, const int value)
{
uint8_t pos = allocate_ll (a->bm);
inject(elm, a->arr[elm].ll.next, pos, a->arr);
set_elm (pos, value, a->arr);
}
void add_elem_prev (struct ll_all *a, const uint8_t elm, const int value)
{
uint8_t pos = allocate_ll (a->bm);
inject(a->arr[elm].ll.prev, elm, pos, a->arr);
a->arr[pos].data = value;
}
void rem_elem_next (struct ll_all *a, const uint8_t elm)
{
set0b (a->arr[elm].ll.next, a->bm);
remove_betw (elm, a->arr[a->arr[elm].ll.next].ll.next, a->arr);
}
void rem_elem_prev (struct ll_all *a, const uint8_t elm)
{
set0b (a->arr[elm].ll.next, a->bm);
remove_betw (a->arr[a->arr[elm].ll.prev].ll.prev, elm, a->arr);
}
Dummy00001 18.08.2017 11:30 # 0
это че за такой загадочный `static`?
inkanus-gray 18.08.2017 11:37 # +5
Array declarators as function arguments now have a meaningful difference from pointer declarators: you can put in type qualifiers. Of particular interest is the very odd optimizer hint of giving an array declarator the static type modifier. Given this declaration: int foo(int a[static 10]);
It is undefined behavior to call foo() with a pointer that doesn't point to at least 10 objects of type int. This is an optimizer hint. All you're doing is promising the compiler that the argument passed to the function will be at least that large; some machines might use this for loop unrolling.
inkanus-gray 18.08.2017 11:43 # +3
The information provided by static in parameter array declarators is not used for optimization. It might make sense to use it in future in conjunction with work on prefetching.
Гэцэцэ тупо игнорирует это слово, обещая, что когда-нибудь в будущем (через 100500 версий) это слово будет влиять на оптимизацию.
Dummy00001 18.08.2017 11:58 # 0
с другой стороны, префетч когда он был мне нужен в либо в компайлерах глючил - либо в процах глючил (сегфолты или доп тормоза). я ему как то не сильно доверяю.
j123123 18.08.2017 13:04 # +3
roman-kashitsyn 18.08.2017 11:52 # +3
inkanus-gray 18.08.2017 11:57 # +2
Вот такой у сишечки интуитивно понятный и запоминаемый синтаксис...
Dummy00001 18.08.2017 12:00 # +2
да я просто тормоз. может с третьего раза запомню.
inkanus-gray 18.08.2017 12:02 # +3
olvidaras 26.02.2019 18:22 # 0
¡Olvidarás!
HEymHblu_nemyx 27.02.2019 01:10 # 0
жуй насвай, гнида
Antervis 18.08.2017 12:15 # 0
Dummy00001 18.08.2017 13:03 # 0
программирование на темплейтах и констэкспр решают меня косающиеся проблемы - там я даже сильно и не пытался запомнить (и реально даже не нужно т.к. ни один проект даже не с++11) но мозги сами по себе впитали. а синтакс там еще хуже.
HEymHblu_nemyx 27.02.2019 01:10 # 0
roman-kashitsyn 18.08.2017 11:49 # +2
1) в нодах можно хранить не только int
2) размер указателя можно вычислять в компайл-тайме из размера пула
j123123 18.08.2017 12:29 # 0
roman-kashitsyn 18.08.2017 12:32 # +1
Мы все видели, что ты можешь. Память только не забудь правильно почистить. А потом попробуй оформить свой генератор в реюзабельную библиотеку.
j123123 18.08.2017 12:44 # 0
Я могу и напитон перейти, если память будет лень чистить. Вообще, в компилтайм-метушне на шаблонах нигде память не чистится вообще никак (ни руками, ни через GC) и при этом никого это особо не волнует, почему я об этом думать должен? Так что можно просто смело срать в память, а потом пусть оно само чистится операционкой после завершения процесса кодогенерации.
roman-kashitsyn 18.08.2017 12:55 # 0
j123123 18.08.2017 13:08 # 0
Dummy00001 18.08.2017 13:18 # 0
самые успешние кодогены которые я писал, они все были одно-целевые.
я написал как то раз генератор юнит тестов, который мог буквально всё. я пытался его еще чистым держать, но тим хотела больше - и через пару итераций все обросло говном. и на него через какое-то время просто забили, потому что всех задрало гадать какой комбинацией опций конфигурации достигается какой эффект. просто - им мало было. сложно - они не могут.
не писать в ручную приятно - но люди забывают что они теряют контроль над кодом. если переходишь какую то невидимую грань - то кодген становится говном, потому что на него больше не возможно полагатся.
ЗЫ а лисп сюда припихивать просто не правомерно. с убогим препроцессором ц/крестов, сравнинивать с лиспом просто нечестно.
j123123 18.08.2017 13:31 # +1
Dummy00001 18.08.2017 13:36 # 0
в смысле - интересно сколько минут понадобится про-лисперу что бы написать интерпретатор ц?
ЗЫ гото?.. почитай книжки по компиляции - ты похоже пытаешь переизобрести BBs (basic blocks).
Dummy00001 18.08.2017 13:40 # +1
... хм. вспоминаю что сам подобным мозги себе разминал. остановился на том что лиспа сильно не знаю, и вещи типа указателей (передача по ссылке/по значению) сложно переносить (потому что их в лиспе в принципе нет).
roman-kashitsyn 18.08.2017 13:45 # 0
Сразу видно, что ты на лиспе не пишешь, а гомоиконы в суе поминаешь. Лисперу бы такой синтаксис для присваивания точно бы в голову не пришёл. Потому что во всех лиспах это проверка на равенство (чисел).
j123123 18.08.2017 14:02 # +2
Но поскольку я пытаюсь сишку сделать лиспом, проверка равенства у меня будет ==
CHayT 18.08.2017 14:13 # 0
j123123 18.08.2017 14:15 # 0
CHayT 18.08.2017 16:56 # 0
j123123 18.08.2017 17:02 # 0
Да и вот eval в контроллер же фиг впихнешь, раз там архитектура гарвардская. Разве что на шитом коде делать, но это для анскиллябр, к тому же много флеша отхавает
CHayT 18.08.2017 17:45 # 0
Знаю кучу людей (включая себя любимую), которые которые кудовские ядра генерят напитоне, схемке и прочих абсолютно анскилльных языках.
В haskell целые language-c и language-c-quote есть.
subaru 18.08.2017 18:24 # 0
CHayT 18.08.2017 18:27 # 0
(Это было на другой работе)
bormand 10.05.2021 19:59 # 0
И что? Ты же будешь гомоиконить на хосте, а на контроллер пихать уже готовый результат, параметризованный под конкретную задачу.
Тут главное как-то провести грань между компайлтаймом и рантаймом. И GC в компайлтайме -- это офигенно удобно. А в рантайме выжившие данные станут какими-нибудь массивами констант.
j123123 10.05.2021 20:07 # 0
Да, я про это еще в 2017 году написал, посмотри выше мой комментарий.
> j123123 18.08.2017 16:02 # 0
> Для компилтайм-метушни можно и GC с жирным рантаймом поиспользовать, а когда все окончательно скомпилируется, можно и без GC сделать результат, чтоб в контроллер впихнуть.
roman-kashitsyn 06.01.2018 14:27 # 0
COWuTEJIbTBOEuMAMKu 08.01.2018 10:37 # 0