Forth и другие саморасширяющиеся системы программирования Locations of visitors to this page
Текущее время: Ср июн 18, 2025 03:39

...
Google Search
Forth-FAQ Spy Grafic

Часовой пояс: UTC + 3 часа [ Летнее время ]




Ответить
Имя пользователя:
Заголовок:
Текст сообщения:
Введите текст вашего сообщения. Длина сообщения в символах не более: 60000

Размер шрифта:
Цвет шрифта
Настройки:
BBCode ВКЛЮЧЕН
[img] ВЫКЛЮЧЕН
[flash] ВЫКЛЮЧЕН
[url] ВКЛЮЧЕН
Смайлики ВЫКЛЮЧЕНЫ
Отключить в этом сообщении BBCode
Не преобразовывать адреса URL в ссылки
Вопрос
Теперь гостю придется вводить здесь пароль. Не от своей учетной записи, а ПАРОЛЬ ДЛЯ ГОСТЯ, получить который можно после регистрации на форуме через ЛС.:
Этот вопрос предназначен для выявления и предотвращения автоматических регистраций.
   

Обзор темы - Трансляторы Си в Форт
Автор Сообщение
  Заголовок сообщения:  Re: Трансляторы Си в Форт  Ответить с цитатой
А дальше еще смешнее. :)
Зашил интерпретатор в Форт-процессор в ПЛИС, частоту поставил 1.5MHz, тест с ферзями выполняется за 2:16. Если сравнивать с соседями по турнирной таблице отсюда https://www.hpmuseum.org/cgi-bin/articles.cgi?read=700 (рассматривал только те, которые на бейсике и для которых в этом же документе указана частота процессора)
Код:
2:45 SHARP             PC-1248                          @ 1.024MHz
2:29 TEXAS INSTRUMENTS CC-40                  TMS70C20  @ 2.5MHz
2:18 TEXAS INSTRUMENTS TI-74 BASICALC         TMS70C46  @ 2MHz
2:00 ЭЛЕКТРОНИКА       МК-85 (Fast Mode x5.3) КА1013ВМ1 @ 0.36x5.3=1.9MHz
, то мой подопечный смотрится вполне достойно
Код:
2:16                                          f44       @ 1.5MHz
При этом сам бейсик скомпилирован самодельным транслятором Си, качество кода на выходе которого оставляет желать лучшего. Но главное, что текст программы в моем случае пока хранится в неизменном текстовом виде, в то время как в ретро-бейсиках для экономии места и увеличения скорости традиционно выполняется "предварительная компиляция": команды языка кодируются одним байтом, числа и адреса прыжков переводятся в двоичный вид и т.д. Т.е. сейчас каждый раз для интерпретируемого слова выполняется сравнение строк (вместо многократно более быстрого сравнения чисел), при каждом прыжке заново производится поиск метки (снова сравнение строк!) в тексте программы (вместо того, чтобы один раз при запуске вычислить адрес перехода и дальше прыгать по этому адресу), а числа каждый раз набиваются поразрядно домножением текущего значения на 10 и добавлением очередного разряда (вместо того, чтобы однократно перегнать число из текстового представления в двоичное). И боюсь даже представить, как сильно вырастет скорость, если переписать интерпретатор BASIC на Форте/ассемблере и/или реализовать предварительную компиляцию. :)

Изображение
ссылка на изображение
Изображение
ссылка на изображение
Сообщение Добавлено: Вт июн 03, 2025 12:29
  Заголовок сообщения:  Re: Трансляторы Си в Форт  Ответить с цитатой
:) Немного подлечил транслятор basic-в-esoteric forth.
http://totalvacuum.ru/UB/ubasic.zip
Раньше в нем были ровно те же ограничения, что и в целевой платформе (ef \ esoteric forth \): не умел компилировать 2/3/...-разрядные числа и переменные с именами c/b/h/s/x/o/g, т.к. эти имена были задействованы в библиотеке ввода-вывода. Теперь понимает и длинные числа и переменные a-z. А еще двухсимвольные операторы сравнения <= <> >= добавились в дополнение к односимвольным < = >. И операторы poke/push/pop, а также функция peek. Компилируется теперь под win, а не под dos. Но транслятор до сих пор так и весит в районе 100 строк, а в скомпилированном виде - 3 с хвостиком Kb.
Оно выглядит смешно и даже "игрушечно", но легко транслирует простые тесты или, например, калькуляторный тест с ферзями отсюда: https://www.hpmuseum.org/cgi-bin/articles.cgi?read=700 А вообще тут главное идея: трансляция с языка высокого уровня в форт-подобное представление - это просто. :)
Сообщение Добавлено: Пн июн 02, 2025 16:43
  Заголовок сообщения:  Re: Трансляторы Си в Форт  Ответить с цитатой
