--- parser3/operators.txt 2002/06/25 14:28:57 1.54
+++ parser3/operators.txt 2002/11/29 08:13:38 1.103
@@ -5,15 +5,19 @@ Xне сделано, видимо, не будет сделано
операторы
!^eval(выражение)[формат] выражение, кроме обычных функций::
+ !допустимы #комментарии
+ работают до конца строки или закрывающейся круглой скобки
+ внутри комментария допустимы вложенные круглые скобки
!из неочевидных операторов:
- # побитный xor
- ## логический xor
+ !| побитный xor
+ !|| логический xor
~ побитное отрицание
\ целочисленное деление 10\3=3
!def для проверки defined,
пустая строка не defined
пустая таблица не defined
пустой hash не defined
+ ^if(method $hash.delete){yes}
!eq ne lt gt le ge для сравнения строк,
!in "/dir/" для проверки
["внутри не допустимы, если надо сравнить со сложным,
@@ -27,16 +31,17 @@ Xне сделано, видимо, не будет сделано
!числовой литерал бывает 0xABC
!приоритеты:
/* logical */
- %left "##"
+ %left "!||"
%left "||"
%left "&&"
%left '<' '>' "<=" ">=" "lt" "gt" "le" "ge"
%left "==" "!=" "eq" "ne"
%left "is" "def" "in" "-f" "-d"
%left '!'
+ условие ? когдаДа: когдаНет
/* bitwise */
- %left '#'
+ %left '!|'
%left '|'
%left '&'
%left '~'
@@ -45,6 +50,8 @@ Xне сделано, видимо, не будет сделано
%left '-' '+'
%left '*' '/' '%' '\\'
%left NEG /* negation: unary - */
+
+
!^if(условие){когда да}{когда нет}
!^switch[значение]{^case[вариант1[;вариант2...]]{действие}^case[DEFAULT]{действие по умолчанию}}
!^while(условие){тело}
@@ -85,7 +92,8 @@ Xне сделано, видимо, не будет сделано
default as-is
!^taint[[lang]][код]
default "just tainted, language unknown"
- !^process{строка, которая будет process-ed, как код}
+ !^process[[$caller.CLASS|$object|$КЛАСС:CLASS]]{строка, которая будет process-ed, как код}
+ по умолчанию, методы компилируются в $self [в случае оператора, $self=$MAIN:CLASS]
!^connect[protocol://строка соединения]]{код с ^sql[...]-ями}
!mysql://user:pass@{host[:port]|[/unix/socket]}/database?
charset=cp1251_koi8&
@@ -160,8 +168,10 @@ odbc c:\drives\y\parser3project\odbc\
!и есть исключение: ^untaint[html]{код} не оптимизируется
Xбезотностительно флажка
- !у всех макросов есть локальная переменная $result, если в неё что положить,
+ !у всех методов есть локальная переменная $result, если в неё что положить,
!то _это_ будет результатом макроса, а не его тело
+ !у всех методов есть локальная переменная $caller, в ней лежит родительский stack frame,
+ !если туда записать
!use(^use или @USE) ищет файл...
!1. ...если путь начинается с /, то считается, что это путь от корня веб пространства
@@ -216,6 +226,10 @@ odbc c:\drives\y\parser3project\odbc\
!void
+ !^имя.length[]
+ 0
+ !^имя.pos[...]
+ -1
!^имя.int[] (default)
0 или default
!^имя.double[] (default)
@@ -243,7 +257,7 @@ odbc c:\drives\y\parser3project\odbc\
пример:
^if(def $form:name) не пуста?
^if($user.isAlive) истина? [автопреобразование к числу, не ноль?]
- !^string::sql{query}[[$.limit(2) $.offset(4) $.default{n/a}]]
+ !^string::sql{query}[[$.limit(1) $.offset(4) $.default{n/a}]]
результат запроса должен быть один столбец/одна строка
!^имя.int[] .int(default) целочисленное значение строки.
если ломается преобразование, берётся default
@@ -260,7 +274,13 @@ odbc c:\drives\y\parser3project\odbc\
!^строка.match[шаблон][опции поиска]{замена}
опции поиска+=
g заменить все вхождения, а не одно
+ !^строка.split[разделитель][[lrhv]]
+ l слева направо [default]
+ r справа налево
+ h nameless таблица
+ v таблица из столбца piece [default]
!^строка.{l|r}split[разделитель] таблица из столбца $piece
+ оставлен для совместимости
!^строка.upper|lower[]
X^строка.truncate(предел терпенья) стиль :(
!^строка.length[]
@@ -281,9 +301,9 @@ odbc c:\drives\y\parser3project\odbc\
логическое значение равно "не пуста?"
числовое значение равно count[]
!^table::create[[nameless]]{данные} старое имя "set"
- !^table::create[table]
- клонирует таблицу
- !^table::load[[nameless;]путь]
+ !^table::create[table][[$.limit(1) $.offset(5) $.offset[cur]]]
+ клонирует таблицу
+ !^table::load[[nameless;]путь[;опции]]
!если не nameless, названия колонок берутся из первой строки
!пустые строки, и строки в первой колонке содержащие '#', игнорируются
!^table::sql{query}[[$.limit(2) $.offset(4) todo:$.default{ ^table::create[...] }]]
@@ -303,18 +323,18 @@ odbc c:\drives\y\parser3project\odbc\
X^таблица.remove(position[;count]) - стирает запись
из текущей позиции [стирает запись из конкретной позиции]
[стирает count записей]
- !^таблица.join[таблица] - добавляет записи из таблицы.
+ !^таблица.join[таблица][$.limit(1) $.offset(5) $.offset[cur]] - добавляет записи из таблицы.
таблицы должны иметь одинаковую структуру.
!^таблица.flip[] выдаёт транспонированную, надо куда-то сложить, потом пользовать
!^таблица.locate[поле;значение] передвигает текущую строку, если найдёт. выдаёт bool
!^таблица.locate(логическое выражение) передвигает текущую строку, если найдёт. выдаёт bool
- !^таблица.hash[поле, что будет ключом][[поле значений|table поля значений]]+
+ !^таблица.hash{[поле]|{код}|(выражение)}[[поле значений|table поля значений]][[$.distinct(1)]]
значением $hash.ключ будет hash в котором поля значений будут ключами
поля значений могут быть не указаны, тогда ими будут все столбцы, включая ключевой
!^таблица.columns[]+ таблица из одного столбца $column
!$отобранное[^таблица.select(выражение)] = таблица из тех же столбцов и строк, у которых условие совпало
- $adults[^man.select($man.age>=18)]
- ^таблица.color[цвет1;цвет2]
+ $adults[^man.select($man.age>=18)]
+ ^таблица.color[цвет1;цвет2]
!hash
@@ -334,7 +354,7 @@ odbc c:\drives\y\parser3project\odbc\
!^a.intersection[b] = пересечение
значения a
!^a.intersects[b] = bool
- !^hash::sql{запрос}[[$.limit(2) $.offset(4) todo:$.default{$.field[]...}]]
+ !^hash::sql{запрос}[[$.distinct(1) $.limit(2) $.offset(4) todo:$.default{$.field[]...}]]
получается hash(ключи=значения первая колонка ответа)
of hash(ключи=названия остальных колонкок ответа)
!^hash._keys[]+ таблица из одного столбца $key
@@ -345,8 +365,12 @@ odbc c:\drives\y\parser3project\odbc\
!form
[берётся первый элемент из одноимённых из GET, потом первый из POST]
!$form:поле = string/file
+ !$form:nameless = поле со значением поля без имени "?value&...", "...&value&...", "...&value"
+ !$form:qtail = строка со значением текста после второго "?xxxxx", если там не было ',' [imap]
!$form:fields = hash со всеми полями формы
!$form:tables.поле = table с одним столбцом "field" со значениями "поля"
+ !$form:imap = хэш с ключами 'x' и 'y'
+ со значением ?1,2 приписки при использовании server-site image map
!env
!$env:переменная
@@ -358,6 +382,7 @@ odbc c:\drives\y\parser3project\odbc\
!request
!$request:query
+ !$request:body unprocessed POST request body
!$request:uri
X!$request:browser это hash, поля:
!$type = ie/nn и !$version = номер, скажем 5.5
@@ -374,6 +399,8 @@ odbc c:\drives\y\parser3project\odbc\
!значение может быть string а может быть hash:
! $value[abc] field: {abc}<<часть
! $attribute[zzz] field: abc; {attribute=zzz}<<часть
+ !значение поля или атрибута может быть string или date
+ ! если дата, она будет преобразована к формату "Sun, 25-Aug-2002 12:03:45 GMT"
!$response:body[DATA] замещает стандартный ответ
!$response:status
!^response:clear[] забыть все заданные response поля
@@ -540,6 +567,11 @@ Xhashfile
!$картинка[^image::measure[DATA]]
смотрит на .ext case insensitive,
умеет мерить пока только .gif и .jpg .jpeg
+ !$image.exif << hash после measure jpeg с exif информацией
+ !$image.exif.DateTime & co
+ [полный список см. http://www.ba.wakwak.com/~tsuruzoh/Computer/Digicams/exif-e.html]
+ !числа типа int/double,
+ !перечисления в виде hash с ключами 0..count-1
!$картинка.src .width .height
!$картинка.line-width число=ширина линий
!$картинка.line-style строка=стиль линий '*** * '='*** * *** * *** * '
@@ -583,15 +615,17 @@ Xhashfile
!^file:delete[имя файла]
!^file:find[имя файла][{когда не нашли}]
!^file:list[путь[;шаблон]] = table с колонкой name
- !^file::load[text|binary;!big.zip[;!domain_press_release_2001_03_01.zip]]
+ !^file::load[text|binary;!big.zip[;!domain_press_release_2001_03_01.zip][;опции]]
!$файл_который_был_loaded.size
!^file::stat[имя файла]
!$файл_который_был_stated.size !.adate !.mdate !.cdate
- !^file::cgi[имя файла[;env hash[;1cmd[;2line[;3ar[;4g[;5s]]]]]]]
+ !^file::cgi[имя файла[;env hash +options[;1cmd[;2line[;3ar[;4g[;5s]]]]]]]
возвращённый заголовок рассыпается на $поля
$status
$stderr
!^file::exec[имя файла[;env hash[;1cmd[;2line[;3ar[;4g[;5s;...under win32 max 10 args]]]]]]]
+ options:
+ $.stdin[текст] если текст пуст, отключается автоматическое пересовывание данных HTTP-POST
!^file:move[старое имя файла;новое имя файла]
можно переименовывать и двигать каталоги[win32: но не через границу дисков]
каталоги для dest создаются с правами 775
@@ -607,6 +641,8 @@ Xhashfile
!^file:basename[/a/some.tar.gz]=some.tar.gz
!^file:justname[/a/some.tar.gz]=some.tar
!^file:justext[/a/some.tar.gz]=gz
+ !/some/page.html: ^file:fullpath[a.gif] => /some/a.gif
+
math
!$math:PI
@@ -630,6 +666,8 @@ math
количество дней с epoch [1 января 1970 (UTC)], дробное
!всё происходит в localtime,
!временная зона задаётся вне parser средствами OS
+ $date:UTC-offset сколько дней надо прибавить,чтобы попасть в local время
+ $date:TZ наш часовой пояс, дробное, в часах (где-то есть с точностью до получаса)
!^date::now[]
!^date::now(смещение в днях) выдаёт сейчас+смещение
!^date::create(дней с epoch) // старое имя set
@@ -638,13 +676,13 @@ math
для удобного создания по значению из базы
формат1: %Y[-%m[-%d[ %H[:%M[:%S]]]]]
формат2: %H:%M[:%S]
- !$date.year month day hour minute second weekday todo:yearday
+ !$date.year month day hour minute second weekday yearday(0...) daylightsaving
read-only
!^date.roll[year|month|day](+-смещение) сдвигает дату
!^date.sql-string[] %Y-%m-%d %H:%M:%S
where published='$дата.sql-string[]'
!^date:calendar[rus|eng;год;месяц] выдаёт неименованную таблицу
- столбцы: 0..6
+ столбцы: 0..6, week, weekyear
!^date:calendar[rus|eng;год;месяц;день] выдаёт именнованную таблицу
столбцы: year, month, day, weekday
@@ -676,10 +714,12 @@ xdoc(xnode)
!равно текущей кодировке выходной страницы,
$response:charset
::sql{...}
- !::create{} старое имя 'set'
- !::create[qualifiedName]
- !::load[file.xml]
- !.transform[rules.xsl][[params hash]] выдаёт dom
+ !::create[[URI]]{} старое имя 'set'
+ !::create[[URI]][qualifiedName]
+ URI default = disk path to requested document
+ для каталогов конечный / обязателен
+ !::load[file.xml[;опции]]
+ !.transform[rules.xsl|xdoc][[params hash]] выдаёт dom
шаблон кэшируется, кэш обновляется при изменении даты файла шаблона,
или изменении даты файла "имя шаблона.stamp"[проверка даты stamp приоритетнее]
} any error in xml/xslt libs
!smtp.connect not found/timeout
!smtp.execute communication error
-
-
+ !email.format hren tam@null.ru wrong email format(bad chars/empty)
+ !email.send $MAIL.sendmail[/shit] sendmail not executable
+ !http.host ^file::load[http://notfound/there] host not found
+ !http.connect ^file::load[http://not_accepting/there] host found, but do not accept connections
+ !http.timeout ^file::load[http://host/doc] whole load operation failed to complete in # seconds
+ !http.response ^file::load[http://ok/there] host found, connection accepted, bad answer
+ !http.status ^file::load[http://ok/there] host found, connection accepted, status!=200
+
!нужно выключить русский apache: CharsetDisable on
!если в MAIN будет определён флаг $ORIGINS(1) то вместо обычного вывода страницы будет