Сегодня смог усесться и пописать Иколайси. Теперь есть поддержка вложенных структур, то есть что-то типа такого:
@define stsup as struct {
	s32 v0;
	s32 v1;
};

@define st as struct {
	u8 a;
	u8 b;
	stsup c;
};

func () main {
	st v;
	
	v.a = 5;
	
	st* vptr = &v;
	vptr->b = 12;
	
	v = vptr->;
	vptr-> = v;
	
	v.c.v1 = 54;
};

Также подправил взаимодействие с указателями. Но мог сломать некоторую индексацию переменных.
Я ещё посмотрел случайно в центр треда и увидел, что когда-то даже for запилил. С тех пор прошло много времени и компилятор был переписан, а вместе с ним и for пропал. Надо будет его снова ввести. И всяких yield и исключений в стандарте нет.

Но я думаю над тем, как следует пользователям сигнализировать об ошибках. Пока что у меня в стандарте есть assert. Это должно будет вызывать аварийное завершение программы + вывод ошибки. Я считаю так, что программа не должна иметь ошибки и поэтому надо теребить программиста исправлять их, а главное это показывать, где они. А чтобы проверять правильность аргументов, вызывать функцию, проверяющую её. Например, если где-то будет функция умножения матриц произвольного размера, то надо чтобы ширина и высота в некотором порядке совпадали. То есть, если не будут совпадать, то вызов assert. А для проверки можно использовать функцию проверки. Причём, я собираюсь ввести такую фичу, чтобы названия некоторых функций могли начинаться с оператора. И можно будет сделать m0 *.check m1, чтобы не писать какое-нибудь громоздкое MatrixMulCheck(m0,m1).
Но точно ли только такой подход нужен? Что если ошибка не простая как в случае умножения матриц? Что если это обращение к какому-то API и там штук 400 сообщений для каждого из типа ошибки. Программисту не захочется обрабатывать каждый случай. Можно было бы ввести try, except и raise для исключений, чтобы программа хандлила эти ошибки и уже в зависимости от прихотей программиста слала их сообщения в консольку, на клиент пользователю или в ГУИ-приложение. Но может лучше давать делать это и просто функцией для проверки аргументов и всего такого. Пусть она возвращает строку с ошибкой вместо raise или assert. К тому же, ввести исключения не так уж и просто, это придётся ввести поддержку потоков, чтобы для каждого создавать свою скрытую глобальную переменную, которая содержит инфу для setjmp. Наверное. Да и какие-то странные эти исключения, не хочу их.
Кстати, вспомнил вредные исключения, которые получаются в pyparsing. Это питон-модуль для парсинга и так там можно на грамматическое правило сделать функцию проверки, которая из одних аргументов (строк, например) сделает другие (объект). А если вызовет исключение, значит правило не прошло проверку. И когда у меня были исключения от всяких key error или index out of range в обычных питоновских переменных, то я не понимаю, где ошибка.

Ещё я раздумывал о том, как сделать встроенную функцию суммы. Я хочу, чтобы лаконично записанной операцией можно было посчитать значений операндов, как если бы между ними был некоторый оператор. То есть sum(ops[:4]) это ops[0] + ops[1] + ops[2] + ops[3]. Но я хочу, чтобы не только + можно было поставить. Раньше я думал сделать это так, чтобы можно было свой оператор поставить в sum(). То есть sum(ops,+) или sum(ops,-) или sum(ops,*). Но это как-то тупо выглядит. Пересылать операторы, серьёзно? И вот я придумал такой синтаксис: ops{operator}. То есть ops[0:10]{+} это сумма 10 элементов ops, ops[1:10]{*} это факторил девяти. И чтобы можно было переслать подходящую функцию ops[0:10]{myfunc}.
Ещё надо бы какой-нибудь аттрибут для таких функций придумать, которые показывают, а можно ли аргументы мешать местами. Если можно, как скалярные числа, то такое вычисление можно будет распараллелить. А если нет и это как умножение матриц, то нельзя. Таким же образом можно будет и одну функцию перегруженного оператора сделать для, например, вектор*скаляр и и скаляр*вектор.

надеюсь сдешняя разметка не съест звёздочки...