Victor__v писал(а):
Лесолёд
Достаточно спорное утверждение
Сообщение Добавлено: Чт май 29, 2025 21:13
  Заголовок сообщения:  Re: Трансляторы Си в Форт  Ответить с цитатой
Total Vacuum писал(а):
Запускаю программу
Код:
print "bezzlobie?"
Но выводит мистическое
Код:
hryukostyag!
К чему бы это?

Лесолёд
Сообщение Добавлено: Чт май 29, 2025 11:28
  Заголовок сообщения:  Re: Трансляторы Си в Форт  Ответить с цитатой
Запускаю программу
Код:
print "bezzlobie?"
Но выводит мистическое
Код:
hryukostyag!
К чему бы это?
Сообщение Добавлено: Чт май 29, 2025 11:25
  Заголовок сообщения:  Re: Трансляторы Си в Форт  Ответить с цитатой
Victor__v писал(а):
[*] CLEAR – очистка кэша
[*] LIST – создание списка
[*] RUN – запуск сторонней программы из оболочки форта[/list]

Наверное, это задумывалось как одна сверхмощная суперкоманда "начать с чистого листа", но Гоголь-переводчик сплоховал и выдал "clear list run" :)
Сообщение Добавлено: Чт май 29, 2025 00:51
  Заголовок сообщения:  Re: Трансляторы Си в Форт  Ответить с цитатой
Вот этот вот бейсик у меня накидан на скорую руку в нескольких вариантах:
- компилятор, транслирует в uf \ micro forth \ или ef \ esoteric forth \
- интерпретатор, исполняет код из файла через командную строку;
- интерпретатор, запускается в интерактивном режиме и ожидает ввода текста программы с клавиатуры
И только в последнем варианте нужны clear/list/run, более того, сюда же следует добавить exit.
Но вообще в каждом варианте примерно 100 строк и 3-5Kb в скомпилированном виде. При этом легко расширяется. Допустим, добавляем peek/poke, после чего спокойно запускаем калькуляторный тест с ферзями отсюда: https://www.hpmuseum.org/cgi-bin/articles.cgi?read=700
Типа такого:
Код:
1 let x = 0 let s = 0
2 let r = 8
3 let a = 3000
4 if x = r goto 18
5 let x = x + 1
6 poke ( a + x ) r
7 let s = s + 1
8 let y = x
9 let y = y - 1
10 if y = 0 goto 4
11 let t = peek ( a + x ) - peek ( a + y )
12 if t = 0 goto 14
13 if t < 0 let t = - t if x - y <> t goto 9
14 poke ( a + x ) ( peek ( a + x ) - 1 )
15 if peek ( a + x ) <> 0 goto 7
16 let x = x - 1
17 if x <> 0 goto 14
18 print s


А если еще добавить push/pop для передачи в функции/из функций параметров/результатов, то такой бейсик превращается в виртуальный процессор с регистрами a-z, командами перехода (goto), в т.ч. и по условию (if), подпрограммами (gosub/return), командами для доступа к памяти и периферии (peek/poke) и небольшим количеством арифметики :) Получится вполне достаточная для написания любых программ "система команд"
Сообщение Добавлено: Чт май 29, 2025 00:38
  Заголовок сообщения:  Re: Трансляторы Си в Форт  Ответить с цитатой
Цитата:
А вообще странно, что они сделали CLEAR/LIST/RUN частью спецификации.

Идём в ногу со временем [сарказм]

Я бы дал этим словам такой функционал
  • CLEAR – очистка кэша
  • LIST – создание списка
  • RUN – запуск сторонней программы из оболочки форта
Сообщение Добавлено: Ср май 07, 2025 17:27
  Заголовок сообщения:  Re: Трансляторы Си в Форт  Ответить с цитатой
