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

...
Google Search
Forth-FAQ Spy Grafic

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




Начать новую тему Ответить на тему  [ Сообщений: 78 ]  На страницу Пред.  1, 2, 3, 4, 5, 6  След.
Автор Сообщение
 Заголовок сообщения: Re: Генератор на Форте кода для C
СообщениеДобавлено: Пт апр 07, 2017 21:23 
vpn289 писал(а):
...
Еще один не умеющий читать "фортер"?


Вернуться к началу
  
Ответить с цитатой  
 Заголовок сообщения: Re: Генератор на Форте кода для C
СообщениеДобавлено: Пт апр 07, 2017 22:50 
Не в сети
Administrator
Administrator
Аватара пользователя

Зарегистрирован: Вт май 02, 2006 22:48
Сообщения: 7960
Благодарил (а): 25 раз.
Поблагодарили: 144 раз.
vpn289 писал(а):
Или это просто LATEST ? Которое кладет на стек nfa последнего определенного слова. При применении внутри определения кладет адрес поля имени самого этого определения.

Нет, идея в том, чтобы создать слово, кладущее на стек указатель на структуру. CREATE создает такие слова, что HERE уже будет на стеке при их выполнения. Что будет сделано дальше, определяется куском кода после DOES>.


Вернуться к началу
 Профиль Отправить личное сообщение  
Ответить с цитатой  
 Заголовок сообщения: Re: Генератор на Форте кода для C
СообщениеДобавлено: Пт апр 07, 2017 23:01 
Не в сети

Зарегистрирован: Вс мар 26, 2017 00:23
Сообщения: 40
Благодарил (а): 0 раз.
Поблагодарили: 0 раз.
Hishnik писал(а):
vpn289 писал(а):
Или это просто LATEST ? Которое кладет на стек nfa последнего определенного слова. При применении внутри определения кладет адрес поля имени самого этого определения.

Нет, идея в том, чтобы создать слово, кладущее на стек указатель на структуру. CREATE создает такие слова, что HERE уже будет на стеке при их выполнения. Что будет сделано дальше, определяется куском кода после DOES>.

Не понял. CREATE кладет на стек pfa. DOES> заменяет действие CREATE, подменяет поле кода слова, определенного через CREATE на действие после DOES>. Только перед действием по DOES> на стеке лежит еще pfa, слова определенного через CREATE. HERE там разный.
А как определена структура? Почитаю-ка тред еще.


Вернуться к началу
 Профиль Отправить личное сообщение  
Ответить с цитатой  
 Заголовок сообщения: Re: Генератор на Форте кода для C
СообщениеДобавлено: Пт апр 07, 2017 23:32 
Hishnik писал(а):
Конкретно, при использовании внутри слова оно должно класть на стек имя этого слова.

Hishnik писал(а):
Нет, идея в том, чтобы создать слово, кладущее на стек указатель на структуру.

Маркетоиды ошибок не признают-с! Хотя, скорее всего, он и в первый, и во второй раз писал, не думая...


Вернуться к началу
  
Ответить с цитатой  
 Заголовок сообщения: Re: Генератор на Форте кода для C
СообщениеДобавлено: Пт апр 07, 2017 23:45 
Не в сети
Administrator
Administrator
Аватара пользователя

Зарегистрирован: Вт май 02, 2006 22:48
Сообщения: 7960
Благодарил (а): 25 раз.
Поблагодарили: 144 раз.
vpn289 писал(а):
Не понял. CREATE кладет на стек pfa. DOES> заменяет действие CREATE, подменяет поле кода слова, определенного через CREATE на действие после DOES>. Только перед действием по DOES> на стеке лежит еще pfa, слова определенного через CREATE. HERE там разный.
А как определена структура? Почитаю-ка тред еще.

Стоп, разбираемся с начала. Что делает CREATE? Оно выбирает из входного потока имя и создает в словаре слово. Это слово сразу содержит код push xxx ret, где xxx - HERE на момент создания слова. CREATE часто ассоциируют с "конструкцией CREATE DOES>", но на самом деле DOES> не обязано каждый раз закрывать CREATE.

