|
Временно недоступен
957 / 228 / 14
Регистрация: 12.04.2009
Сообщений: 926
|
|||||||||||||||||||||||||||||||||||||||||||||||||||
Пишем свой интерпретатор языка BASIC20.06.2009, 20:03. Показов 253370. Ответов 464
Метки нет (Все метки)
Благодаря форуму и Evg в частности интерпретатор развивается, потихоньку превращаясь в простенький интерпретатор QBASIC.
Некоторые из самых старых версий сохранились в теме и ссылки на них будут добавлены в это сообщение,а также ссылки на другие темы,связанные с этой. Репозиторий с проектом находится тут, там же есть возможность в браузере посмотреть историю ревизий (английский в логах весьма примитивен,комментарии и рекомендации можете писать в личку),а также скачать самый последний архив репозитория в формате .tar.gz Если кто-то пользуется Subversion,скачать исходники можно так:
Технический приём для формирования согласованных данных https://www.cyberforum.ru/c-linux/thread46096.html Вопрос по svn (Subversion) Создание системы тестирования ПО. Вопрос про разные реализации бэйсиков Можно ли выразить порядковый номер элемента массива через индексы? [C++] Какие флаги указать линкеру для компиляции программы? Как можно определить переменную в файле configure.in,чтобы её можно было использовать в Makefile? Странный SIGSEGV, или что зависит от порядка написания интерфейса класса https://www.cyberforum.ru/c-linux/thread61324.html Альтернативная версия интерпретатора от Evg на C Это простая реализация разбора выражений, написанная Evg на C: Представление выражения в двоичном дереве ***************** Первое сообщение: ***************** Задание(Страуструп,из книги,по готовому коду): Введите программу калькулятора и заставьте её работать.Например,при вводе
LexicalAnalyzer.h
LexicalAnalyzer.cpp
main.cpp
Анализатор-то работает,но конечное значение не вычисляется.Более того,если вводим
Добавлено через 2 часа 5 минут 30 секунд Пришлось решать влоб с дебаггером.У Страуструпа опечатка (или намеренная ошибка,что более вероятно ) Вот в этом куске кода в функции get_token():
Добавлено через 16 минут 19 секунд И ещё опечатка была
31
|
|||||||||||||||||||||||||||||||||||||||||||||||||||
| 20.06.2009, 20:03 | |
|
Ответы с готовыми решениями:
464
Пишем свой интерпретатор языка BASIC
Пишем свой чекер |
|
Временно недоступен
957 / 228 / 14
Регистрация: 12.04.2009
Сообщений: 926
|
|
| 26.10.2009, 22:34 [ТС] | |
|
Да,вот интересно,под виндой работает намного быстрее,причём только в полноэкранном режиме,хотя и не дотягивает до натурального QBASIC-а.
Возможно,тут уже ничего не сделаешь,это уже библиотека так работает видимо,но всё же со временем надо будет попытаться ускорить хоть чуть-чуть. Небольшое напутствие,если делать линию через цикл от края до края,то почему-то нельзя указывать размер границы,видимо происходит выход запределы экрана и программа падает(скорее всего это в самой SDL)
0
|
|
|
|
|
| 26.10.2009, 23:29 | |
|
Со скоростью сделать можно, надо только разобраться. На SDL'е написан FreeCraft - по сути переделка 2-го warcraft'а под линух. Всё там шустро бегало. Надо только разобраться, как эта бодяга работает
1
|
|
|
Временно недоступен
957 / 228 / 14
Регистрация: 12.04.2009
Сообщений: 926
|
||||||
| 28.10.2009, 06:55 [ТС] | ||||||
|
Попробовал улучшить немного со скоростью,так,по мелочи поменял,но вроде эффект есть.Вот можешь проверить таким вот тестом.Алгоритм аппроксимации(так вроде?) линии содрал прямо с вики,там используется битовая арифметика,я пока не очень понимаю,зачем там сдвиги на 12 позиций и прочее,надеюсь потом пойму.
0
|
||||||
|
|
|
| 28.10.2009, 09:56 | |
|
Ты заметил, что когда рисуешь по точкам через PRESET, то тормозит, а когда через LINE - то практически мгновенно. Т.е. проблему я вижу в концепции SDL. Насколько я понимаю, подобные библиотеки работают через некий виртуальный монитор. Т.е. все точки ты сначала наносишь в этот монитор (который попросту лежит в обычной памяти), и эти операции являются быстрыми. Затем ты этот монитор отображаешь в реальную картинку. Делается это путём ПОЛНОГО обновления виртуального монитора на реальную картинку. Этот процесс уже "медленный" (по сравнению с помещением точки в виртуальный монитор)
В случае, когда ты рисуешь по точкам, получается, что для происовки линии из 100 точек тебе нужно 100 раз обновить экран. Когда ты рисуешь линию, то сначала все 100 точек линии отображаются в виртуальный монитор, и затем один раз обновляются. Т.е. в теории нарисовать линию из 100 точек работает в 100 раз быстрее, чем рисовать 100 точек Библиотека видно написана всё-таки для игрушек. Поскольку игрушки как правило отображают экран по тикам. Т.е. (к примеру) 60 раз в секунду рассчитывается картинка, при этом она сначала рисуется по точкам в виртуальный монитор (т.к. эти операции быстрые), а затем картинка отрисовывается на экран (медленная операция, но 60 раз в секунду успевает). Для интерпретатора такое поведение неудобно, потому что у тебя нет точек привязки, по которым можно отображать картинку из виртуального монитора на реальный. В качестве эксперимента можешь ввести дополнительный оператор в бэйсике, который перенесёт виртуальный монитор на реальную картинку, а все точки ставить строго в виртуальном мониторе. Этот эксперимент нужен лишь для того, чтобы проверить догадку. Если она оправдается, то надо придумать механизм, как это работало бы нормально. Т.е. видимо всегда всё будет рисоваться в виртуальный монитор, при этом асинхронно по таймеру виртуальный монитор будет отображаться в картинку Добавлено через 5 минут Ещё надо какую-нить операцию для паузы (опять-таки можно врЕменную), чтобы картинка не удалялась. А то если вставить бесконечный цикл, то программу только по kill -9 смог убить. INPUT так и не понял, как правильно писать
1
|
|
|
Временно недоступен
957 / 228 / 14
Регистрация: 12.04.2009
Сообщений: 926
|
|
| 28.10.2009, 18:40 [ТС] | |
|
Насчёт обновления картинки ты прав на все 100.Прямо в точку.Подозрение пало как раз на функцию SDL_UpdateRect(x,y,w,h) и я прочитал в интернете как многие жаловались на медленную работу графики с этой функцией.
В качестве средства предлагалось добавить флаг SDL_DOUBLEBUF при выставлении режима видео,а также создавать поверхность не в системной памяти,а в видеопамяти.После чего просто использовать функцию SDL_Flip,которая делает замену между первым и вторым буфером,происходит это довольно быстро.Но всё же она ждёт вертикальной синхронизации,и в некоторых случаях SDL_UpdateRect может работать быстрее. Но самое правильное-это таймер. В общем пока для пикселей используется SDL_UpdateRect и обновляет только один пиксель,который рисуется,а для линий тоже SDL_UpdateRect ,только обновляется только четырёхугольник,диагональю которого является рисуемая линия. Но ты всё правильно сказал-нужен таймер,чтобы обновлял всю картинку с помощью SDL_Flip с постоянной частотой,например 30-35 кадров в секунду,и сделать это следует безусловно,иначе графика попиксельно(да и вообще)будет относительно тормознутой.Благо таймер в SDL существует как отдельная подсистема,и его можно просто подключить. Насчёт паузы после рисования-в самом QBASIC-е после рисования картинки появляется надпись "Нажмите любую клавишу для продолжения",поэтому надо будет как-то писать текст внизу поверх картинки или что-то такое. Добавлено через 19 минут А ещё забыл сказать:дело ещё не только в этом - как оказалось,у меня почему-то режим с глубиной цвета 16бит(слабо представляю,что это вообще) жутко тормозит,а когда делаешь 32бит,то всё намного быстрее.Так вот я добавил флаг SDL_ANYFORMAT,так что теперь есть предпочтение на 16бит,но если в силу каких-либо причин этот режим не очень подходит,библиотека сама подберёт лучший режим.
0
|
|
|
Временно недоступен
957 / 228 / 14
Регистрация: 12.04.2009
Сообщений: 926
|
|
| 30.10.2009, 23:30 [ТС] | |
|
Что-то пока никак не соображу,как же работают таймеры.Вот есть программа,с каким-то списком инструкций.А где-то есть функция,запускающая таймер и следящая за временными отрезками.Но ведь программа не состоит из одной этой функции,как тогда обновляется таймер вовремя? Или сам таймер должен работать как отдельный процесс,или я не знаю.Какая там концепция?
0
|
|
|
|
|
| 30.10.2009, 23:45 | |
|
Вообще концепция по идее такая, что процесс вызывает ядро и говорит "разбуди через 10 миллисекунд", через 10 миллисекунд выдаётся сигнал, программа прерывается и вызывается пользовательский обработчик сигнала (см. sigaction). Но я не знаю, насколько такое быстро работает, к тому же это линух-зависимое
Что касается встроенной возможности в SDL, то я как-то не понял (правда особо и не разбирался). Но там они пишут, что это замедляет работу, но в SMP этого замедления не будет. SMP, насколько я понимаю, это многопроцессорная машина, а потому вполне возможно, что запускают ещё один процесс
1
|
|
|
Временно недоступен
957 / 228 / 14
Регистрация: 12.04.2009
Сообщений: 926
|
|||||||||||||||||||||
| 31.10.2009, 08:02 [ТС] | |||||||||||||||||||||
|
Как раберусь,сделаю таймер.
Пока делал опции для LINE столкнулся с проблемкой: Синтаксис LINE описывается так (Источник,которым пользуюсь):
Поэтому временно синтаксис LINE:
Пока нет проверки на рисование за границы экрана,поэтому сразу говорю,неправильные данные рушат SDL.Пока не решил,где и как именно сделать проверку,но это мелочи. Небольшой тест
P.S. >Ещё надо разбираться с тем, что если программа зациклилась на интерпретации в то время, как работает графический режим, то кроме как по kill -9 она не убивается А что вообще можно с этим сделать? Какие есть выходы из ситуации? Делать интерпретатор работающий с threads?
0
|
|||||||||||||||||||||
|
|
||||
| 31.10.2009, 11:51 | ||||
|
Добавлено через 3 минуты
1
|
||||
|
Временно недоступен
957 / 228 / 14
Регистрация: 12.04.2009
Сообщений: 926
|
|
| 02.11.2009, 12:23 [ТС] | |
|
Помнишь,ты писал,что отдельный графический интерфейс делается в виде библиотеки .so или .dll? А что должно быть внутри библиотеки? Как именно она должна взаимодействовать с консольным приложением? Есть ли там функция main,всмысле это тоже отдельная программа? Я поискал,некоторые советуют делать общение GUI с программой через сокеты.Но в тоже время есть класс в Qt,называется QProcess,и он предназначен для запуска внешних программ.Значит,если в таком варианте,нужно разработать ещё одно приложение с окнами,которое будет обрабатывать события и запускать что нужно с необходимыми опциями командной строки.Но тогда это уже нельзя сделать в виде .so?
0
|
|
|
|
|
| 02.11.2009, 15:38 | |
|
Динамическая библиоткеа - это по большому счёту часть кода, вынесенная отдельно. Это экономит дисковое пространство, т.к. динамическая библиотека есть в единственном экземпляре и нет необходимости статически линковать к каждому бинарнику
Второй бонус динамической библиотеки - это возможность её подключения прямо во время работы программы О чём говорил я "тогда" - толком уже и не помню. Но смысл скорее всего сводится к тому, что ты заводишь некий абстрактный интерфейс для работы с графикой. Грубо говоря, это процедуры типа "инициализировать графику", "нарисовать точку в виртуальное окно", "отобразить виртуальное окно на физическое" и т.п. - т.е. набор низкоуровневых примитивов. Далее ты можешь создать динамическую библиотеку, которая реализовывает этот интерфейс через SDL, потом другую библиотеку, которая реализовывает этот интерфейс через что-то другое. Т.е. для твоего интерпретатора получается до фонаря, что там делается на низком уровне и какая реально графическая библиотека используется, он работает с предоставленным интерфейсом В какое-то время, глядя на твои заслуги по части графики у меня зачесалась ж..а и я тоже что-то там сделал, но в итоге опять забил. Т.е. сейчас всё находится в некотором устаканившемся состоянии, можешь попробовать посмотреть. 1. Сейчас FOR сделан несколько через ж...у (там вроде бы только целочисленный положительный STEP поддерживается) 2. В SCREEN можно подать любое число (пока оно игнорируется, реально должно отрабатываться в __rt_graph_SCREEN. Выхода обратно в текстовый режим пока нет 3. Обрати внимание на то, как реализованы PRINT, синусы-косинусы, графика с точки зрения реализации в виде процедур - для движка промежуточного представления всё это выглядит в виде одной и той же конструкции. При этом в операции вызова я список аргументов печатаю в квадратных скобках (чтобы не мельтешило в глазах с круглыми скобками от выражений) - запускай "./interp -s" 4. Обрати внимание, как у меня на нижнем уровне (runtime) реализована графика: разбор непосредственно бэйсиковской реализации отдельно, работа с графической библиотекой отдельо, алгоритмы прорисовки отдельно 5. Всё то, что находится в graph_sdl.c по большому счёту и есть та динамическая библиотека, о которой я писал выше. Если заменить префикс sdl_ на что-нибудь другое, то мы как раз и получим тот абстрактный интерфейс нижнего уровня. Всё, что находится за пределами модуля sdl_graph "не знает" о том, что мы работаем с библиотекой SDL 6. Пока по прежнему на вход читаем файл a.txt. Опции, которые на данный момент могут тебе показаться интересными Пользовательские: -w трассировка записей -e трассировка исполнения -u по умолчанию все переменные прописываются undef'ами (для отладки неинициализированных значений) Внутренние: -s печать промежуточного представления Остальные опции увидишь в main.c но они тебе особенно не интересны
1
|
|
|
|
|
| 13.11.2009, 14:14 | |
|
Оказывается, я тебе наврал про реализацию двухаргументных арифметических операций. Я почему-то всю жизнь считал, что в Си второй аргумент приводится к типу первого. Оказывается это не так. Из двух аргументов выбирается "более широкий тип" и оба аргумента приводятся к этому типу (а точнее, приводится только один из аргументов, ибо второй имеет этит тип) и результат имеет этот самый более широкий тип. Считается, что плавающий тип шире целого
Т.е. я утверждал, что INT + FLOAT эквивалентно (int) (INT + (int)FLOAT), на самом деле это (float) ((float)INT + FLOAT). Т.е. поведение в этом месте бэйсика и Си совпадают. Собственно из-за неправильной реализации у меня коряво работала картинка с синусами и косинусами - мне приходилось заводить плавающие константы
1
|
|
|
|
||
| 14.11.2009, 12:43 | ||
|
1
|
||
|
Временно недоступен
957 / 228 / 14
Регистрация: 12.04.2009
Сообщений: 926
|
|
| 16.11.2009, 11:45 [ТС] | |
|
А я не осваивал.Там в документации есть примеры (с исходниками),я просто взял за основу исходники окошка с подсветкой кода,немного поменял его (там понятный код,правда шаблоны знаков ("регекспы") пришлось методом тыка делать).Ещё там рядом есть пример,но с ToolBar-ом с кнопочками-иконками,я оттуда перенёс этот тулбар.
Сначала-то я вообще не знал,с чего начинать,то ли .ui файл делать с дизайнером,то ли ещё как-то.Тыкался,тыкался,пока не содрал из документации.В-общем,хотел как лучше,а получилось как всегда
0
|
|
|
|
|
| 16.11.2009, 12:05 | |
|
Понятно. Тогда придётся всё-таки осваивать. Ибо для полного счастья надо ещё и отладчик встроенный сделать. Ну а потом остаётся тупое развитие и добавление новых инструкций языка
Добавлено через 55 секунд Кстати, у тебя как сечас сделано? И gui, и интерпретатор всё в одном флаконе? По идее нормально должно быть так, что интерпретатор отдельно, а гуй отдельно и из гуя вызывается (запускается) интерпретатор
1
|
|
|
Временно недоступен
957 / 228 / 14
Регистрация: 12.04.2009
Сообщений: 926
|
|
| 16.11.2009, 23:31 [ТС] | |
|
Ой,а у меня наоборот )). Я просто подумал,что консольный вариант главный,gui только как опция.Ну ещё от незнания,что-то я сразу не представил вариант,когда gui вызывает консольное приложение.Просто тогда получается,что нужно все исходники интерпретатора вкладывать в проект GUI (это мне так видится).Или как иначе? В Qt же по нажатию на кнопку нужно вызывать функцию из интерпретатора,а как её туда "приделать"?
0
|
|
|
|
||
| 16.11.2009, 23:57 | ||
|
Нормально должно быть так. Отдельно пишется интерпретатор (т.е. то, что у тебя было до гуя). Отдельно пишется графическая оболочка с редактором. Далее в этой графической оболочке при нажатии на клавишу "Run" у тебя записывается редактируемый файл с исходником (чтобы все правки подцепились), после чего запускается "basin source.bas". По завершении исполнения программы анализируем код возврата: если у нас отработало нормально, значит передаём управление обратно на редактор. Если завершилось с ошибкой, то анализируем выдачу от интерпретатора в stdout: парсим то, что он напечатал (вырезаем имя файла и номер строки), позиционируем курсор на той строке исходника и где-то отображаём полную выдачу ошибки от интерпретатора
В нормальном случае делается так, что отдельной поставкой выдаётся интерпретатор (как логически законченная программа), а дополнительной поставкой ставится гуй, в качестве настройки которому надо указать, где лежит интерпретатор. И как вариант делается некоторая полная поставка, включающая в себя оба компонента. Технически удобнее держать исходники в разных каталогах: интерпретатор отдельно, гуй отдельно. Делать это в одном репозитории или в двух разных - хз как удобнее. Для начала делай так, как удобнее, а там будет видно, как надо правильно
1
|
||
| 16.11.2009, 23:57 | |
|
Помогаю со студенческими работами здесь
240
пишем свой троян с нуля Пишем свой класс, спецификатор доступа protected Интерпретатор небольшого языка программирования на С++ Не удается откомпилировать интерпретатор М-языка
Искать еще темы с ответами Или воспользуйтесь поиском по форуму: |
|
Новые блоги и статьи
|
|||
|
Первый деплой
lagorue 16.01.2026
Не спеша развернул своё 1ое приложение в kubernetes.
А дальше мне интересно создать 1фронтэнд приложения и 2 бэкэнд приложения
развернуть 2 деплоя в кубере получится 2 сервиса и что-бы они. . .
|
Расчёт переходных процессов в цепи постоянного тока
igorrr37 16.01.2026
/ *
Дана цепь постоянного тока с R, L, C, k(ключ), U, E, J. Программа составляет систему уравнений по 1 и 2 законам
Кирхгофа, решает её и находит токи на L и напряжения на C в установ. режимах до и. . .
|
Восстановить юзерскрипты Greasemonkey из бэкапа браузера
damix 15.01.2026
Если восстановить из бэкапа профиль Firefox после переустановки винды, то список юзерскриптов в Greasemonkey будет пустым.
Но восстановить их можно так.
Для этого понадобится консольная утилита. . .
|
Изучаю kubernetes
lagorue 13.01.2026
А пригодятся-ли мне знания kubernetes в России?
|
|
Сукцессия микоризы: основная теория в виде двух уравнений.
anaschu 11.01.2026
https:/ / rutube. ru/ video/ 7a537f578d808e67a3c6fd818a44a5c4/
|
WordPad для Windows 11
Jel 10.01.2026
WordPad для Windows 11
— это приложение, которое восстанавливает классический текстовый редактор WordPad в операционной системе Windows 11. После того как Microsoft исключила WordPad из. . .
|
Classic Notepad for Windows 11
Jel 10.01.2026
Old Classic Notepad for Windows 11
Приложение для Windows 11, позволяющее пользователям вернуть классическую версию текстового редактора «Блокнот» из Windows 10. Программа предоставляет более. . .
|
Почему дизайн решает?
Neotwalker 09.01.2026
В современном мире, где конкуренция за внимание потребителя достигла пика, дизайн становится мощным инструментом для успеха бренда. Это не просто красивый внешний вид продукта или сайта — это. . .
|