Разбор полётов на примере r5636

 
+
-
edit
 

Balancer

администратор
★★★★★

Увидел и упал :D

system-time-day-of-week dup 1 = 7 = +

1. Для логического ИЛИ у нас используется слово OR.
2. Смотрим, что у нас на стеке:
system-time-day-of-week ( — day )
dup ( day — day day )
1 = ( day day — day day==1? )
7 = ( day day==1? — day {day==1}==7? )
и теперь мы это безобразие складываем. Ужас.

Вот как должно быть:
system-time-day-of-week ( — day )
dup ( day — day day )
1 = ( day day — day day==1? )
swap ( day day — day==1? day )
7 = ( day day==1? — day==1? day==7? )
or ( day==1? day==7? — day==1||day==7 )

А, вообще, лучше возвращать день в виде "понедельник"==1, "воскресенье"==7, что и было сделано в r5658:

: system-time-day-of-week  ( -- день_недели[1..7] )
  7 "java.util.Calendar" class "getInstance" 0 jget "get" { int.class } jget
  1- ?dup unless 7 then
;


Надеюсь, понятно, как 1==воскресенье, 2==понедельник... 7==суббота, превращаются в более привычные цифры по формуле:
день := день - 1
если день == 0, то день := 7.

unless - это почти то же самое, что not if

Дальше:

  ( ... ) if
    true boolean
  else
    false boolean
  then


1. boolean можно вынести за пределы условия и писать только раз: if true else false then boolean

2. А чему равно if true else false then? Да нет операции, вообще-то :D

3. Наконец, зачем тут boolean? Мы же не в Java-метод объект Boolean передаём.

В итоге весь этот if-блок просто... выкидывается.


: system-time-isNight
  system-time-hour dup 12 <= 22 >= + if
    system-time-is-offday not if
        true boolean
      else
        false boolean
    else
      false boolean
  then
;


Вообще красота. На два if'а - один then. Мне даже как-то в голову не пришло сделать проверку на такую ошибку на этапе компиляции. Надо будет сделать.

А что по сути? Та же ошибка с + вместо OR и отсутствие swap между сравнениями.

Дальше. Вложение if'ов - ни что иное, как логическое И. В итоге от всего этого слова у нас остаётся:

: system-time-isNight  ( -- скидки? )
  system-time-hour dup 12 <= swap 22 >= or
  system-time-is-offday not and
;


В принципе, это выражение можно даже ещё чуть-чуть упростить, вспомнив слово
WITHIN ( число левая_граница правая_граница -- входит? )
(нужно помнить, что левая граница берётся включительно, правая - исключительно).

Т.е.:

: system-time-isNight  ( -- скидки? )
  system-time-hour 11 21 within \ если это день
  system-time-is-offday or      \ или выходной
  not                           \ скидок нет
;
… чтобы понять рекурсию, нужно сперва понять рекурсию …  
+
-
edit
 

Balancer

администратор
★★★★★
Маленький довесок:

: gatekeeper-jump (( x y z amount objectId1 objectId2 -- )) 
    self "AlikeDead" p? if "You not teleport in death mode" show exit then 
    system-time-isNight if amount 2 / to amount then
    amount adena? nip unless "You have not adena!" show exit then
    objectId1 id>obj objectId2 id>obj dist 300 > if "Too far" show exit then 
    amount adena_pay 
    x y z jump 
;


Вот так будет покрасивее:


: gatekeeper-jump (( x y z adena objectId1 objectId2 -- )) 
    self "AlikeDead" p? if "You not teleport in death mode" show exit then 
    adena system-time-isNight if 2 / then adena? not if drop "You have not adena!" . exit then drop 
    objectId1 id>obj objectId2 id>obj dist 300 > if "Too far" . exit then 
    adena system-time-isNight if 2 / then adena_pay 
    x y z jump 
;


гы... сделать, что ли, так?

: gatekeeper-jump (( x y z оплата obj1 obj2 -- )) 
    я AlikeDead? если "You not teleport in death mode" вывести выйти тогда
    скидки? если оплата пополам в оплата тогда
    оплата деньги-есть? если-нет "You have not adena!" вывести выйти тогда
    obj1 id>obj obj2 id>obj расстояние 300 > есди "Too far" вывести выйти тогда
    оплата заплатить
    x y z прыгнуть
;


;)
… чтобы понять рекурсию, нужно сперва понять рекурсию …  
+
-
edit
 

Balancer

администратор
★★★★★
Что-то я развеселился :) (этот пример - оттестирован)

module: время
: час
  11 "java.util.Calendar" class "getInstance" 0 jget "get" { int.class } jget
;

: день_недели  ( -- день_недели[1..7] )
  7 "java.util.Calendar" class "getInstance" 0 jget "get" { int.class } jget
  1- ?dup unless 7 then
;

"включает?" alias within
"или" alias or
"нет" alias not

: выходной?   день_недели 6 >= ;
: день?       час 11 21 включает? ;
: скидки?     выходной? день? или   нет ;
;module


:)
… чтобы понять рекурсию, нужно сперва понять рекурсию …  
+
-
edit
 
Ну если бы где-то было хотябы подобие документации... А так понятно каждый пишет как знает, изобретая свои конструкции.
Пытаясь понять рекурсию, следи за тем, чтобы она не поняла тебя первой...  
+
-
edit
 

Balancer

администратор
★★★★★
По Форту в сети масса литературы. forth.org.ru в руки :)

Всё, что касается стека и вычислений, обычно умещается в первой главе и у нас работает также, как и в любом другом Форте. Разница со стандартным Фортом начинается только там, где появляются адреса. У нас вместо них - ссылки на объекты.
… чтобы понять рекурсию, нужно сперва понять рекурсию …  
+
-
edit
 

Balancer

администратор
★★★★★
Кроме того, некоторые напрочь отказываются рассматривать вопросы тестирования. А Форт тут - рулит как нигде. Цепляешься к живому серверу телнетом, и возишься с операциями на стеке по одной, просматривая результат по .s. Что может быть проще? :D

# telnet localhost 1904
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
Welcome To The L2J Telnet Session.
Please Insert Your Password!
Password: ****
Password Correct!
[L2J]
system-time-day-of-week
.s
Stack: 7
dup .s
Stack: 7 7
1 = .s
Stack: 7 0
7 = .s
Stack: 7 0
+ .s
Stack: 7


Неужели тут так трудно заметить, что что-то в Датском королевстве не то? :D
… чтобы понять рекурсию, нужно сперва понять рекурсию …  
+
-
edit
 
Имеется в виду список возможных команд :)
?dup unless within - никогда о таких не слышал...
Пытаясь понять рекурсию, следи за тем, чтобы она не поняла тебя первой...  
AD Реклама Google — средство выживания форумов :)
+
-
edit
 

Balancer

администратор
★★★★★
?dup - это стандартная команда Форта. У нас на Wiki даже описана: http://la2.balancer.ru/wiki/index.php/Dup Правда, с ошибкой (поправил).

unless - это калька с Перла. Используется уже очень давно и в куче примеров, в т.ч. на этом форуме.

within - стандартное слово.
… чтобы понять рекурсию, нужно сперва понять рекурсию …  

в начало страницы | новое
 
Поиск
Настройки
Твиттер сайта
Статистика
Рейтинг@Mail.ru