Вот такой пример создает массивы.

Код:
CREATE X[] 100 ALLOT
CREATE Y[] 100 ALLOT


X[] будет создан так, чтобы класть на стек, допустим, 10000. После этого совершенно независимая от CREATE конструкция 100 ALLOT передвинет HERE, и в момент вызова второй строчки Y[] будет создан так, чтобы класть на стек уже 10100.

Теперь что делает DOES>. Оно принудительно затирает последнюю команду (а это ret) в только что созданном слове и вписывает туда jmp на себя. Поэтому если мы определим константу, прямо в том виде, как описано у Баранова, то получится:

Код:
: CONSTANT CREATE , DOES> @ ;

5 CONSTANT ПЯТЬ


Итак, ПЯТЬ сначала положит на стек HERE (но не текущий, а тот, который был на момент его создания, т.е. это не вызов HERE, а просто число). Запятая после CREATE уже занесла в эту ячейку число со стека. Код слова ПЯТЬ после DOES> выглядит уже как push xxx jmp, и перейдет оно на "хвост" после DOES>. А там @. Поэтому ПЯТЬ сначала положит на стек адрес ячейки, где лежит значение константы, а потом прочитает на стек число из этого адреса памяти.

Вот такой нехитрый прием позволяет сделать много полезного. Оно выглядит как связанные действия, но таковыми не является.



За это сообщение автора Hishnik поблагодарил: dmitry-st
Вернуться к началу
 Профиль Отправить личное сообщение  
Ответить с цитатой  
 Заголовок сообщения: Re: Генератор на Форте кода для C
СообщениеДобавлено: Сб апр 08, 2017 00:18 
Не в сети

Зарегистрирован: Вс мар 26, 2017 00:23
Сообщения: 40
Благодарил (а): 0 раз.
Поблагодарили: 0 раз.
Hishnik писал(а):
Стоп, разбираемся с начала. Что делает CREATE? Оно выбирает из входного потока имя и создает в словаре слово. Это слово сразу содержит код push xxx ret, где xxx - HERE на момент создания слова.

Ох уж этот "момент" создания слова :) HERE во время создания слова указывает в несколько разных мест. По завершению работы CREATE, да, HERE указывает на поле параметров. (Хотя многие и не верят в поле параметров, но оно есть всегда :) Теперь ясно, что Вы имели ввиду.
Пусть теперь топикстартер поподробнее разъяснит задачу. Сдается мне некорректна она несколько. Или он или я за деревьями леса не видим.


Вернуться к началу
 Профиль Отправить личное сообщение  
Ответить с цитатой  
 Заголовок сообщения: Re: Генератор на Форте кода для C
СообщениеДобавлено: Сб апр 08, 2017 00:49 
Не в сети
Administrator
Administrator
Аватара пользователя

Зарегистрирован: Вт май 02, 2006 22:48
Сообщения: 7960
Благодарил (а): 25 раз.
Поблагодарили: 144 раз.
vpn289 писал(а):
HERE во время создания слова указывает в несколько разных мест. По завершению работы CREATE, да, HERE указывает на поле параметров.

HERE всегда возвращает адрес первой свободной ячейки в пространстве данных. При реализации Форта в машинном коде HERE вообще не изменяется при работе CREATE. При использовании шитого кода возможны разные варианты, зависящие от того, что именно разработчик хочет хранить в данных.


Вернуться к началу
 Профиль Отправить личное сообщение  
Ответить с цитатой  
 Заголовок сообщения: Re: Генератор на Форте кода для C
СообщениеДобавлено: Сб апр 08, 2017 11:17 
Не в сети

Зарегистрирован: Вс мар 26, 2017 00:23
Сообщения: 40
Благодарил (а): 0 раз.
Поблагодарили: 0 раз.
Hishnik писал(а):
HERE всегда возвращает адрес первой свободной ячейки в пространстве данных.