Total Vacuum писал(а):
Вот есть такое: https://en.wikipedia.org/wiki/Tiny_BASIC
Грамматика в части операторов там совсем простая:
Код:
    statement ::= PRINT expr-list
                  IF expression relop expression THEN statement
                  GOTO expression
                  INPUT var-list
                  LET var = expression
                  GOSUB expression
                  RETURN
                  CLEAR
                  LIST
                  RUN
                  END

А вообще странно, что они сделали CLEAR/LIST/RUN частью спецификации. Скорее уж это команды редактора или даже операционной системы, но никак не самого языка. Где-то они могут быть полезны (например, при построчном вводе программы через терминал), а где-то полноценный встроенный редактор и запуск по F9, либо внешний редактор и интерпретация или компиляция файлов через командную строку, и вот здесь-то эти команды точно не нужны.
Впрочем, спецификация Tiny BASIC уходит корнями в покрытую мхом почтенную древность, так что простительно. :) В этом даже какой-то шарм безвозвратно ушедшей в прошлое 8-битной эпохи.
Ну а в текущих реалиях надо отделять мух от котлет: редактор (если он вообще нужен) будет отдельно, а интерпретатор (BASIC, Forth, любой другой или все сразу) - отдельно.
Сообщение Добавлено: Ср май 07, 2025 12:01
  Заголовок сообщения:  Re: Трансляторы Си в Форт  Ответить с цитатой
Собственно, лежит тут: http://totalvacuum/UB/ubasic.zip
Сам ubasic.c компилировал при помощи TCC, но должно любым сишным компилироваться. В скомпилированном виде весит 3K. В папке TEST пара тестов, перекомпилируются при помощи соответствующих *.bat по схеме basic => ef => asm => com, хотя можно и под win сделать, если транслятор ef \ esoteric forth \ подменить.
Натравил на него свой сишный транслятор, там меньше 2K исполняемый файл получается, правда это 16-битный com-файл. Для форт-процессора будет и того меньше, раза в 2, наверное.

Интерпретатор в 100 строк, скорее всего, не уложится, он будет сложнее компилятора, но точно не в разы.

Да, кстати, для добавления poke/peek (а это ведь по сути фортовские !/@) достаточно в stmt() перед label дописать строки
Код:
   if (t("poke"))   {expr(); expr(); op(ASSIGN);} else
   if (t("peek"))   {var(); expr(); op(LOAD); op(ASSIGN);} else

А, например, для push/pop:
Код:
   if (t("push"))   {expr();} else
   if (t("pop"))    {var(); op("!");} else

Хотя peek можно оформить в виде функции, чтобы была возможность использования в выражениях. В этом случае нужно добавить в prim() строку
Код:
   else if (t("peek")) {unary(); op(LOAD);}


Забавно будет, если по итогу интерпретатор BASIC на борту Форт-процессора в ПЛИС окажется шустрее спектрумовского :D
Сообщение Добавлено: Вт май 06, 2025 01:33
  Заголовок сообщения:  Re: Трансляторы Си в Форт  Ответить с цитатой
Hishnik писал(а):
Из добавляемого очень уж просятся именованные подпрограммы.
:) И да, есть возможность использования именованных подпрограмм. Например:
Код:
let r = 1
let n = 8
gosub fact
print r
end

fact
   let r = r * n
   let n = n - 1
   if n > 1 gosub fact
return
А всё потому, что поленился сделать обработку ошибок. В результате всё непонятное автоматически считается меткой. Лень - двигатель прогресса, однако. :)
Кроме того, строки не обязаны начинаться с метки, в строке допускается размещать несколько операторов и меток. И наоборот: допускается размещать опкод и операнды на разных строках. Т.е. в каком-то смысле полная свобода в оформлении кода.
Сообщение Добавлено: Пн май 05, 2025 23:26
  Заголовок сообщения:  Re: Трансляторы Си в Форт  Ответить с цитатой
