Смекни!
smekni.com

Программирование и разработка приложений в Maple (стр. 97 из 135)

Save2 := proc()

local a b c j k G S, , , , , , , ν, ,f ω, ;h `if`(nargs < 2, RETURN(NULL), assign(ν = interface(warnlevel), ω = (x → null interface(( warnlevel = x)))))

;

if type(args[-1], 'file') then f := args[-1]; ω(0) elif not type(eval args[-1]( ), {'symbol', 'string'}) then

ERROR "<%1> can't specify a datafile",( args -1[ ]) else ω(0); f := MkDir(args -1[ ], 1) end if; assign(h = cat(currentdir( ), "/$Art16_Kr9$")); assign(G = [ ], S = ""), ω(2), assign( a = {op(SLD(convert '( procname args( )', 'string')[7 .. -1], ",")[1 .. -2])}); seq `if` type(( ( eval args[ ]( j ), {`module`, 'procedure'}), assign(' 'G = [op(G), args[ ]j ]), NULL), j = 1 .. nargs − 1), assign(b = a minus {op(map(convert, G, 'string'))}),

`if`(b = { } and G = [ ], RETURN(ω ν( )), NULL); if b ≠ { } then assign(c = cat "_Vars_", " := proc() global ",( seq(cat(b j[ ], ","), j = 1 .. nops(b)), "; assign(" seq(, cat(convert(cat "'", [ ],( b j "'") = eval(convert(b j[ ], 'symbol')), 'symbol'), `,`), j = 1 .. nops(b)), ") end proc:")), seq(assign('S' = cat(S, `if`(member(k, {op Search2( ,( c {""" ",)" ",;", , }))}), NULL, c k[ ]))), k = 1 .. length( )c ), writebytes( ,h S), fclose(h),

(proc() read h; fremove(h) end proc )( )

end if; Save1([[op(G), `if`(b = { }, NULL, _Vars_)]], [f]), ω(ν), f end proc

> MM:=module () export x, m; m:= module() export y; y:= () -> `+`(args) end module end module: MM1:= module() local F,m; export a; option package; m:= module() export y; y:=() -> `+`(args) end module; F:=() -> m:- y(args); a:=F end module: SVEGAL:=module() export x; x:=() -> `+`(args)/nargs^6 end module: PP:=proc() `+`(args)/nargs^2 end proc: PP1:=proc() `+`(args)/nargs end proc: PP2:=proc() `+`(args)/nargs end proc: GS:=module() export x; x:=() -> `+`(args)/nargs^3 end module: avz:=61: agn:=56: Art:=14: Kr:=7:

> Save2(op({MM, 'avz', SVEGAL, MM1, 'agn', GS, 'Art', PP, 'Kr', PP1, 'Svet'}),

"C:/RANS/IAN/RAC/REA/Academy/Art_Kr.txt.m");

"c:&bsol;rans&bsol;ian&bsol;rac&bsol;rea&bsol;academy&bsol;art_kr.txt.m" Read1 := proc(F::{list({string, symbol}), set({string, symbol})}) local k j act_tab rf v t fg nm T U R, , , , , , , , , , ; `if`(F = [ ] or F = { }, ERROR("files for reading are absent"), NULL); assign(fg = (a string:: → `if`(search(a, "/"), a[2 .. -2], a)), U = {anames( )}); assign( act_tab = table(['procs' = { }, 'mods1' = { }, 'mods2' = { }, 'vars' = { }]),

T = table [( 'procs' = { }, 'mods1' = { }, 'mods2' = { }, 'vars' = { }])); v := table([""" = 1, "#" = 2, "$" = 3, "%" = 4, "&" = 5, "'" = 6, "(" = 7, ")" = 8,

"*" = 9, "+" = 10, "," = 11, "-" = 12, "." = 13, "/" = 14, "0" = 15, "1" = 16,

"2" = 17, "3" = 18, "4" = 19, "5" = 20, "6" = 21, "7" = 22, "8" = 23, "9" = 24,

":" = 25, ";" = 26, "<" = 27, "=" = 28, ">" = 29, "?" = 30, "@" = 31, "A" = 32,

"B" = 33, "C" = 34, "D" = 35, "E" = 36, "F" = 37, "G" = 38, "H" = 39,

"I" = 40, "J" = 41, "K" = 42, "L" = 43, "M" = 44, "N" = 45, "O" = 46,

"P" = 47, "Q" = 48, "R" = 49, "S" = 50, "T" = 51, "U" = 52, "V" = 53,

"W" = 54, "X" = 55, "Y" = 56, "Z" = 57]);

rf := proc(f) local _h _p _p1 k _z _g _r _q, , , , , , , ; close( )f , assign(_p = { }, _p1 = { },

_z = {seq(lhs(op 2,( eval( )v )[ ]k ), k = 1 .. nops([indices( )v ]))}); do

_h := readline(f);

if _h = 0 then break

else if cat " ",( f)[-2 .. -1] = ".m" then if _h[1] = "I" and member(_h[2], _z) then

_p :=

{cat(``, _h[3 .. 2 + eval( [v _h[2]])]), op(_p)}

; _p1 := _p end if

else if _h[1 .. 11] = "unprotect('"then

_g := Search(_h ` `, ); _p := {op(_p), cat(``, fg(_h[_g[1] + 1 .. _g[2] − 1]))}

elif evalb(

assign('_q' = Search2(_h, {" := mod" " := proc", })),

_q ≠ [ ]) then

_p := {op(_p), cat(``, fg(_h[1 .. _q[1] − 1]))} elif search(_h ` := `, , '_r') then

_p1 := {op(_p1), cat(``, fg(_h[1 .. _r − 1]))} end if

end if

end if

end do; close(f), [_p, _p1]

end proc ;

for k to nops(F) do try if not type(F k[ ], 'file') then

WARNING("<%1> is not a file or does not exist", F[k]); next elif not TRm( [ ])F k then

WARNING("file <%1> is not readable by statement <read>" [ ], F k )

;

next

else if nargs = 1 then read [ ]F k ; next else nm := (proc(`_$$$_`) read `_$$$_`; rf `_$$$_`( ) end proc )( F k[ ]); for j to nops(nm[1]) do if type(eval(nm[1][ ]j ), 'procedure') and member(nm[1][ ]j , {anames '( procedure')}) then act_tab['procs'] :=

{nm[1][ ]j , op(act_tab['procs'])} elif type(eval(nm[1][j]), `module`) and member(nm[1][ ]j , {anames(`module`)}) then if type(nm[1][ ]j , 'mod1') then act_tab['mods1'] :=

{nm[1][ ]j , op(act_tab['mods1'])} else act_tab['mods2'] :=

{nm[1][j], op(act_tab['mods2'])} end if

end if

end do; act_tab['vars'] := { op(act_tab['vars']), op(nm[2] intersect{anames( )})} minus map(op,

{act_tab['procs'], act_tab['mods1'], act_tab['mods2']}) end if end if

catch "local and global":

NULL "Processing of especial situations with program modules"( ) end try

end do;

`if`(member(_Vars_, act_tab['procs']), _Vars_( ), NULL), assign(R = act_tab['mods1'] union act_tab['mods2']), `if`(R ≠ { }, map(eval R, ), NULL); `if`(act_tab['procs'] ≠ { },

(proc() try map(act_tab['procs'], ``) catch "": NULL end try end proc )( ),

NULL);

null(`if`(1 < nargs, [assign(args[2] = eval(act_tab)), `if`(nargs = 3, [seq( assign(' [ ]'T k = U intersectact_tab k[ ]), k = ['procs', 'mods1', 'mods2', 'vars'])

, assign(args 3[ ] = eval(T))], NULL)], NULL))

end proc > restart; Read1(["C:/RANS/IAN/RAC/REA/Academy/Art_Kr.txt.m"], 'h'), eval(h); table([procs = {_Vars_, SVEGAL, PP, PP1, MM, MM1, GS}, mods1 = {}, mods2 = {}, vars = {}])

> [avz, agn, Art, Kr], 36*PP(42, 47, 67, 62, 89, 96), SVEGAL:- x(42, 47, 67), GS:- x(42, 47, 67);

[61 56 14 7, , , ], 403,,

Процедура Save2 весьма существенно расширяет предложение save с полным наследованием синтаксиса последнего. но в отличие от него позволяет корректно сохранять в m-файлах переменные, процедуры и программные модули. Вызов процедуры возвращает полный путь к файлу с сохраненными Maple-объектами. В свою очередь, процедура Read1(F) используется как для загрузки в память файлов, сохраненных по Save2, так и для получения имен объектов, сохраненных в них, в разрезе их типов. В этом же контексте представляет интерес, например, реализованная однострочным экстракодом процедура savemu, обеспечивающая корректное сохранение модулей в m-файлах с возвратом NULL-значения. Последующее чтение таких файлов read-предложением делает доступными экспорты (exp) сохраненного в них модуля по конструкции M[exp](args), при этом, сами сохраненные модули не распознаются пакетом в качестве таковых.

savemu := (M::{`module`, set(`module`), list(`module`)}, F) → (proc() local a b c f, , , ; assign(a = (x → `if`(type(x `module`, ), [ ]x , x)), c = "", f = cat([libname][1][1 .. 2], "&bsol;_$Art16Kr9$_" );)

map(mod21, a M( )), seq(

assign('c' = cat(c, b, " := eval('parse'(convert(eval(", b, "), 'string'))):")), b = a M( ));

(proc() writeline ,(f c), close( )f ; read f; fremove( )f end proc )( ),

(proc() save args, F end proc )(op(a M( )))

end proc )( ) > module A () export B, G; B:= () -> `*`(args): G:= () -> sqrt(`+`(args)) end module: M:= module() export vs; vs:= () -> `+`(args)/nargs end module: savemu({A, M}, "C:/tmp/m.m"); restart; read("C:/tmp/m.m"); > map(type, [A,M],`module`),A[B](1,2,3),A[G](9,10,17), M[vs](2,3,4,5,6); ⇒ [false, false], 6,6,4

С другими нашими средствами Save-группы можно ознакомиться в [41-43,103,108,109].

6.2. Средства Maple-языка для работы с внешними файлами данных

Средства доступа к файлам включают ряд функций, при этом под «файлом» подразумевается не только организованная совокупность данных во внешней памяти ПК, но и канал, а также непосредственный интерфейс с пользователем. В этом отношении все составляющие понятие файл компоненты являются эквивалентными и за редким исключением любой файл обрабатывается одним и тем же набором функций доступа. Для обеспечения доступа к файлам данных Maple-язык располагает рядом достаточно эффективных для ПС данного типа средств. Как и в случае большинства известных систем программирования, для инициации операций обмена с файлом данных требуется предварительное его открытие, а после завершения работы с файлом – его закрытие; при этом, если открытие файла должно быть явным (кроме случая стандартных и специальных файлов), то закрытие его, в общем случае, не обязательно должно быть явным, ибо в конце работы с прикладной программой все используемые ею ресурсы, включая файлы различных типов, закрываются автоматически. Однако, для большинства ПС число одновременно открытых файлов ограничено и их максимальное количество колеблется в пределах (8-24). Для случая нашего пакета количество открытых пользовательских файлов не должно превышать 7. С целью устранения данного ограничения нами была создана процедура holdof, предлагающая следующий механизм расширения числа доступных каналов ввода/вывода (в/в), а именно.

Если число открытых каналов в/в меньше семи, вызов процедуры holdof(hold) возвращает список логических номеров открытых каналов в/в; в противном случае возвращается логический номер открытого канала в/в с сохранением состояния файла данных, ранее открытого по данному каналу. Успешный вызов процедуры позволяет использовать дополнительный канал для работы с файлами. После завершения работы с выделенным каналом вызовом процедуры holdof(restore) восстанавливается отложенное состояние файла данных, ранее открытого по этому каналу с возвратом NULL-значения. Таким образом, схема использования процедуры holdof имеет следующий принципиальный вид: holdof(hold) => обработка файла данных на выделенном канале в/в => holdof(restore)

holdof := proc(C::symbol) local a b k, , , ψ, ,j ω; global _avzagnartkrarn63 ; ψ := x → {k $ (k = 0 .. 6)} minus {seq(x j[ ][1], j = 4 .. nops( )x )};

`if` member(( C, {'hold', 'restore'}), assign(a = iostatus( )),

ERROR("argument should be 'hold' or 'restore' but has received <%1>", C)); if C = 'hold' then

`if`(nops(a) < 10, RETURN(ψ(a)), NULL);

for k from 4 to nops(a) do

if not member(a k[ ][2], {"terminal" "default", }) and member(a[k][3], {'STREAM', 'RAW'}) then _avzagnartkrarn63 := filepos(a k[ ][2]), a k[ ];

close(a k[ ][1]), RETURN(a k[ ][1])

end if

end do;

if type(_avzagnartkrarn63 , 'assignable1') then

ERROR "too many files already open"( ) end if

else try `if`( not typeseq(_avzagnartkrarn63, 'seqn'), RETURN( ), assign67(ω = _avzagnartkrarn63 ));

unassign '( _avzagnartkrarn63'), close(ω[2][1])

catch "file descriptor not in use"null("processing of an open I/O channel"):

end try ; b := [`if`(ω[2][3] = 'RAW', 'open', 'fopen'), ω[2][2], op(ω[2][5 .. `if`(ω[2][3] = 'RAW', 5 6, )])];

null(OpenLN(ω[2][1], op(b)), filepos(ω[2][1], ω[1])), `if`(1 < nargs,

NULL, WARNING(

"file <%1> had been restored on I/O channel <%2>" [, ω 2][2], ω[2][1 ))] end if

end proc

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