Да. Так точнее.
Hishnik писал(а):
При реализации Форта в машинном коде HERE вообще не изменяется при работе CREATE. При использовании шитого кода возможны разные варианты, зависящие от того, что именно разработчик хочет хранить в данных.

Ну тут каша какая-то. Вы явно пытаетесь мне объяснить очевидные вещи, но мне сложно следить за ходом Вашей мысли. Приходится переспрашивать.
Вы хотите сказать, что при написании форта на ассемблере (правильно я понял?) CREATE ничего не компилирует на вершину словаря (кодофайла)?
Я размышлял о системе с изолированными адресными пространствами. Отдельное для стека возвратов, отдельное для стека данных, отдельное для низкоуровневого кода, отдельное для кодофайла. Неоправданно сложно получалось.


Вернуться к началу
 Профиль Отправить личное сообщение  
Ответить с цитатой  
 Заголовок сообщения: Re: Генератор на Форте кода для C
СообщениеДобавлено: Сб апр 08, 2017 15:31 
Не в сети

Зарегистрирован: Пн ноя 05, 2007 13:54
Сообщения: 144
Благодарил (а): 0 раз.
Поблагодарили: 13 раз.
Задача на тему "дерева в памяти" мне показалась любопытной. Не буду сейчас поднимать вопрос практической целесообразности, в конце концов, написание программ на Форте часто сравнивают с разгадыванием головоломки в духе "Судоку".

Итак, за основу возьму описание структуры силами фортовского DSL, а на выходе создам "дерево в памяти", которое еще и распечатаю в виде S-выражения. Почему не в виде C-выражения? Так ведь надо же что-то (кроме вывода возможны и преобразования дерева) оставить и в качестве упражнения для читателя!

Я несколько отвык от Форта за последнее время, так что прошу простить мне "не идиоматический подход". В частности, я не собираюсь тратить время на определяющие слова и словари. Более того, мне и со SWAP, ROT и подобными фортизмами связываться не хочется. Поэтому начну я с реализации локальных переменных.

Код:
create locals 1024 cells allot
variable lptr  locals lptr !
: loc+ ( n) cells lptr +! ;
: loc ( i) lptr @ swap 2 + cells - @ ;
: loc! ( x i) lptr @ swap 2 + cells - ! ;
: loc: ( .. n) lptr @ >r 0 do lptr @ ! 1 loc+ loop
  r> lptr @ ! 1 loc+ ;
: loc; -1 loc+ lptr @ @ lptr ! ;


Никаких имен, только индексы. Код с применением таких конструкций не является читабельным, но, по крайней мере, его несколько удобнее писать.

Чем потенциально хороши DSL на Форте? Помимо последовательностей слов, разделяемых пробелами, достаточно выразительно выглядят "префиксные" выражения с использованием WORD. Но работу со строками в Форте удобной не назовешь. Тот же WORD сохраняет текст во временную область. Раз уж взялся за задачу, реализую хранилище для строк.

Код:
create strings 1024 allot
variable sptr  strings sptr !
: >str ( a - a) dup count 1 + 3 loc: sptr @ 1 loc!
  0 loc sptr @ 2 loc cmove 2 loc sptr +! 1 loc loc; ;


Слово >str получает строку со счетчиком и сохраняет ее в области strings.

Как же хранить пресловутое дерево в памяти? Буду использовать классический алгоритм размещения дерева в линейном массиве. Сначала в массив помещаются дочерние узлы, затем -- родительский узел. Каждый узел состоит из числа элементов и последовательности адресов дочерних узлов.

Код:
create nodes 1024 cells allot
variable nptr  nodes nptr !
: node+ ( n) cells nptr +! ;
: node ( .. n) nptr @ >r dup r@ ! 1 node+
  dup >r loc: r> 0 do i loc nptr @ ! 1 node+ loop
  loc; r> ;


Слово node берет со стека n дочерних узлов и формирует с их помощью новый узел в nodes.

Теперь следует заняться печатью дерева в виде S-выражения. Буду считать атомом узел, у которого вместо адреса первого дочернего узла хранится 0.

