=head1 Gramatica geral do CAMILA
texto -> [deftypes] bloco
deftypes : "TYPE" deftipo (";" deftipo )* "ENDTYPE'
deftipo : SIMB "=" deftp
| SIMB "::" deftp
deftp : SIMB
| deftp ("|" deftp)+ {* ALTernativas *}
| (SIMB ":" deftp)+ {* TUPlo *}
| deftp "->" deftp {* FF *}
| deftp "<->" deftp {* RELacao binaria *}
| deftp-list {* LISTa *}
| deftp-set {* SET *}
| "[" deftp "]" {* tipo opcional *}
bloco : ( elemento ";" )*
elemento : deffunccao | directivas | exp
directivas : "#include" file {* preprocessa e inclui file *}
| "#includemetoo" filemetoo {* inclui file em xmetoo *}
| "#debugon" {* *}
| "#debugoff" {* *}
deffuncao : SIMB "(" argumentos ")" "=" exp
| "FUNC" SIMB "(" argum_tipos ")" ":" tipos {* assinatura *}
["PRE" exp ["->" exp]] {* precondicao *}
["STATE" exp] {* alteracao do estado *}
["RETURN" exp] {* valor devolvido *}
argumentos : id ( "," id )*
| {* vazio *}
tipo : deftp
| "(" identificador_estado ")"
exp : SIMB {* Identificador xmetoo *}
| "(" exp ")" {* Alterar prioridades *}
| STRING {* string entre aspas *}
| defobj {* definicao de estado *}
| SIMB "(" explist ")" {* invocacao de funcao *}
| "(" exp ")" "(" explist ")" {* invocacao de funcao *}
| exp "[" exp "]" {* (aply exp exp) *}
| seqexp {* Sequencia *}
| setexp {* Conjunto *}
| ffexp {* Funcao finita *}
| relexp {* Relacao binaria *}
| letexp
| ifexp
| boolexp {* expressao booleana *}
| exp "\" exp {* dom subtract *}
| exp "/" exp {* dom restrict *}
| exporio {* somatorio, func-orio *}
defobj : SIMB "<-" exp {* define/redefine estado *}
exporio : SIMB "-orio" "("exp ","exp ")" {* add-orio(neutro,conj) *}
intexp : INTEIRO
| "#" exp {* cardinal *}
=head2 Bool expressions
boolexp : exp "in" exp {* member *}
| exp "notin" exp {* not member *}
| exp "&&" exp {* and *}
| exp "||" exp {* or *}
| "~" exp {* not *}
| exp "==" exp {* equal *}
| exp "!=" exp {* diferente *}
| "(" exp ">" exp ")" {* gt *}
| "(" exp "<" exp ")" {* lt *}
| exp ">=" exp {* geq *}
| exp "<=" exp {* leq *}
| "is-" SIMB "(" exp ")" {* (is SIMB exp) *}
| false {* constante falso *}
| true {* constante verdade *}
=cut
a <- 1 in {1,2,3} /\ 4 notin {1,2,3};
b <- 2 > 3 \/ 3 > 2 ;
c <- all( x <- : x );
d <- all( x <- , y <- : x /\ y);
_ok( "bool expression" , a /\ b /\ c /\ d , true);
comp(x) = if(x is-<> -> 0 ,
x is- -> 1 .+ comp(b) ) ;
_ok("if x is-", comp(<1,2,3,4,2>), 5);
tlet() = let( = <1,2>) in a.+b;
_ok("let (= ...", tlet(), 3);
=head2 Sets
setexp : "{" exp "|" fromlist "}" {* conj em compreensao *}
| "{" exp-list "}" {* conj em extensao *}
| exp "*" exp {* intersection *}
| exp "U" exp {* union *}
| exp "-" exp {* difference *}
=cut
a <- {1,2,3} * {1,2,3,4} U {3} ;
b <- { | a1 <- a , a2 <- a : a1 != a2 };
d <- { | a1 <- a , a2 <- a : a1 > a2 };
e <- { | a1 <- a , a2 <- a : a1 < a2 };
c <- a - {1};
_ok("set op", #a == 3 /\ #b == 6 /\ #c == 2 /\ #d == 3 /\ #e == 3 ,true);
=head2 sequences
seqexp : "<" exp "|" fromlist ">" {* seq em compreensao *}
| "<" exp-list ">" {* seq em extensao *}
| "<" exp ":" exp ">" {* (cons exp exp) *}
| exp "^" exp {* (append exp exp) *}
=cut
a <- <1,2,3> ^ <1,2,3,4> ^ <3> ;
b <- < | a1 <- a , a2 <- a : (a1 != a2) >;
b1 <- < | a1 <- a , a2 <- a : a1 != a2 >;
c <- < 1 : a >;
_ok("seq op", length(a)==8 /\ length(b) == 46 /\ length(c) == 9, true);
=head2 sequences
fromlist : from ("," from)*
from : SIMB "<-" exp {* (from SIMB exp) *}
| SIMB "<-" exp ":" cond {* (from SIMB exp cond) *}
ffexp : "[" exp "->" exp "|" from "]" {* ff em comprensao *}
| "[" exppair-list "]" {* makeff *}
| exp "+" exp {* plus *}
relexp : "[*" "<" exp "," exp ">" "|" fromlist "*]"
{* Rel Binaria em compreensao *}
| "[*" exppair-list "*]" {* makerel *}
exppair : exp "->" exp
letexp : "let" "(" deflist ")" "in" exp
deflist : def ("," def)*
def : SIMB "=" exp
ifexp : "if" exp "then" exp
| "if" exp "then" exp "else" exp
| "if" "(" caselist ")" ["otherwise" exp] {*comandos guardados*}
caselist : exp "->" exp ("," exp "->" exp )*
cond : exp
---------------------------------------------------------------------
N : QUANTIFICADORES
ALL : SYM SET BOOL -> BOOL
all( simb1 <- set1 , simb2 <- set2 , ... : expbool)
EXIST : SYM SET BOOL -> BOOL
exist( simb <- set : expbool)
EXIST1 : SYM SET BOOL -> BOOL
exist1( simb <- set : expbool)
---------------------------------------------------------------------
N : LOGICAS
and(&&) : BOOL BOOL -> BOOL
| exp "&&" exp {* and *}
not(~) : BOOL -> BOOL
| "~" exp {* not *}
or(||) : BOOL BOOL -> BOOL
| exp "||" exp {* or *}
false : -> BOOL
true : -> BOOL
---------------------------------------------------------------------
N : RELATIONAL
N : OP RELACIONAIS
eq : S-EXP S-EXP -> BOOL
equal(==) : S-EXP S-EXP -> BOOL
geq (>=) : INT INT -> BOOL / STR STR -> BOOL
gt : INT INT -> BOOL / STR STR -> BOOL
lt : INT INT -> BOOL / STR STR -> BOOL
neq : S-EXP S-EXP -> BOOL
nequal(!=) : S-EXP S-EXP -> BOOL
---------------------------------------------------------------------
N : INTEIRAS
add : INT INT -> INT
sub : INT INT -> INT
mul : INT INT -> INT
div : INT INT -> INT
rem : INT INT -> INT
max : INT+ -> INT
min : INT+ -> INT
abs : INT -> INT
ascii : STR -> INT
atoi : STR -> INT
card : SET -> INT / REL -> INT
chr : INT -> STR
itoa : INT -> STR
length : LIST -> INT
strlen : STR* -> INT
---------------------------------------------------------------------
N : SET
N : CONJUNTOS
difference(-) : SET SET -> SET
intersection(*) : SET SET -> SET
union(U) : SET SET -> SET
empty : -> SET
UNION : SET -> SET
makeset : S-EXP* -> SET
isempty : SET -> BOOL
member(in) : S-EXP SET -> BOOL
exp "notin" exp {* not member *}
exp "in" exp {* member *}
subset : SET SET -> BOOL
card : SET -> INT
choice : SET -> S-EXP
dom : REL -> SET / FF -> SET
elems : LIST -> SET
inseg : INT -> SET
ran : REL -> SET / FF -> SET
set : S-EXP {SYM (LIST|SET) [BOOL]}+ -> SET
the : SET -> S-EXP
---------------------------------------------------------------------
N : SEQ
N : LISTAS
CONC : LIST -> LIST
append : LIST LIST+ -> LIST
cons : S-EXP LIST -> LIST
el(=nth) : INT LIST -> S-EXP
elems : LIST -> SET
head(=hd) : LIST -> S-EXP
inds : LIST -> LIST
length : LIST -> INT
makeseq(=list) : S-EXP* -> LIST
nil : -> LIST
pair : S-EXP S-EXP -> LIST
plusq : LIST FF -> LIST
reduce : S-EXP SYM LIST -> S-EXP
reverse : LIST -> LIST
seq : S-EXP {SYM (LIST|SET) [BOOL]}+ -> LIST
tail(=tl) : LIST -> LIST
first : LIST INT -> S-EXP
second : LIST INT -> S-EXP
third : LIST INT -> S-EXP
fourth : LIST INT -> S-EXP
fifth : LIST INT -> S-EXP
---------------------------------------------------------------------
N : FF
N : FUNCOES FINITAS (MAPPINGS)
isempty : FF -> BOOL
ap : FF S-EXP [S-EXP] -> S-EXP
dom : FF -> SET
dr : FF SET -> FF
ds : FF SET -> FF
ff : SYM SET S-EXP [BOOL] -> FF
makeff : {S-EXP S-EXP}* -> FF
plus : FF FF -> FF
plusq : LIST FF -> LIST
ran : FF -> SET
---------------------------------------------------------------------
N : RELACOES BINARIAS
isempty : REL -> BOOL
member : S-EXP REL -> BOOL
subset : REL REL -> BOOL
card : REL -> INT
choice : REL -> S-EXP
difference : REL REL -> REL
dom : REL -> SET
dr : REL SET -> REL
ds : REL SET -> REL
intersection : REL REL -> REL
makerel : {S-EXP S-EXP}* -> REL
ran : REL -> SET
the : REL -> S-EXP
union : REL REL -> REL
---------------------------------------------------------------------
N : ALL
S : all( simb1 <- set1 , simb2 <- set2 , ... : expbool)
(ALL exp1 exp2 exp3)
F : SYM SET BOOL -> BOOL
(ALL s set pred) ^= [Implementa o quantificador universal, sendo 's' a
variavel quantificada, 'set' o dominio da
quantificacao e 'pred' o predicado;
o resultado e' "false" e o calculo termina quando,
para um dos elementos, eval( pred ) = "false";
o resultado e' "true" se se obtiver sucesso na
quantificacao;
as expressoes 'set' e 'pred' sao parcialmente
validadas sintaticamente, no caso de conterem
subexpressoes que definam variaveis locais ("let",
"lambda", "ALL", "EXIST", "EXIST1", "ff", "set",
"seq", "foreach")]
---------------------------------
N : abs
S : abs( exp1)
(abs exp1)
F : INT -> INT
(abs e1) ^= | e1 |
---------------------------------
N : add
S : add( exp1 exp2)
(add exp1 exp2)
F : INT INT -> INT
(add e1 e2) ^= eval( e1 ) + eval( e2 )
---------------------------------
N : and
S : exp "&&" exp {* and *}
(and exp1 exp2)
F : BOOL BOOL -> BOOL
(and e1 e2) ^= eval( e1 ) andif eval( e2 )
---------------------------------
N : ap
N : aply
S : exp "[" exp "]" {* (aply exp exp) *}
(ap exp1 exp2 [exp3])
F : FF S-EXP [S-EXP] -> S-EXP
(ap e1 e2 e3) ^= let f = eval( e1 )
s2 = eval( e2 )
in if el_set( s2, dom( f ))
then f(s2)
else eval( e3 )
["nil" caso nao exista e3]
---------------------------------
N : append
S : exp "^" exp {* (append exp exp) *}
(append exp1 exp2+)
F : LIST LIST+ -> LIST
(append e1 .. en) ^= eval( e1 ) ^ .. ^ eval( en )
---------------------------------
N : ascii
S : ascii( exp1)
(ascii exp1)
F : STR -> INT
(ascii e1) ^= [codigo ascii do primeiro caracter de eval( e1 );
se eval( e1 ) for "" o resultado e' 0]
---------------------------------
N : atoi
S : atoi( exp1)
(atoi exp1)
F : STR -> INT
P : [string numerica]
(atoi e1) ^= [inteiro representado pela "string" eval( e1 ); os espacos
iniciais sao desprezados; sao considerados apenas o sinal
(opcional) e os digitos ate' ao primeiro caracter nao nu-
merico; em caso de erro e' retornado o valor 0]
---------------------------------
N : atom
S : atom( exp1)
(atom exp1)
F : S-EXP -> BOOL
(atom e1) ^= let s1 = eval( e1 )
in s1 = nil orif
el_set( type( s1 ),
{INT, STR, SYM, SUBR, FPTR, CHAN(Config. "COMM")} )
---------------------------------
N : card
S : card( exp1)
(card exp1)
F : SET -> INT
REL -> INT
(card e1) ^= [numero de elementos do conjunto/relacao eval( e1 )]
---------------------------------
N : choice
S : choice( exp1)
(choice exp1)
F : SET -> S-EXP
REL -> S-EXP
P : eval( exp1 ) != {}
(choice e1) ^= [um elemento do conjunto/relacao eval( e1 );
implementado de forma a dar o primeiro da lista que
representa o conjunto]
---------------------------------
N : chr
S : chr( exp1)
(chr exp1)
F : INT -> STR
(chr e1) ^= ["string" com o caracter cujo codigo ascii e' eval( e1 )]
---------------------------------
N : CONC
S : CONC( exp1)
(CONC exp1)
F : LIST -> LIST
P : [os elementos de eval( exp1 ) sao listas]
(CONC e1) ^= l1 ^ l2 ^ ... ^ lk
[em que l1..lk sao as listas elementos da lista eval( e1 )]
---------------------------------
N : cons
S : "<" exp ":" exp ">" {* (cons exp exp) *}
(cons exp1 exp2)
F : S-EXP LIST -> LIST
Configs "nao LAZY": (cons e1 e2) ^= ^ eval( e2 )
Config. "LAZY": (cons e1 e2) ^= ^ delay( e2 )
---------------------------------
N : difference
S : exp "-" exp {* difference *}
(difference exp1 exp2)
F : SET SET -> SET
REL REL -> REL
(difference e1 e2) ^= eval( e1 ) - eval( e2 )
---------------------------------
N : div
S : div( exp1 exp2)
(div exp1 exp2)
F : INT INT -> INT
(div e1 e2) ^= eval( e1 ) div eval( e2 )
---------------------------------
N : dom
S : dom( exp1)
(dom exp1)
F : REL -> SET
FF -> SET
(dom e1) ^= [dominio da relacao/funcao finita eval( e1 )]
---------------------------------
N : dr
S : exp "/" exp {* dom restrict *}
(dr exp1 exp2)
F : REL SET -> REL
FF SET -> FF
(dr e1 e2) ^= [restringe o dominio da relacao/funcao finita eval( e1 )
ao conjunto eval( e2 )]
seja rf = ((1 b) (2 g) (8 h) (9 h))
(dr rf (makeset 1 2)) = ((1 b) (2 g))
---------------------------------
N : ds
S : exp "\" exp {* dom subtract *}
(ds exp1 exp2)
F : REL SET -> REL
FF SET -> FF
(ds e1 e2) ^= [elimina do dominio da relacao/funcao finita eval( e1 )
os elementos do conjunto eval( e2 )]
seja rf = ((1 b) (2 g) (8 h) (9 h))
(ds rf (makeset 1 2)) = ((8 h) (9 h))
---------------------------------
N : el ( nth )
S : el( exp1 exp2)
(el exp1 exp2)
F : INT LIST -> S-EXP
P : 0 < eval( exp1 ) <= [comprimento da lista eval( exp2 )]
(el e1 e2) ^= [eval( e1 )-esimo elemento da lista eval( e2 )]
---------------------------------
N : elems
S : elems( exp1)
(elems exp1)
F : LIST -> SET
(elems e1) ^= [conjunto dos elementos da lista eval( e1 )]
---------------------------------
N : empty
S : empty
F : -> SET
empty ^= {} [representado por "nil"]
---------------------------------
N : eq
S : eq( exp1 exp2)
(eq exp1 exp2)
F : S-EXP S-EXP -> BOOL
(eq e1 e2) ^= let s1 = eval( e1 )
s2 = eval( e2 )
in (s1 = s2 = nil) orif
if (type( s1 ) = type( s2 ) = INT) or
(type( s1 ) = type( s2 ) = STR) or
(type( s1 ) = type( s2 ) = FPTR) or
(type( s1 ) = type( s2 ) = CHAN(Config. "COMM")) or
(type( s1 ) = type( s2 ) = SUBR)
then @s1 = @s2
else if type( s1 ) = type( s2 ) = SYM
then s1 = s2
else false
---------------------------------
N : equal
S : exp "==" exp {* equal *}
(equal exp1 exp2)
F : S-EXP S-EXP -> BOOL
(equal e1 e2) ^= (eq e1 e2) orif eval( e1 ) = eval( e2 )
---------------------------------
N : EXIST
S : EXIST( exp1 exp2 exp3)
(EXIST exp1 exp2 exp3)
F : SYM SET BOOL -> BOOL
(EXIST s set pred) ^= [Implementa o quantificador existencial, sendo 's' a
variavel quantificada, 'set' o dominio da
quantificacao e 'pred' o predicado;
o resultado e' "true" se se obtiver sucesso na
quantificacao;
as expressoes 'set' e 'pred' sao parcialmente
validadas sintaticamente, no caso de conterem
subexpressoes que definam variaveis locais ("let",
"lambda", "ALL", "EXIST", "EXIST1", "ff", "set",
"seq", "foreach")]
---------------------------------
N : EXIST1
S : EXIST1( exp1 exp2 exp3)
(EXIST1 exp1 exp2 exp3)
F : SYM SET BOOL -> BOOL
(EXIST1 s set pred) ^= [Implementa o quantificador existencial exclusivo,
sendo 's' a variavel quantificada, 'set' o
dominio da quantificacao e 'pred' o predicado;
o resultado e' "false" e a quantificacao termina se
se encontrar um "segundo" 's' para o qual
eval( pred ) = "true" ou se eval( pred ) = "false"
para todos os 's';
as expressoes 'set' e 'pred' sao parcialmente
validadas sintaticamente, no caso de conterem
subexpressoes que definam variaveis locais ("let",
"lambda", "ALL", "EXIST", "EXIST1", "ff", "set",
"seq", "foreach")]
---------------------------------
N : false
S : false
F : -> BOOL
[constante booleana cujo valor e' o simbolo "false"]
---------------------------------
N : ff
S : ff( exp1 exp2 exp3 [exp4])
(ff exp1 exp2 exp3 [exp4])
F : SYM SET S-EXP [BOOL] -> FF
(ff sim set e b) ^= [funcao finita cujo dominio e' formado pelos
elementos 'sim' do conjunto eval( set ) que verifi-
cam eval( b ); o contra-dominio e' formado por
eval( e ) no ambiente aumentado por 'sim';
'sim' e' local a "ff" e o seu ambito sao as expressoes
'e' e 'b', nao fazendo sentido o seu uso em 'set';
as expressoes 'set', 'e' e 'b' sao parcialmente
validadas sintaticamente, no caso de conterem
subexpressoes que definam variaveis locais ("let",
"lambda", "ALL", "EXIST", "EXIST1", "ff", "set",
"seq", "foreach")]
(ff x (makeset 1 2 3) (add x 1) (not (eq x 2))) = ((1 2) (3 4))
---------------------------------
N : geq
S : exp ">=" exp {* geq *}
(geq exp1 exp2)
F : INT INT -> BOOL
STR STR -> BOOL
(geq e1 e2) ^= eval( e1 ) >= eval( e2 )
---------------------------------
N : gt
S : "(" exp ">" exp ")" {* gt *}
(gt exp1 exp2)
F : INT INT -> BOOL
STR STR -> BOOL
(gt e1 e2) ^= eval( e1 ) > eval( e2 )
---------------------------------
N : head ( hd )
S : head( exp1)
(head exp1)
F : LIST -> S-EXP
P : eval( exp1 ) != <>
Configs "nao LAZY": (head e1) ^= [primeiro elemento de eval( e1 )]
Config "LAZY":
(head e1) ^= if type( e1 ) = "lazy-list"
then eval( [primeiro elemento de e1] )
else let s1 = eval( e1 )
in if type( s1 ) = "lazy-list"
then eval( [primeiro elemento de s1] )
else [primeiro elemento de s1]
---------------------------------
N : inds
S : inds( exp1)
(inds exp1)
F : LIST -> LIST
(inds <>) = <>
(inds e1) ^= [lista constituida pelos naturais 1..comprimento da
lista eval( e1 )]
---------------------------------
N : inseg
S : inseg( exp1)
(inseg exp1)
F : INT -> SET
(inseg e1) ^= [conjunto formado pelos naturais 1..eval( e1 )]
---------------------------------
N : intersection
S : exp "*" exp {* intersection *}
(intersection exp1 exp2)
F : SET SET -> SET
REL REL -> REL
(intersection e1 e2) ^= eval( e1 ) /\ eval( e2 )
---------------------------------
N : isempty
S : isempty( exp1)
(isempty exp1)
F : SET -> BOOL
REL -> BOOL
FF -> BOOL
(isempty e1) ^= eval( e1 ) = {}/[]
---------------------------------
N : itoa
S : itoa( exp1)
(itoa exp1)
F : INT -> STR
(itoa e1) ^= ["string" formada pelos digitos (e sinal) do inteiro
eval( e1 )]
---------------------------------
N : length
S : length( exp1)
(length exp1)
F : LIST -> INT
(length e1) ^= [comprimento de eval( e1 )]
---------------------------------
N : leq
S : exp "<=" exp {* leq *}
(leq exp1 exp2)
F : INT INT -> BOOL
STR STR -> BOOL
(leq e1 e2) ^= eval( e1 ) <= eval( e2 )
---------------------------------
N : list ( makeseq )
S : (list exp1*)
F : S-EXP* -> LIST
(list) ^= <>
(list e1 ... ek) ^=
---------------------------------
N : lt
S : "(" exp "<" exp ")" {* lt *}
(lt exp1 exp2)
F : INT INT -> BOOL
STR STR -> BOOL
(lt e1 e2) ^= eval( e1 ) < eval( e2 )
---------------------------------
N : makeff
S : "[" exppair-list "]" {* makeff *}
(makeff {(exp1 exp2)}*)
F : {S-EXP S-EXP}* -> FF
P : [nao ha elementos repetidos no dominio]
(makeff) ^= []
(makeff (e1 e2) ... (ek ek+1)) ^=
[eval( e1 ) -> eval( e2 ), ..., eval( ek ) -> eval( ek+1 )]
---------------------------------
N : makerel
S : "[*" exppair-list "*]" {* makerel *}
(makerel {(exp1 exp2)}*)
F : {S-EXP S-EXP}* -> REL
(makerel) ^= {}
(makerel (e1 e2) ... (ek ek+1)) ^=
{ , ..., }
---------------------------------
N : makeseq ( list )
S : "<" exp-list ">" {* seq em extensao *}
(makeseq exp1*)
F : S-EXP* -> LIST
(makeseq) ^= <>
(makeseq e1..ek) =
---------------------------------
N : makeset
S : "{" exp-list "}" {* conj em extensao *}
(makeset exp1*)
F : S-EXP* -> SET
(makeset) ^= {}
(makeset e1 ... ek) ^= {eval( e1 ), ..., eval( ek )}
---------------------------------
N : max
S : max( exp1+)
(max exp1+)
F : INT+ -> INT ou
STR+ -> STR
(max e1..ek) ^= ei [maior valor de { e1, ..., ek }]
---------------------------------
N : member
S : member( exp1 exp2)
(member exp1 exp2)
F : S-EXP SET -> BOOL
S-EXP REL -> BOOL
(member e1 e2) ^= el_set( eval( e1 ), eval( e2 ))
---------------------------------
N : min
S : min( exp1+)
(min exp1+)
F : INT+ -> INT ou
STR+ -> STR
(min e1..ek) ^= ei (menor valor de { e1, ..., ek })
---------------------------------
N : mul
S : mul( exp1 exp2)
(mul exp1 exp2)
F : INT INT -> INT
(mul e1 e2) ^= eval( e1 ) * eval( e2 )
---------------------------------
N : neq
S : neq( exp1 exp2)
(neq exp1 exp2)
F : S-EXP S-EXP -> BOOL
(neq e1 e2) ^= not( eq( e1 e2 ) ) [ver funcao "eq"]
---------------------------------
N : nequal
S : exp "!=" exp {* diferente *}
(nequal exp1 exp2)
F : S-EXP S-EXP -> BOOL
(nequal e1 e2) ^= not( equal( e1 e2) ) [ver funcao "equal"]
---------------------------------
N : nil
S : nil
F : -> S-EXP
nil ^= <>
---------------------------------
N : not
S : "~" exp {* not *}
(not exp1)
F : BOOL -> BOOL
(not e1) ^= if eval( e1 )
then "true"
else "false"
---------------------------------
N : null
S : null( exp1)
(null exp1)
F : S-EXP -> BOOL
(null e1) ^= eval( e1 ) = nil
---------------------------------
N : or
S : exp "||" exp {* or *}
(or exp1 exp2)
F : BOOL BOOL -> BOOL
(or e1 e2) ^= eval( e1 ) orif eval( e2 )
---------------------------------
N : pair
S : pair( exp1 exp2)
(pair exp1 exp2)
F : S-EXP S-EXP -> LIST
(pair e1 e2) ^=
---------------------------------
N : plus
S : exp "+" exp {* plus *}
(plus exp1 exp2)
F : FF FF -> FF
(plus f1 f2) ^= [funcao finita cujo dominio e' a uniao dos dominios de
eval( f1 ) e eval( f2 ); a cada elemento do dominio
e' associado o elemento do contra-dominio da funcao que
lhe diz respeito; no caso de um elemento pertencer aos
dois dominios e'-lhe associado o elemento do contra-
-dominio de eval( f2 )]
sejam f1 = ((q 2) (w 2) (e 3))
f2 = ((q 3) (r 5) (h 4) (j 2))
(plus f1 f2) = ((q 3) (w 2) (e 3) (r 5) (h 4) (j 2))
---------------------------------
N : plusq
S : plusq( exp1 exp2)
(plusq exp1 exp2)
P : dom( eval( exp2 ) ) C= elems( inds( eval( exp1 )))
F : LIST FF -> LIST
(plusq e1 e2) ^= [lista eval( e1 ) reescrita nas posicoes determinadas
por 'i' pertencente a dom( eval( e2 )) pelo elemento
eval( e2 )(i)]
seja f = ((1 4) (5 3) (2 2))
l = (1 2 3 4 5 6)
(plusq l f) = (4 2 3 4 3 6)
---------------------------------
N : ran
S : ran( exp1)
(ran exp1)
F : REL -> SET
FF -> SET
(ran e1) ^= [contra-dominio da relacao/funcao finita eval( e1 )]
---------------------------------
N : reduce
S : reduce( exp1 exp2 exp3)
(reduce exp1 exp2 exp3)
F : S-EXP SYM LIST -> S-EXP
S-EXP SYM SET -> S-EXP
P : [exp2 e' o nome de uma funcao binaria] and
[o tipo do resultado e' o mesmo do segundo argumento] and
[o tipo de eval( exp1 ) e' o mesmo do segundo argumento] and
[os elementos de eval( exp3 ) sao do tipo do primeiro argumento] and
eval( exp3 ) != <> / {}
(reduce e s ls) ^= s( x1, s( x2, s( ..., s( xk, eval( e ))...)))
[em que eval( ls ) = / {x1, ..., xk}]
(reduce nil cons (list 1 2 1 3 1 4 5 6)) = (1 2 1 3 1 4 5 6)
(reduce 0 add (makeset 5 1 6 8 2)) = 22
---------------------------------
N : rem
S : rem( exp1 exp2)
(rem exp1 exp2)
F : INT INT -> INT
(rem e1 e2) ^= eval( e1 ) mod eval( e2 )
---------------------------------
N : reverse
S : reverse( exp1)
(reverse exp1)
F : LIST -> LIST
(reverse e1) ^= [lista eval( e1 ) invertida na ordem dos seus elementos]
---------------------------------
N : seq
S : seq( exp1 {(from exp2 exp3 [exp4]}+)
(seq exp1 {(from exp2 exp3 [exp4]}+)
F : S-EXP {SYM (LIST|SET) [BOOL]}+ -> LIST
(seq e1 (from s1 ls1 b1) ... (from sk lsk bk)) ^=
[lista dos elementos resultantes de eval( e1 ) no ambiente aumentado
pelos simbolos s1..sk; 'e1' e' calculado apenas quando a cada 'si'
esta' associado um valor da lista/conjunto eval( lsi ); as listas/
conjuntos sao totalmente percorridas/os e os predicados 'bi' sao
testados para cada combinacao de valores; caso nao exista um 'bi'
ele e' considerado "true"; uma combinacao so' e' valida quando
todos os 'bi' sao verificados; 'e1' pode ser funcao de todos os
'si' para alem de outros simbolos nao locais a "seq"; os 'bi' podem
ser funcao dos simbolos s1..si-1 para alem de outros simbolos nao
locais a "seq"; os simbolos 'si' sao mudos e locais a "seq"; um
simbolo 'si' nao deve ser incluido na expressao 'lsi' correspondente;
as expressoes 'lsi' e 'bi' sao parcialmente validadas sintaticamente,
no caso de conterem subexpressoes que definam variaveis locais
("let", "lambda", "ALL", "EXIST", "EXIST1", "ff", "set", "seq",
"foreach")]
(seq (list y x)
(from x (list 1 2 3 2) (not (eq x 1))) (from y (makeset 'q 'f))) =
((q 2) (f 2) (q 3) (f 3) (q 2) (f 2))
---------------------------------
N : set
S : set( exp1 {(from exp2 exp3 [exp4]}+)
(set exp1 {(from exp2 exp3 [exp4]}+)
F : S-EXP {SYM (LIST|SET) [BOOL]}+ -> SET
(set e1 (from s1 ls1 b1) ... (from sk lsk bk)) ^=
[conj. dos elementos resultantes de eval( e1 ) no ambiente aumentado
pelos simbolos s1..sk; 'e1' e' calculado apenas quando a cada 'si'
esta' associado um valor da lista/conjunto eval( lsi ); as listas/
conjuntos sao totalmente percorridas/os e os predicados 'bi' sao
testados para cada combinacao de valores; caso nao exista um 'bi'
ele e' considerado "true"; uma combinacao so' e' valida quando
todos os 'bi' sao verificados; 'e1' pode ser funcao de todos os
'si' para alem de outros simbolos nao locais a "set"; os 'bi' podem
ser funcao dos simbolos s1..si-1 para alem de outros simbolos nao
locais a "set"; os simbolos 'si' sao mudos e locais a "set"; um
simbolo 'si' nao deve ser incluido na expressao 'lsi' correspondente;
as expressoes 'lsi' e 'bi' sao parcialmente validadas sintaticamente,
no caso de conterem subexpressoes que definam variaveis locais
("let", "lambda", "ALL", "EXIST", "EXIST1", "ff", "set", "seq",
"foreach")]
(set (mul x y)
(from x (makeset 1 3 4)) (from y (list 1 2 4 5 2) (not (eq x y)))) =
(2 4 5 3 6 12 15 8 20)
---------------------------------
N : strcat
S : strcat( exp1*)
(strcat exp1*)
F : STR* -> STR
P : [o somatorio dos comprimentos das "strings"] <= 100
(strcat) ^= ""
(strcat e1 ... ek) ^= [concatenacao das "strings"
eval( e1 ) ... eval( ek )]
---------------------------------
N : strlen
S : strlen( exp1*)
(strlen exp1*)
F : STR* -> INT
(strlen) ^= 0
(strlen e1 ... ek) ^= [somatorio dos comprimentos das "strings"
eval( e1 ) ... eval( ek )]
---------------------------------
N : sub
S : sub( exp1 exp2)
(sub exp1 exp2)
F : INT INT -> INT
(sub e1 e2) ^= eval( e1 ) - eval( e2 )
---------------------------------
N : subset
S : subset( exp1 exp2)
(subset exp1 exp2)
F : SET SET -> BOOL
REL REL -> BOOL
(subset e1 e2) ^= eval( e1 ) C= eval( e2 )
---------------------------------
N : substr
S : substr( exp1 exp2 [exp3])
(substr exp1 exp2 [exp3])
F : STR INT [INT] -> STR
(substr e1 e2 e3) ^= ["substring" de eval( e1 ) iniciada na posicao
eval( e2 ) e formada por eval( e3 ) caracteres;
se eval( e2 ) < 1 ou eval( e2 ) > comprimento
da "string" eval( e1 ) o resultado e' "";
se nao existir o argumento 'e3' ou
se eval( e2 ) + eval( e3 ) > comprimento da
"string" eval( e1 ) o resultado e' a "string"
formada pelos caracteres seguintes a eval( e2 )
inclusive']
(substr "abcdef" 2) = (substr "abcdef" 2 6) = "bcdef"
(substr "abcdef" 2 -1) = ""
(substr "abcdef" 2 3) = "bcd"
---------------------------------
N : the
S : the( exp1)
(the exp1)
F : SET -> S-EXP
REL -> S-EXP
P : [eval( exp1 ) contem um e um so' elemento]
(the e1) ^= [o unico elemento do conjunto/relacao eval( e1 )]
---------------------------------
N : true
S : true
F : -> BOOL
[constante booleana cujo valor e' o simbolo "true"]
---------------------------------
N : tail ( tl )
S : tail( exp1)
(tail exp1)
F : LIST -> LIST
P : eval( exp1 ) != <>
Configs. "nao LAZY":
(tail e1) ^= [eval( e1 ) retirando-lhe o primeiro elemento]
Config. LAZY:
(tail e1) ^= if type( e1 ) = "lazy-list"
then [e1 retirando-lhe o primeiro elemento]
else [eval( e1 ) retirando-lhe o primeiro elemento]
---------------------------------
N : union
S : exp "U" exp {* union *}
(union exp1 exp2)
F : SET SET -> SET
REL REL -> REL
(union e1 e2) ^= eval( e1 ) U eval( e2 )
---------------------------------
N : UNION
S : UNION( exp1)
(UNION exp1)
F : SET -> SET
P : [os elementos de eval( exp1 ) sao conjuntos]
(UNION e1) ^= s1 U s2 U ... U sk
[em que s1..sk sao os conjuntos elementos do conjunto
eval( e1 )]
8.2 Funcoes para comunicacao sincrona (Config. "COMM")
---------------------------------
N : chanel
S : chanel( exp1)
(chanel exp1)
F : STR -> CHAN
STR -> nil
P : 1 <= [comprimento de eval( exp1 )] <= 4
(chanel e1) ^= [criacao de um canal de comunicacao de nome eval( exp1 );
da' "nil" como resultado caso nao consiga cria'-lo]
---------------------------------
N : receive
S : receive( exp1)
(receive exp1)
F : CHAN -> S-EXP
(receive e1) ^= [expressao-S recebida pelo canal eval( e1 )]
---------------------------------
N : send
S : send( exp1 exp2)
(send exp1 exp2)
F : CHAN S-EXP -> S-EXP
P : eval( exp2 ) = nil orif
el_set( type( eval( exp2 )), {INT, STR, SYM, LIST, SET, REL, FF, FUN,
tipos def. pelo utilizador (Config. USERTYPE")})
(send e1 e2) ^= eval( e2 )
[como efeito lateral, envia eval( e2 ) atraves do canal
eval( e1 )]
8.3 Funcoes condicionais
---------------------------------
N : cond
S : cond( {(exp1 exp2*)}*)
(cond {(exp1 exp2*)}*)
F : {BOOL S-EXP*}* -> S-EXP
(cond) ^= nil
(cond (b1 e1 ... ek) ... (bn en ... en+m)) ^=
[calcula todas as expressoes 'ej' associadas ao primeiro 'bi' cujo
valor e' "true"; da' como resultado eval( [ultima expressao dessa
serie]); no caso de todos os 'bi' serem falsos o resultado e' "nil"]
(cond (false (add 2 3))
(true (def x 3) (def y 4) (add 4 5))
((lt 2 3) 'q)) = 9 ['x' e 'y' sao inseridos na tabela de simbolos
com os valores 3 e 4 respectivamente]
---------------------------------
N : if
S : "if" exp "then" exp
"if" exp "then" exp "else" exp
"if" "(" caselist ")" ["otherwise" exp] {*comandos guardados*}
(if exp1 exp2 [exp3])
F : BOOL S-EXP [S-EXP] -> S-EXP
(if e1 e2 e3) ^= if eval( e1 )
then eval( e2 )
else eval( e3 )
[e3 e' "nil" por defeito]
8.4 Aplicacao de funcoes definidas pelo utilizador
---------------------------------
S : exp1( exp2*)
(exp1 exp2*)
F : FUN S-EXP* -> S-EXP
SUBR S-EXP* -> S-EXP
P : [tomar atencao `a ordem, tipo e numero de argumentos]
(f e1 ... ek) ^=
[E feito o calculo de f, "eval( f )";
Testa-se o tipo do resultado:
- se for SUBR, a funcao correspondente e' invocada com os parametros
e1..ek
- se for FUN, na config. "nao LAZY", e' invocada a funcao definida
pelo utilizador apos serem ligados aos seus parametros formais os
valores resultantes do calculo de e1..ek
- se for FUN, na config. "LAZY", e' invocada a funcao definida pelo
utilizador apos serem ligados aos seus parametros formais o resul-
tado dos "delay" de e1..ek]
8.5 Definicoes locais
---------------------------------
N : let
S : "let" "(" deflist ")" "in" exp
(let ({(exp1 exp2)}*) exp3*)
F : {SYM S-EXP}* S-EXP* -> S-EXP
(let ((s1 e1) ... (sk ek)) exp1 ... expn) ^=
[Config. "nao LAZY": para cada par ('si, 'ei') e' feito o eval( ei ) apos
o que o ambiente e' alargado com o valor de 'si'; o processamento dos
pares e' sequencial de 1 a k;
Config. "LAZY": sao ligados aos simbolos 'si' os valores respectivos
resultantes de delay( e1 )..delay( ek );
e' feito o "eval" das exp1..expn; o resultado de "let" e' eval( expn );
caso nao existam 'expi' o resultado e' "nil";
os simbolos s1..sk sao mudos nao tendo qualquer ligacao com simbolos
com o mesmo nome definidos noutras expressoes; o ambito do simbolo 'si' e'
exp1..expn;
as expressoes 'ei' e 'expi' sao parcialmente validadas sintaticamente, no
caso de conterem subexpressoes que definam variaveis locais ("let",
"lambda", "ALL", "EXIST", "EXIST1", "ff", "set", "seq", "foreach")]
8.6 Definicao de funcoes e simbolos
---------------------------------
N : def
S : def( exp1 lambda (exp2*) exp3)
(def exp1 lambda (exp2*) exp3)
(def exp1 exp2)
F : SYM SYM* S-EXP -> SYM
SYM S-EXP -> SYM
P : [exp1 nao pode ser um dos simbolos reservados da "shell"]
(def s lambda (s1 ... sk) e1) ^= s
[como efeito lateral faz a ligacao de 's' `a funcao definida pelo
utilizador com nome 's', parametros formais s1..sk e corpo 'e1'; os
parametros formais sao mudos nao tendo qualquer ligacao com simbolos
com o mesmo nome definidos noutras expressoes; o simbolo 's' e'
inserido na lista de operadores associada ao simbolo "ops" (8.8.3)]
(def s e1) ^= s
[como efeito lateral liga 's' a eval( e1 ); o simbolo 's' e' inserido
na lista de objectos associada ao simbolo "obs" (8.8.3)]
---------------------------------
N : lambda
S : lambda( (exp1*) exp2)
(lambda (exp1*) exp2)
F : SYM* S-EXP -> FUN
(lambda (s1 ... sk) e1) ^=
[funcao anonima definida pelo utilizador cujos parametros formais sao
os simbolos 'si' e cujo corpo e' 'e1'; os parametros formais sao mudos
nao tendo qualquer ligacao com simbolos com o mesmo nome definidos
noutras expressoes; o ambito deles e' 'e1';
a expressao 'e1' e' parcialmente validada sintaticamente, no caso de
conter subexpressoes que definam variaveis locais ("let", "lambda",
"ALL", "EXIST", "EXIST1", "ff", "set", "seq", "foreach");]
8.7 Definicao de tipos pelo utilizador (Config. "USERTYPE")
8.7.1 Relacao com a Sintaxe Abstracta VDM
Esta configuracao extende o "metoo" base permitindo ao utilizador a definicao de
tipos a um nivel de abstraccao identico ao da Sintaxe Abstracta VDM.
Numa clausula de "Sintaxe Abstracta Metoo" podem ser definidos tuplos, alter-
nativas, igualdades, funcoes finitas, relacoes binarias, listas, conjuntos e os
tipos atomicos simbolos, inteiros, "strings", "file pointers" e canais (Config.
"COMM").
8.7.2 BNF das "expressoes de tipo"
::= | | | |
| | |
::= | | |
| |
::= 'TUP' { '(' ')' }+
::= 'ALT' ['NIL'] +
::= 'EQ'
::= 'FF'
::= 'REL'
::= 'LIST'
::= 'SET'
::= 'SYM' | 'INT' | 'STR' | 'FPTR' | 'CHAN' (Config. "COMM")
::= simbolo "metoo"
::= simbolo "metoo"
8.7.3 Funcoes
8.7.3.1 Definicao
---------------------------------
N : deftype
S : deftype( exp1 exp2)
(deftype exp1 exp2)
F : SYM -> SYM
P : [exp1 nao pode ser um dos simbolos reservados da "shell"]
(deftype t etipo) ^= t
[associa ao simbolo 't' o tipo definido pela expressao
'etipo'; em 'etipo' podem existir identificadores de
tipos ainda nao definidos; nao sao postas restricoes
a definicoes directa ou indirectamente recursivas;
o simbolo 't' passa a ser utilizavel como construtor
de objectos do seu tipo; no caso deste ser um tuplo as
etiquetas podem ser utilizadas como selectores - a
existencia de etiquetas com o mesmo nome em tuplos
diferentes nao introduz confusao; no caso dos tuplos
os simbolos correspondentes `as etiquetas nao podem
ser reservados e o seu valor e' redefinido]
8.7.3.2 Construcao/Interrogacao
8.7.3.2.1 Compatibilidade expressoes - tipos
Considere-se "exp" uma expressao com valor de um dos seguintes tipos:
tipo definicao "exp compativel t" se
------------------------------------------------------------------------------
tuplo (deftype t TUP (et1 c1) .. (etm cm)) exp e' do tipo t
alternativa (deftype t ALT a1 .. am) EX i. exp compativel ai
igualdade (deftype t EQ t1) exp compativel t1
lista (deftype t LIST t1) exp e' do tipo t ou
conjunto (deftype t SET t1) exp e' uma lista/conjunto constituida/o
por elementos compativeis com t1
relacao bin (deftype t REL t1 t2) exp e' do tipo t ou
funcao finita (deftype t FF t1 t2) exp e' uma relacao/funcao com dominio/
contra-dominio constituidos por elementos
compativeis com t1/t2
atomicos (deftype t ...) exp e' do tipo t ou
(INT, SYM, ...) exp e' do tipo atomico que t define
------------------------------------------------------------------------------
A todos os tipos definidos pelo utilizador e' associado um construtor.
Estabelecendo um paralelo com o VDM, observa-se que este construtor so' e'
obrigatorio na construcao de valores de tipo tuplo associando-lhes uma etiqueta.
Os construtores de alternativas nunca etiquetam os valores.
No caso dos tipos das algebras "metoo" e dos tipos atomicos o uso de construtor
e' facultativo. Se para a definicao de um valor for usado um construtor, o valor
sera' etiquetado. Note-se que um objecto etiquetado nunca e' compativel com o
tipo de um objecto nao etiquetado.
8.7.3.2.2 Construcao
---------------------------------
N : [t - nome do tipo definido pelo utilizador atraves de "deftype"]
S : t( exp1+)
(t exp1+)
F : S-EXP+ -> t
hipoteses:
1: t define um tuplo -- TUP (et1 c1) .. (etm cm)
construtor -- (t e1 .. en)
pre'-condicao : (n = m) and (AL i. eval( ei ) compativel ci)
2: t define uma alternativa -- ALT a1 .. am
construtor -- (t e1)
pre'-condicao : EX i. eval( e1 ) compativel ai
3: t define uma igualdade -- EQ b
construtor -- (t e1)
pre'-condicao : eval( e1 ) compativel b
4: t define uma lista/conjunto -- LIST/SET b
construtor -- (t e1)
pre'-condicao : [eval( e1 ) e' uma lista/conjunto cujos elementos sao
compativeis com b]
5: t define uma relacao bin./funcao finita -- REL/FF b c
construtor -- (t e1)
pre'-condicao : [eval( e1 ) e' uma relacao bin./funcao finita cujos
elementos do dominio sao compativeis com b e os
elementos do contra-dominio sao compativeis com c]
6: t define um tipo atomico -- INT/STR/SYM/FPTR/CHAN(Config. "COMM")
construtor -- (t e1)
pre'-condicao : [eval( e1 ) e' do tipo correspondente]
8.7.3.2.3 Interrogacao
---------------------------------
N : is
S : "is-" SIMB "(" exp ")" {* (is SIMB exp) *}
(is exp1 exp2)
F : S-EXP -> BOOL
MACTYPE S-EXP -> BOOL
(is tipo exp) ^= [se tipo e' uma macro de tipos ("MACTYPE")
da' eval( exp ) compativel tipo representado pela
macro
senao eval( exp ) compativel 'tipo']
A definicao de uma macro e' feita pela funcao:
---------------------------------
N : mactype
S : mactype( exp1 exp2+)
(mactype exp1 exp2+)
F : SYM SYM+ -> SYM
P : [exp1 nao pode ser um dos simbolos reservados da "shell"]
(mactype s slist) ^= s
[cria uma expressao do tipo "MACTYPE" associando-a
ao simbolo 's'; o valor de 's' na tabela de simbolos
e' redefinido;
a validacao sintatica da expressao de tipo
representada por 'slist' sera' feita aquando do seu
uso em "is"]
8.7.3.3 Eliminacao de etiquetas de um valor
Representacao interna de um valor de tipo definido pelo utilizador
tuplos : um valor e' representado por uma lista etiquetada com o nome do tipo
correspondente;
alternativas : o nome de uma alternativa nunca e' usado como etiqueta;
igualdades : o valor e' sempre etiquetado com o nome da igualdade excepto
quando o tipo final da cadeia de igualdades for uma alternativa;
algebras "metoo"
e atomicos : o valor (representado da mesma forma que valores de tipos
"xmetoo" correspondentes) e' etiquetado com o nome do tipo
definido pelo utilizador.
Para que os valores de tipos definidos pelo utilizador possam ser operados por
funcoes da "shell", as etiquetas terao que ser removidas. Isso tera que ser
feito pela funcao:
---------------------------------
N : ignlab
S : ignlab( exp1)
(ignlab exp1)
F : S-EXP -> S-EXP
(ignlab exp) ^= [se exp nao e' um valor etiquetado
eval( exp ) seguido da remocao de etiquetas
senao da' exp sem as etiquetas]
8.8 Funcoes da "Shell"
8.8.1 Memoria
---------------------------------
N : alloc
S : alloc( exp1)
(alloc exp1)
F : INT -> INT
P : eval( exp1 ) >= 1
(alloc e1) ^= [altera o numero de nodos a alocar por segmento para
eval( e1 ), retornando o valor anterior]
---------------------------------
N : expand
S : expand( [exp1])
(expand [exp1])
F : [INT] -> INT
P : eval( exp1 ) >= 1
(expand e1) ^= [tenta alocar eval( e1 ) segmentos (1 no caso de e1 nao
existir; retorna o numero de segmentos realmente alocados]
---------------------------------
N : gc
S : gc()
(gc)
F : -> nil
(gc) ^= nil
[como efeito lateral executa uma "garbage-collection"; se neces-
sario e possivel aloca novo segmento]
---------------------------------
N : mem
S : mem()
(mem)
F : -> nil
(mem) ^= nil
[como efeito lateral imprime no ecran as estatisticas:
Nodes - numero de nodos alocados desde o inicio do processo ate'
ao momento
Free nodes - numero de nodos livres nos segmentos que compoem a
memoria actual do interpretador
Segments - numero de segmentos alocados ate' ao momento
Allocate - numero de nodos a alocar por segmento quando for
necessario reservar novos segmentos
Collections - numero de "garbage-collections" efectuadas ate' ao
momento]
8.8.2 "I/O" sobre Ficheiros
---------------------------------
N : fclose
S : fclose( exp1)
(fclose exp1)
F : FPTR -> nil
P : [o ficheiro apontado por eval( exp1 ) tem que estar aberto]
(fclose e1) ^= nil
[fecha o ficheiro apontado por eval( e1 )]
---------------------------------
N : fgetc
S : fgetc( [exp1])
(fgetc [exp1])
F : [FPTR] -> INT | nil
P : [o ficheiro apontado por eval( exp1 ) tem que estar aberto]
(fgetc e1) ^= [codigo ASCII do proximo caracter do ficheiro apontado por
eval( e1 ) (teclado por defeito); retorna "nil" caso se
atinja o fim do ficheiro]
---------------------------------
N : fgets
S : fgets( [exp1])
(fgets [exp1])
F : [FPTR] -> STR | nil
P : [o ficheiro apontado por eval( exp1 ) tem que estar aberto]
(fgets e1) ^= [proxima linha do ficheiro apontado por eval( e1 )
(teclado por defeito); retorna "nil" caso se atinja
o fim do ficheiro]
---------------------------------
N : fopen
S : fopen( exp1 exp2)
(fopen exp1 exp2)
F : STR STR -> FPTR | nil
(fopen e1 e2) ^= ["file pointer" para o ficheiro de nome eval( e1 )
aberto em modo eval( e2 ); modos possiveis:
"r" - leitura de um ficheiro ja existente
"w" - escrita num ficheiro (re)criado
"a" - escrita apos fim de ficheiro
"r+"- leitura/escrita num fich. ja existente
"w+"- leitura/escrita num ficheiro (re)criado
"a+"- leitura/escrita apos fim do ficheiro
caso nao consiga a abertura, retorna "nil"]
---------------------------------
N : fputc
S : fputc( exp1 [exp2])
(fputc exp1 [exp2])
F : INT [FPTR] -> INT
P : [o ficheiro apontado por eval( exp2 ) tem que estar aberto]
(fputc e1 e2) ^= eval( e1 )
[como efeito lateral escreve no ficheiro eval( e2 ) (ecran por defeito)
o caracter de codigo ASCII eval( e1 )]
---------------------------------
N : fputs
S : fputs( exp1 [exp2])
(fputs exp1 [exp2])
F : STR [FPTR] -> STR
P : [o ficheiro apontado por eval( exp2 ) tem que estar aberto]
(fputs e1 e2) ^= eval( e1 )
[como efeito lateral escreve no ficheiro eval( e2 ) (ecran por defeito)
a "string" eval( e1 )]
---------------------------------
N : m2read
S : m2read( exp1)
(m2read exp1)
P : [o ficheiro apontado por eval( e1 ) tem que estar aberto para leitura]
F : FPTR -> S-EXP
(m2read e1) ^= [retorna "eval" da " expressao "S" lida do ficheiro apontado
por eval( e1 ); no caso de ser encontrado EOF termina em
erro]
---------------------------------
N : m2write
S : m2write( exp1 exp2)
(m2write exp1 exp2)
P : [o ficheiro apontado por eval( e1 ) tem que estar aberto para escrita] and
(el_set( type( eval( exp2 )), {INT, STR, SYM, LIST, SET, REL, FF,
tipos def. pelo utilizador (Config. USERTYPE")}))
F : FPTR S-EXP -> nil
(m2write e1 e2) ^= nil
[como efeito lateral escreve o resultado de eval( e2 )
no ficheiro apontado por eval( e1 ) de forma que
m2read( fp m2write( fp exp ) = exp]
---------------------------------
N : stdin
S : stdin
F : -> FPTR
[apontador para o "standard input" actual]
---------------------------------
N : stdout
S : stdout
F : -> FPTR
[apontador para o "standard output" actual]
---------------------------------
N : readf
S : readf( exp1)
(readf exp1)
P : [o ficheiro apontado por eval( e1 ) tem que estar aberto para leitura]
F : FPTR -> S-EXP
(readf e1) ^= [retorna a expressao "S" lida do ficheiro apontado por
eval( e1 ); no caso de ser encontrado EOF termina em erro]
---------------------------------
N : writef
S : writef( exp1 exp2)
(writef exp1 exp2)
P : [o ficheiro apontado por eval( e1 ) tem que estar aberto para escrita] and
(el_set( type( eval( exp2 )), {INT, STR, SYM, LIST, SET, REL, FF,
tipos def. pelo utilizador (Config. USERTYPE")}))
F : FPTR S-EXP -> nil
(writef e1 e2) ^= nil
[como efeito lateral escreve o resultado de eval( e2 )
no ficheiro apontado por eval( e1 )]
8.8.3 Diversas
---------------------------------
N : eval
S : eval( exp1)
(eval exp1)
F : S-EXP -> S-EXP
(eval e1) ^= eval( eval( e1 ))
---------------------------------
N : !
S : (! [exp1])
(! [exp1])
F : [INT] ->
(! e1) ^= [unica forma de terminar a execucao do processo retornando
eval( e1 ) (0 por defeito) ao sistema operativo]
---------------------------------
N : foreach
S : foreach( exp1 exp2 exp3*)
(foreach exp1 exp2 exp3*)
F : SYM LIST S-EXP* -> S-EXP
(foreach s l e1 ... ek) ^=
[liga-se sucessivamente "s" a todos os elementos de eval( l ) e calcu-
lam-se as expressoes e1..ek em cada ambiente resultante; o resultado
e' o valor da ultima expressao calculada; e' retornado "nil" caso
eval( l ) seja "nil" ou caso nao existam expressoes e1..ek;
as expressoes 'l' e 'ei' sao parcialmente validadas sintaticamente, no
caso de conterem subexpressoes que definam variaveis locais ("let",
"lambda", "ALL", "EXIST", "EXIST1", "ff", "set", "seq", "foreach")]
---------------------------------
N : load
S : load( exp1)
(load exp1)
F : STR -> STR
(load e1) ^= [le e calcula todas as expressoes "S" contidas no ficheiro
de nome eval( e1 ); retorna eval( e1 ); os resultados do
calculo das expressoes contidas no ficheiro nao sao
visualizadas]
---------------------------------
N : LOAD
S : LOAD( exp1)
(LOAD exp1)
F : STR ->
(LOAD e1) ^= [reinicializa o estado (guardado por "SAVE") carregando-o
do ficheiro com nome eval( e1 )]
---------------------------------
N : oblist
S : oblist
F : -> LIST
[lista com todos os simbolos que constituem o estado]
---------------------------------
N : obs
S : obs
F : -> LIST
[lista com os simbolos definidos atraves da funcao "def" usada na forma
"(def exp1 exp2)" (8.6)]
---------------------------------
N : ops
S : ops
F : -> LIST
[lista com os simbolos (nomes de funcoes) definidos atraves da funcao "def"
usada na forma "(def exp1 lambda (exp2*) exp3)" (8.6)]
---------------------------------
N : PACK
S : PACK( exp1)
(PACK exp1)
F : LIST -> SYM
(PACK e1) ^= [simbolo cujo nome e' a concatenacao dos nomes dos simbolos
e/ou inteiros positivos elementos da lista eval( e1 )]
---------------------------------
N : princ
S : princ( exp1*)
(princ exp1*)
F : S-EXP* -> nil
(princ e1 .. ek) ^= nil
[como efeito lateral imprime no ecran o eval( e1 ) .. eval( ek )]
---------------------------------
N : print
S : print( exp1*)
(print exp1*)
F : S-EXP* -> nil
(print e1 .. ek) ^= nil
[como efeito lateral imprime no ecran o eval( e1 ) .. eval( ek );
ao imprimir uma "string", sao substituidos:
- "escape" por "\e"
- "newline" por "\n"
- "return" por "\r"
- "tab" por "\t"
- caracteres nao visiveis pelo seu codigo octal "\ddd"]
---------------------------------
N : prog1
S : prog1( exp1*)
(prog1 exp1*)
F : S-EXP* -> S-EXP
(prog1) ^= nil
(prog1 e1 ... ek) ^= [faz eval( e1 )..eval( ek );
retorna o valor eval( e1 )]
---------------------------------
N : progn
S : progn( exp1*)
(progn exp1*)
F : S-EXP* -> S-EXP
(progn) ^= nil
(progn e1 ... ek) ^= [faz eval( e1 )..eval( ek );
retorna o valor eval( ek )]
---------------------------------
N : quote
S : quote( exp1)
(quote exp1)
[equivalente a 'exp1]
F : S-EXP -> S-EXP
(quote e1) ^= e1
---------------------------------
N : read
S : read( [exp1])
(read [exp1])
F : [STR] -> S-EXP
(read e1) ^= [expressao "S" contida em eval( e1 ); no caso de "e1" nao
existir, a leitura e' feita do teclado]
---------------------------------
N : repeat
S : repeat( exp1 exp2*)
(repeat exp1 exp2*)
F : INT S-EXP* -> S-EXP
(repeat e1 e2 ... ek) ^=
[retorna o valor da ultima expressao calculada; o calculo das expres-
soes e2..ek e' feito eval( e1 ) vezes ; e' retornado "nil" no caso de
eval( e1 ) ser menor ou igual a 0 ou no caso de nao existirem
expressoes e2..ek]
---------------------------------
N : SAVE
S : SAVE( exp1)
(SAVE exp1)
F : STR -> nil
(SAVE e1) ^= [guarda o estado no ficheiro com nome eval( e1 ); o estado
podera' ser recuperado por "LOAD"]
---------------------------------
N : sh
S : sh( [exp1])
(sh [exp1])
F : [STR] -> INT
(sh s) ^= [passa o controlo ao sistema operativo para execucao do comando
na "string" eval( s );
no caso de nao existir argumento e' criada uma "shell" do
sistema sobre o "xmetoo";
UNIX: e' retornado o codigo de erro resultado da execucao do
comando;
MS/DOS: e' retornado o estado na saida do "COMMAND.COM"]
---------------------------------
N : type
S : type( exp1)
(type exp1)
F : S-EXP -> SYM
(type e1) ^= type( eval( e1 ))
---------------------------------
N : trace
S : trace()
(trace)
F : -> nil
(trace) ^= nil
[como efeito lateral nega a "trace-flag"(5.3)]
---------------------------------
N : UNPACK
S : UNPACK( exp1)
(UNPACK exp1)
F : SYM -> LIST
(UNPACK e1) ^= [lista de simbolos (constituidos por um caracter) ou
inteiros (0..9) que concatenados dao o simbolo eval( e1 )]
---------------------------------
N : while
S : while( exp1 exp2*)
(while exp1 exp2*)
F : BOOL S-EXP* -> S-EXP
(while e1 e2 ... ek) ^=
[retorna o valor da ultima expressao calculada; o calculo das expres-
soes e2..ek e' feito enquanto eval( e1 ) for "true"; no caso de
eval( e1 ) = "false" `a partida e' retornado "nil";
no caso de nao existirem expressoes e2..ek a calcular o resultado
sera' "nil" quando eval( e1 ) = "false"]
=cut