Comments 26
А как это всё запускать, собирать? Есть пример, инструкция?

Да, именно так, ранняя стадия разработки.
Проект пишу ~4 месяца с чистого листа. За этот срок проделан значительный объем работ. Планирую основные работы по компилятору закончить в конце сентября. После чего накидаю минимум для RTOS(AVR) и высокоуровневый runtime. Даже в конце года проект будет максимум на стадии MVP(пока с поддержкой только AVR). Это слишком большой объем работ для одного человека. Я это осознаю, буду двигаться постепенно.
:) Немного торопитесь, проект на ранней стадии разработки. Пока не закончен кодогенератор(он оказался немного сложнее, чем я ожидал, тем не менее я надеюсь уложиться в срок и к концу сентября закончить кодогенерацию и навести порядок в семантике.
К примеру сейчас реализую кодогенерацию(для AVR) логических операций и операций сравнения для AVR в конструкции условных операторов
Я обязательно займусь документацией, примерами и тестами производительности, но скорее всего к концу года.
Статья/карма/подписка/Github: +/+/+/+.
Плюсы: + амбициозный проект; + это подлинное программирование.
Минусы: - маленькая аудитория (но в этом минусе плюс, что она хотя бы есть один пользователь проекта - сам автор); - нужно тянуть java, а это платформа с весьма "специфичным" "характером".
Автору — респект.
Вопрос — в чем преимущества применения восьмибитных архитектур при дешевизне 32 битных?
Я могу ошибаться в деталях, но в общем 8 бит мк, по моему личному мнению, имеют следующие преимущества:
дешевле, в больших партиях эта разница существенна.
меньше размерами
потребляют меньше тока
более устойчивы к ESD
Предиктивны (можно прогнозировать количество потраченных тактов/времени)
Менее сложные (меньше периферии, легче реализация функционала - например инициализация периферии или тактирования)
5 вольтовых входы выходы.
Больший ток входов выходов
Иногда это критично
Насчет "дешевле" могу не согласиться, 32-битки уже дешевле 8-биток, в особенности, AVR. AVR'в сейчас даже дороже.
А насчет надёжности да, надёжнее, за счет 5В и сильных портов, до 20 мА с пина
Стабильно есть в наличии и совместимость pin-to-pin даже переферии в пределах серии. Например в STM32 во времена кризиса чипов это было проблемой.
Господи, RTTI на 8-битках... где SRAM может доходить до нескольких десятков байт...
Очевидно, что высокоуровневый ООП язык на устройстве с десятками байт невозможен. Однако в проекте будет режим функций(без ООП). Проект также может быть полезен для реализации ASM программы. Так как включает в себя ассемблер-сборщик и наработанные библиотеки(в том числе и RTOS). Подключение кода будет только по необходимости.
Также прошу обратить внимание, что в моем решении минимальное потребление памяти для RTTI
*проект находится на ранней стадии разработки.
Не очень понятны две вещи:
Зачем проверка типов во время исполнения кода?
Зачем полиморфизм также во время исполнения кода?
Обычно такие вещи в runtime присутствуют либо в языках с виртуальной машиной и интерпретатором, либо:
информация о типах удаляется, так как код прошёл все проверки;
обобщённый код заменяется на специализированные варианты во время компиляции.
import Animal {
void makeSound();
}
class Dog implements Animal {
void makeSound() {...}
void toWag() {...}
}
class Cat implements Animal {
void makeSound() {...}
}
Animal myPet = getRandomAnimal(); // Может вернуть и Dog, и Cat
myPet.makeSound(); // Какая реализация метода должна быть вызвана?
if(myPet is Dog as dog) {
dog.toWag();
}
Проверка типов во время выполнения нужна для работы с полиморфными объектами, конкретный тип которых неизвестен на этапе компиляции и определяется динамически (по данным с датчиков, от пользователя, из сети и т.д.).
Runtime-полиморфизм нужен для единообразной работы с объектами через их общий интерфейс, без необходимости знать их конкретный тип.
Всё ещё не понятно: у вас статическая типизация? Значит все типы переменных известны заранее. А если что-то придёт из-вне неизвестное, то всё что вы можете сделать -- проигнорировать или упасть.
Пример с кошечками и собачками сомнительный: какой тип у getRandomAnimal()? Animal? Тогда будет вызываться Animal.makeSound(). Так?
Это не чисто статическая система. У интерфейса Animal нет реализации метода makeSound(). Конкретный метод(класса Dog или Cat) выбирается в runtime.
Это не интерпретация, а компиляция с сохранением метаинформации для динамической диспетчеризации.
Если я правильно понял, то это всё напоминает C++ с его абстрактными классами и виртуальными методами.
Я ориентируюсь на Java, но более упрощенную(без наследования классов, но с интерфейсами)
Мне, собственно, так же не хватает интерфейсов и их реализации в языках для встраиваемых систем. А название class сбивает с толку и направляет мышление в сторону ООП с классами...
Да, я использую синтаксис, похожий на Java, но с ключевым отличием: в моём языке нет наследования классов (нет extends для классов, кроме extends для интерфейсов). Наследование классов - слишком избыточно для 8 бит.
Поэтому слово class здесь означает ровно то же, что и final class в Java:
Это конечный (final) тип данных, который нельзя наследовать.
Это реализация состояния (поля) и поведения (методов).
Это единственный способ реализовать интерфейс (implements).
Вся полиморфная работа, ведётся только через интерфейсы. Класс же — это всего лишь «фабрика» для создания объектов, которые могут реализовывать эти интерфейсы.
Таким образом, это не «полноценное ООП с наследованием», а скорее «ООП в стиле композиции», где интерфейсы определяют контракты, а классы — их конкретные реализации. Название class я использую для привычности и краткости, понимая его именно в этом, более узком смысле.
И главное. Я практик, а Вы меня затягиваете на поле спора в теорию. Посмотрите на приведенный в статье код, он буквально объясняет как это работает и зачем это нужно.
i8051 добавить - т.к. на него тыщи кода.....
Оффтоп. Почему под atmega для описания режима работы переферии не используется Device Tree? Идеальный был бы подход, нет?
vm5277, пример компиляции для AVR