Код:
: .atom ( a) count type ;
: n@ ( a i - a) cells + @ ;
: .ast ( a) dup 1 n@ 0 = if 2 n@ .atom exit then
  ." (" dup @ 2 loc: 1 loc if 0 loc 1 n@ .atom
    1 loc 1 - 0 ?do ."  " 0 loc i 2 + n@ recurse loop
  ." )" then loc; ;


Далее понадобится несколько вспомогательных слов.

Код:
: id ( "name" - a) bl word >str 1 loc:
  0 0 loc 2 node loc; ;
: ` postpone postpone ; immediate
: tree: 1 loc+ ;
: tree; -1 loc+ ;


Наконец, пришло время реализовать DSL.

Код:
: (var) 0 loc 1 + 0 loc! 2 1 loc: ;
: var: ( "name")
  ` (var) c" var" ` literal id ` literal ; immediate
: var; 0 loc node loc; ;

: array: ( "name")
  ` (var) c" array" ` literal id ` literal ; immediate
: array; var; ;

: struct: ( "name")
  ` (var) c" struct" ` literal id ` literal ; immediate
: struct; var; ;

: (type) 0 loc 1 + 0 loc! 2 node ;
: type: ( "name")
  c" type" ` literal id ` literal ` (type) ; immediate

: max: ( "name")
  c" max" ` literal id ` literal ` (type) ; immediate
: min: ( "name")
  c" min" ` literal id ` literal ` (type) ; immediate
: default: ( "name")
  c" default" ` literal id ` literal ` (type) ; immediate