Платформо-зависимые вещи убраны в отдельный файл в шапке:
Код:
#include "x86.h"

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
Транслируется в uf \ micro forth \ и ef \ esoteric forth \ :) При желании можно и напрямую в асм перегонять, достаточно лишь заменить соответствующие дефайны в подключаемом файле.
Например,
Код:
#define ADD    "+"
заменить на что-то вроде
Код:
#define ADD    "pop ax\npop bx\nadd ax,bx\npush ax\n"
и т.д.
В сумме 2 файла занимают ровно 100 строк :)

В версии под ef \ esoteric forth \ нельзя использовать двух- и более- значные числа, а также переменные c/b/h/s/x/o/g (они задействованы в stdio), ну а в остальном отличий нет.
Примеры выложу чуть позже здесь: [url]totalvacuum.ru/UB/ubasic.zip[/url]
Сообщение Добавлено: Пн май 05, 2025 23:13
  Заголовок сообщения:  Re: Трансляторы Си в Форт  Ответить с цитатой
Ну и операторы:
Код:
/* stmt */

void print () {
   token(); hold();
   if (s[0]=='"') {expr(); op(PUTS);} else {expr(); op(PUTH);}
}

int stmt () {
   if (n("")) return 0;
   if (t("print"))  {print();} else
   if (t("if"))     {cmp(); op(IF); stmt(); op(ENDIF);} else
   if (t("goto"))   {token(); printf(JMP,s);} else
/*   if (t("input"))  {var(); op(INPUT);} else */
   if (t("let"))    {var(); token(); expr(); op(ASSIGN);} else
   if (t("gosub"))  {token(); printf(CALL,s);} else
   if (t("return")) {op(RET);} else
/*   if (t("clear")||t("list")||t("run")) {} else */
   if (t("end"))    {op(EXIT);} else
                    {printf(LABEL,s); stmt();}
   return 1;
}

void main () {op(TARGET); while (stmt());}
clear/list/run в режиме "компиляции" не нужны, поэтому убрал. input тоже убрал, т.к. в ПЛИС реализация будет другая, а проверять пока можно и без него.
Сообщение Добавлено: Пн май 05, 2025 22:58
  Заголовок сообщения:  Re: Трансляторы Си в Форт  Ответить с цитатой
Разбор выражений:
Код:
/* expr */

void op (char *s) {printf(CMD,s);}

void expr ();

void prim () {
   if (t("(")) {expr(); token();}
   else {op(s); if ((s[0]>='a')&&(s[0]<='z')) op(LOAD);}
}

void unary () {if (n("-")) {unary(); op(NEGATE);} else prim();}

void mul () {
   unary();
   while (n("*")||t("/")) if (t("*")) {unary(); op(MUL);} else {unary(); op(DIV);}
   hold();
}

void expr () {
   mul();
   while (n("+")||t("-")) if (t("+")) {mul(); op(ADD);} else {mul(); op(SUB);}
   hold();
}

void cmp () {char r[3]; expr(); token(); strcpy(r,s); expr(); op(r);}

void var () {token(); op(s);}
Это следует читать так:
Выражение - это сумма слагаемых, слагаемое - это произведение множителей, множитель - это первичное выражение со знаком или без, а первичное выражение - это выражение в скобках, число или переменная.
Сообщение Добавлено: Пн май 05, 2025 22:53
  Заголовок сообщения:  Re: Трансляторы Си в Форт  Ответить с цитатой
Немного упростил себе жизнь на первом этапе, заменив expr-list и var-list на expr и var соответственно, еще токены пока надо вручную разделять пробелами, ну и then в операторе if убрал за ненадобностью. Все это пока не так принципиально. В итоге набросалось на скорую руку такое:

Сканер (потрошит исходник на отдельные лексемы):
Код:
/* scan */

char h = 0, c, s[32];

int gc () {return c = getchar();}

void hold () {h = 1;}

void token () {
   if (h) {h = 0; return;}
   s[0] = 0;
   while (gc()<'!') if (c==-1) return;
   s[0] = c;
   int p = 1;
   if (c=='"') do s[p++] = gc(); while (c!='"');
   else while (gc()>' ') s[p++] = c;
   s[p] = 0;
}

int t (char *x) {return !strcmp(s,x);}

int n (char *x) {token(); return t(x);}
Сообщение Добавлено: Пн май 05, 2025 22:50

Часовой пояс: UTC + 3 часа [ Летнее время ]


Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group
phpBB сборка от FladeX // Русская поддержка phpBB