: size: ( "name")
  c" size" ` literal id ` literal ` (type) ; immediate


Привожу пример описания и вывода структуры.

Код:
: code-tree
  tree:
    struct: UserGroup
      var: priority
        type: int min: 10 max: 10 default: 10
      var; 
      array: name
        type: char size: MAX_GROUP_NAME_LENGTH default: ""
      array;
    struct;
  tree; ;

code-tree .ast

(struct UserGroup (var priority (type int) (min 10) (max 10) (default 10)) (array name (type char) (size MAX_GROUP_NAME_LENGTH) (default "")))


Как можно видеть, ручная реализация примитивных операций в Форте не так уж сложна. По моему опыту, она во многих случаях проще, чем попытки приспособить какие-то готовые конструкции из стандартного Форта. Как известно, Форт -- язык не алгебраический. И дело тут даже не в отсутствии способов записи инфиксных выражений. В Форте, к сожалению, мало уделяется внимания таким важным свойствам математических структур, как замкнутость и композиционность.



За это сообщение автора true-grue поблагодарили - 2: dmitry-st, Hishnik
Вернуться к началу
 Профиль Отправить личное сообщение  
Ответить с цитатой  
 Заголовок сообщения: Re: Генератор на Форте кода для C
СообщениеДобавлено: Сб апр 08, 2017 15:51 
true-grue писал(а):
...
Я, понимаю, что читать чужое решение (которое всего на порядок короче) лень. Но условие задачи прочесть-то было можно?


Вернуться к началу
  
Ответить с цитатой  
 Заголовок сообщения: Re: Генератор на Форте кода для C
СообщениеДобавлено: Сб апр 08, 2017 21:01 
Не в сети
Administrator
Administrator
Аватара пользователя

Зарегистрирован: Вт май 02, 2006 22:48
Сообщения: 7960
Благодарил (а): 25 раз.
Поблагодарили: 144 раз.
А у меня тоже образовалось решение
Код:
1024 CONSTANT MAXFIELDS
256 CONSTANT MAXNAME

1 CONSTANT #INT
2 CONSTANT #STRING

CREATE STRUCTNAME[] MAXFIELDS MAXNAME * ALLOT
CREATE FIELDNAME[] MAXFIELDS MAXNAME * ALLOT
CREATE FIELDTYPE[] MAXFIELDS ALLOT
CREATE FIELDPARENT[] MAXFIELDS CELLS ALLOT

CREATE FIELDMIN[] MAXFIELDS CELLS ALLOT
CREATE FIELDMAX[] MAXFIELDS CELLS ALLOT
CREATE FIELDDEFAULT[] MAXFIELDS CELLS ALLOT


0 VALUE STRUCTS
0 VALUE FIELDS

: ClearParents
  MAXFIELDS 0 DO
    -1 FIELDPARENT[] I -TH !
  LOOP
;
ClearParents

: STRUCT
  PARSE
  STRUCTNAME[] STRUCTS MAXNAME * + SMOVE
;

: STRUCT;
  1 +TO STRUCTS
;

: int
  PARSE
  FIELDNAME[] FIELDS MAXNAME * + SMOVE  // field name
  #INT FIELDTYPE[] FIELDS + C!          // field type
  STRUCTS FIELDPARENT[] FIELDS -TH !    // field parent
  1 +TO FIELDS
;

: string
  PARSE
  FIELDNAME[] FIELDS MAXNAME * + SMOVE  // field name
  #STRING FIELDTYPE[] FIELDS + C!       // field type
  STRUCTS FIELDPARENT[] FIELDS -TH !    // field parent
  1 +TO FIELDS
;

: min
  FIELDMIN[] FIELDS 1- -TH !
;

: max
  FIELDMAX[] FIELDS 1- -TH !
;

: default
  FIELDDEFAULT[] FIELDS 1- -TH !
;

// ***** some reporting *****

: LIST-FIELDS // N --
  MAXFIELDS 0 DO
    FIELDPARENT[] I -TH @ OVER = IF
      " -> " PRINT FIELDNAME[] I MAXNAME * + PRINT
      FIELDTYPE[] I + C@ CASE
        #INT OF "  int " PRINT ENDOF
        #STRING OF "  string " PRINT ENDOF
      ENDCASE
      "  min: " PRINT FIELDMIN[] I -TH @ .
      " max: " PRINT FIELDMAX[] I -TH @ .
      " default: " PRINT FIELDDEFAULT[] I -TH @ .
      CR
    THEN
  LOOP
  DROP
;

: LIST-STRUCTS
  CR
  STRUCTS 0 DO
    I .
    STRUCTNAME[] I MAXNAME * + PRINT CR
    I LIST-FIELDS
  LOOP
;


// ***** TEST *****

STRUCT UserGroup
  int priority
    1 min
    10 max
    5 default
  string name
STRUCT;


STRUCT HishnikGroup
  int size
    1 min
    2000000000 max
    2000000000 default
  string roar
STRUCT;

LIST-STRUCTS 


Вложения:
struct.png
struct.png [ 28.07 Кб | Просмотров: 18675 ]

За это сообщение автора Hishnik поблагодарил: dmitry-st
Вернуться к началу
 Профиль Отправить личное сообщение  
Ответить с цитатой  
 Заголовок сообщения: Re: Генератор на Форте кода для C
СообщениеДобавлено: Сб апр 08, 2017 21:05 
Не в сети
Administrator
Administrator
Аватара пользователя

Зарегистрирован: Вт май 02, 2006 22:48
Сообщения: 7960
Благодарил (а): 25 раз.
Поблагодарили: 144 раз.
vpn289 писал(а):
Вы хотите сказать, что при написании форта на ассемблере (правильно я понял?) CREATE ничего не компилирует на вершину словаря (кодофайла)?

Компилирует код push here ret.
vpn289 писал(а):
Я размышлял о системе с изолированными адресными пространствами. Отдельное для стека возвратов, отдельное для стека данных, отдельное для низкоуровневого кода, отдельное для кодофайла. Неоправданно сложно получалось.

Это как раз существенно проще. Отдельное пространство кода и данных позволяет не задумываться о способах обхода данных, выделенных прямо посередине кода. Отсюда и всяческие поля параметров. В машинном коде есть поле связи, поле имени (с примыкающими флагами), а дальше идет просто код, завершающийся ret. Пока определение не завершено, выполнять ALLOT при общем адресном пространстве бессмысленно - данные просто сядут внутрь текущего определения. Если же данные находятся в собственном пространстве, этой проблемы нет. Так что CREATE не изменяет HERE (зато изменяет [C]HERE, которое указывает на первую свободную ячейку в пространстве кода).


Вернуться к началу
 Профиль Отправить личное сообщение  
Ответить с цитатой  
 Заголовок сообщения: Re: Генератор на Форте кода для C
СообщениеДобавлено: Вс апр 09, 2017 10:12 
Не в сети
Аватара пользователя

Зарегистрирован: Вт мар 28, 2017 10:04
Сообщения: 21
Благодарил (а): 11 раз.
Поблагодарили: 0 раз.
Искренне благодарен true-grue и Hishnik за примеры!!!
Ответ на свой вопрос я получил. Дальше буду сам :work;
Благодарю всех участвовавших!

Пользовался ли кто-нибудь вот этой библиотекой:
https://github.com/irdvo/ffl
Меня заинтересовало в ней несколько вариантов деревьев.
Насколько эта библиотека стабильна и продуманна?


Вернуться к началу
 Профиль Отправить личное сообщение  
Ответить с цитатой  
 Заголовок сообщения: Re: Генератор на Форте кода для C
СообщениеДобавлено: Вс апр 09, 2017 11:38 
dmitry-st писал(а):
Искренне благодарен true-grue и Hishnik за примеры!!!
...
Меня заинтересовало в ней несколько вариантов деревьев.
И совсем ничего, что примеры не относятся к задаче! И что, в отличие от моего, они нерабочие! В полку FORTH-дебилов прибыло!


Вернуться к началу
  
Ответить с цитатой  
 Заголовок сообщения: Re: Генератор на Форте кода для C
СообщениеДобавлено: Вс апр 09, 2017 15:41 
Не в сети
Administrator
Administrator
Аватара пользователя

Зарегистрирован: Вт май 02, 2006 22:48
Сообщения: 7960
Благодарил (а): 25 раз.
Поблагодарили: 144 раз.
dmitry-st писал(а):
Ответ на свой вопрос я получил. Дальше буду сам

О! А я уже было собрался написать экспорт в .h :)

dmitry-st писал(а):
Пользовался ли кто-нибудь вот этой библиотекой:
https://github.com/irdvo/ffl
Меня заинтересовало в ней несколько вариантов деревьев.
Насколько эта библиотека стабильна и продуманна?

Меня творчество Forth Inc &Co вообще сильно настораживает как таковое. Я не говорю, что там вообще никто не может написать ничего толкового - живут же они как-то и за аренду платят. Даже вон хвалились, что они ведущая форт-компания в мире, потому что могут себе позволить целых двух (подумать только!) программистов на full-time. На что мне осталось только пойти пить водку с медведем, заказав ему сыграть что-нибудь жалобное на балалайке. Потому что дойти до этого их показателя - это ж нам увольнять людей теперь, что ли? :D

А в целом у меня претензия к ним формулируется очень просто - "а куда вы вообще идете?". Конкретно по библиотекам - какую задачу вы себе поставили, как она решается конкретно здесь, где преимущества/недостатки? Как тестировать? Где типичные сценарии использования? Кодирование с подготовительной работой по осмыслению неимоверно эффективнее, чем просто кодирование, какими бы красивыми формальностями оно не обрастало. При выкладывании в open source вообще есть интересный мотив. Программист, кроме чистого альтруизма, может иметь желание привлечь побольше людей для поддержки и развития, а заодно создать себе красивое резюме, в котором будет числиться сколько-то проектов на github. Объем проекта там не запредельный, тем более что указан всего 1 разработчик. Такое, при наличии четкой задачи и сформулированных контрольных точек, вполне выращивается с нуля, причем в том виде и стиле, которые нужны.


Вернуться к началу
 Профиль Отправить личное сообщение  
Ответить с цитатой  
Показать сообщения за:  Поле сортировки  
Начать новую тему Ответить на тему  [ Сообщений: 78 ]  На страницу Пред.  1, 2, 3, 4, 5, 6  След.

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


Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 17


Вы не можете начинать темы
Вы можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

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