|
|
DataMuseum.dkPresents historical artifacts from the history of: Bogika Butler |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about Bogika Butler Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - metrics - download
Length: 17664 (0x4500)
Types: TextFile
Names: »EOSP.OV2«
└─⟦61d7681d7⟧ Bits:30009789/_.ft.Ibm2.50006629.imd Mogens Pelles Zilog 80,000 / EOS projekt
└─⟦this⟧ »EOSP.OV2«
^U3. Virkefeltsregler i EosPascal.^u
I dette afsnit vil jeg give en oversigt over virkefeltsreglerne
i EosPascal, herunder de regler, der gælder for standard-Pascal.
^U3.1. Virkefeltsregler i Pascal-standarden.^u
Virkefeltsreglerne i standard-Pascal er de velkendte regler
for blok-strukturerede sprog. I Pascal-standarden opstilles reglerne
på følgende måde på grundlag af begreberne "område" og "virkefelt":
$#klæb
Enhvert navn og enhver etikette har et ^Udefinitionspunkt^u.
Definitionspunktet er (undtagen i visse tilfælde for
feltnavne) det sted, hvor navnet eller
etiketten ^Kerklæres^k. For f.eks. etiketter er dette ^Kikke^k det
samme som det sted, hvor etiketten ^Kdefineres^k.
Til hvert definitionspunkt er der et ^Uområde^u, som er en del
af programteksten, samt et ^Uvirkefelt^u, som er det hele eller
en del af området.
Området for et definitionspunkt er stort set altid ^Khele^k den
mindste blok, som indeholder definitionspunktet (dvs. også de dele
af blokken, som ligger før definitionspunktet). For parametre til
procedurer og funktioner er området dog procedurens/funktionens
blok. Hvad angår
definitionspunkterne for de prædefinerede navne ("real", "char" etc.),
omfatter de tilsvarende områder naturligvis hele programmet.
Som nævnt adskiller behandlingen af feltnavne for poster sig fra
det ovenstående. Feltnavne opfattes som havende flere definitionspunkter
med hvert sit tilknyttede område og virkefelt. Disse definitionspunkter
falder i tre klasser:
(1) Det sted, feltnavnet optræder i en post-definition. Det
tilsvarende område er hele den pågældende post-definition.
(2) Steder, hvor feltnavnet bruges ved udvælgelse af et felt
af en post-variable (f.eks. "b" i "a.b"). Stedet, hvor post-variablen
optræder, siges at være definitionspunkt for alle feltnavne for den
pågældende post-type, med et område, der kun omfatter
feltnavns-positionen ("b" i eksemplet).
(3) With-sætninger. Stedet, hvor en post-variabel optræder i en
with-sætning, betragtes som definitionspunkt for alle feltnavne for
den pågældende post-type, med et område, der omfatter den sætning,
som with-sætningen indeholder.
I alle tilfælde gælder det, at
virkefeltet for et definitionspunkt er dets område (inklusive
alle områder, som det indeholder), med de to begrænsninger, der nævnes
nedenfor.
Den første begrænsning er Pascals blok-struktur:
^KHvis^k et navn eller en etikette har et definitionspunkt for et område A,
og et andet navn eller etikette, som staves på samme måde, har et
definitionspunkt for et område B, og A indeholder B, ^Kså^k er
området B og alle områder, som det indeholder, undtaget fra
virkefeltet for område A's definitionspunkt.
Den anden begrænsning er lidt simplere: Det område, der
udgøres af feltnavnet i en
feltudvælgelse (f.eks. "b" i "a.b") er undtaget fra alle virkefelter,
som omgiver det (men naturligvis ikke fra virkefeltet for feltnavnet).
I samme område må der ikke være mere end et definitionspunkt for
det samme navn eller den samme etikette.
En ^Uanvendelse^u ("applied occurrence") af et navn eller en
etikette er enhver brug af navnet eller etiketten indenfor dets/dens
virkefelt, undtagen den brug, der gøres af navnet eller etiketten
på definitionspunktet. Sådan en brug kaldes i stedet en ^Udefinition^u
("defining occurrence") af navnet eller etiketten. Ingen brug af
navnet eller etiketten udenfor dets/dens virkefelt kaldes en anvendelse
af det/den (men kan naturligvis være en anvendelse eller definition af et
andet objekt, hvis navn staves på samme måde).
Endelig er der en restriktion, der er som skabt til at gøre
livet lettere for oversætter-konstruktører: Enhver anvendelse af
et navn eller en etikette skal komme ^Kefter^k dets/dens
definition. Dog er det tilladt at referere forlæns til type-navne
når man definerer nye pointer-typer. De type-navne, der refereres
forlæns til, skal defineres i den samme "type-definition-part",
som indeholder forlæns-henvisningen.
^U3.2. Virkefeltsregler i EosPascal.^u
De specielle virkefeltsregler i EosPascal er beskrevet i
afsnit 4.5 (side 17-18), 5.1 (side 19) og 6.2 (side 20) i EosPascal-manualen.
Jeg vil ikke gengive dem, men påpege nogle ting, der virker
besynderlige, og som ikke passer så godt sammen med Pascals
virkefeltsregler.
I afsnit 4.5 får man at vide, at en lokal størrelse i
en "entry implementation" kan skjule et argument til den pågældende
indgang. Dette er inkonsistent med den tilsvarende regel for
parametre til procedurer og funktioner (en parameter betragtes -
hvad angår dets virkefelt - ganske som en lokal variabel for proceduren
eller funktionen).
I afsnit 5.1 beskrives, hvordan navne, der defineres inden for
objekt-typer, også kan bruges udenfor disse. Det er ikke så besynderligt,
da det kan sammenlignes med f.eks.
$#kopier blok-start
var r : record
a : (x,y,z)
end;
$#formatter blok-slut
hvor "x", "y" og "z" har et "område", der omfatter hele den
blok, som indeholder variabelerklæringen.
Det besynderlige er, at navne, der defineres inden for
objekt-typer, kan skjules af senere definitioner på ^Ksamme^k
niveau som objekt-type-definitionen.
Og selv om de er blevet skjult, kan man stadig referere
til dem v.hj.a. en "qualified identifier". Endvidere ser man i
afsnit 6.1, at disse navne gøres synlige igen inden for
objekt-implementationer. Det virker alt sammen underligt på
baggrund af Pascals normale virkefeltsregler.
Til sidst: I afsnit 6.2 mangler der præcise regler for,
hvilke navne, der kan skjule hvilke (svarende til redegørelsen
i afsnit 4.5).
^U4. Bemærkninger i øvrigt.^u
I dette afsnit vil jeg trække nogle ting fra
EosPascal-manualen frem, som jeg mener trænger til en uddybning.
^UAfsnit 3.1 (side 7ff)^u
Det ser ud, som om "adaptable arrays" er en slags pointere
med særlig fleksibilitet m.h.t. måltypen. En nøje granskning
af EosPascal-manualen giver som resultat, at den eneste mulige
repræsentation for en variabel af type "adaptable array" er et
par (pointer,^ længde). Pointeren peger på array-elementerne,
og "længde" er deres totale længde i bytes. Endvidere er
pointeren ^Urelativ^u til sig selv.
^UAfsnit 3.1.2 (side 8)^u
En <array slice> kan indledes med en række komma-adskilte
udtryk før "range" kommer. Disse udtryk skal vel svare til
"almindelige" indices f.eks. i sammenhængen:
$#kopier klæb blok-start
▶1b◀Rtype artype = arrayÆ1.1000Å of char;
var x : arrayÆ1..10Å of ^^ÆÅ artype;
xÆ2,456..789Å▶1b◀R▶04◀
$#blok-slut formatter
^UAfsnit 3.1.2 (side 8)^u
Det ser ud som om elementerne af en array slice
nummereres om, når slicen laves. Således formoder jeg, at i
$#klæb kopier blok-start
▶1b◀Rvar a : arrayÆ10..1000Å of char;
har
aÆ60..70Å
elementerne
aÆ60..70ÅÆ10Å ( = aÆ60Å )
aÆ60..70ÅÆ11Å ( = aÆ61Å )
.
.
aÆ60..70ÅÆ20Å ( = aÆ70Å )▶1b◀R▶04◀
$#blok-slut formatter
^UAfsnit 3.1.4 (side 9)^u
Den sidste sætning i afsnittet skal vel fortolkes
således, at den formelle "adaptable array"-variabel bliver
initialiseret, så den henviser til den aktuelle parameter-variabel
(snarere en til en kopi af den aktuelle parameter-variabel). Dette
antydes bl.a. af parameterlisten til og
implementationen af standard-proceduren "bind"
(filerne FAMILY.UNIV.ID, linie 163-169, hhv. EOSLIB.LIB.SA,
næsten i slutningen). Det er altså lidt af en tilsnigelse at
kalde den formelle parameter for en værdi-parameter.
Endvidere ser det ud som om en strengkonstant kan være
aktuel parameter for en sådan formel værdiparameter (se f.eks.
FAMILY.UNIV.ID, linie 45-47, PASINCLU.MIKTYPES.SA, linie 20, samt
EOSMODUL.JCL.SA, linie 312). Dette er
ikke tilladt ifølge EosPascal-manualens afsnit 3.1.4.
^UAfsnit 3.2.1 (side 10)^u
Som det er tilfældet ved definition af nye pointer-typer,
er det tilladt at definere nye kerne-pointer-typer under
henvisning til objekt-typer, der først defineres senere i teksten.
Dette benyttes i FAMILY.OBJDIR.ID, linie 19.
^UAfsnit 3.2.1 (side 11)^u
Ang. andet og tredie afsnit på siden: Bemærk forskellen
mellem at en kernepointer henviser til en "adaptable array type"
og til en "adaptable target". Forskellen illustreres af
de to kernepointer i følgende posttype:
$#klæb kopier blok-start
▶1b◀Rrecord
k1 : ^^^^ ^^ÆÅ arrtype;
k2 : ^^^^ ÆÅ arrtype;
end▶1b◀R▶04◀
$#formatter blok-slut
K1 henviser til et (meget lille) data-segment, som kun
indeholder en adaptable array (dvs. en relativ pointer og
en længdeangivelse). Hvis data-segmentet er længere end som så,
kan man eventuelt initialisere denne adaptable array, så den
peger på resten af datasegmentet. Det kan man gøre v.hj.a.
proceduren "bind": ^Kwith^ x=k1^^^^^ do^ bind(x,^ x,^ 5678)^k.
Derefter kan man henvise til resten af datasegmentet under navnet
"x" i ^Kwith^ x=k1^^^^^ do^ ....^k.
Det er forøvrigt interessant, at "bind" slet ikke bruges i de
Eos-tekster, vi har. Endvidere ser man, at det er af hensyn til
konstruktioner som den viste, pointer-delen af en adaptable array
er nødt til at være relativ (datasegmentet kan jo blive mappet ind
på forskellige steder i adresserummet).
K2 henviser på en måde til hele datasegmentet. En
sætning: ^Kwith^ x=k2^^^^^ do^ ....^k giver adgang til hele
datasegmentet i form af en adaptable array "x".
(Dette fremgår af afsnit (4) side 13, og ses anvendt i
EOSMODUL.MCCM.SA, linierne 744, 798 og 803, baseret på
erklæringen i FAMILY.IOSYS.ID, linie 93.) Denne adaptable
array skabes dynamisk af with-sætningen.
^UAfsnit 3.2.4, delen "(2,3,4) Data Segment Targets" (side 13)^u
Med "any (pointer or) adaptable array pointer components must
not be selected" menes formodentlig, at man ikke må udtage elementer
af en adaptable array ved indicering eller "slicing". Det er velsagtens
tilladt at udvælge et felt af en post, selv om feltet er
en adaptable array? I øvrigt fremgår det af afsnit 3.2.1 (side 11,
femte afsnit), at målvariablen ikke ^Kkan^k indeholde felter af
pointer-type (det er måske derfor, "pointer or" står i parentes?).
^UAfsnit 3.4 (side 14)^u
Her er det uklart, hvad der sker, når den aktuelle
parameter er en adaptable array. Jeg vil gennemgå tre tilfælde:
Hvis den formelle parameter er en værdi-parameter, men ikke
en adaptable array, er det klart en fejl.
Hvis den formelle parameter er en værdi-parameter, som også
er en adaptable array, er der tvivl om resultatet.
Den formelle parameter kan
henvise til enten den aktuelle parameters (pointer,^ længde) par, eller
til de array-elementer, pointer-delen af dette par peger på.
Hvis den formelle parameter er en variabel-parameter, som også
er en adaptable array, får man formodentlig via den formelle parameter adgang
til den aktuelle parameters (pointer,^ længde) par. Dette vil
svare bedst til den måde, variabel-parametre i øvrigt opfattes (og
implementeres) på. Parameterlisten til og implementationen af "bind"
(filerne FAMILY.UNIV.ID, linie 163-169, hhv. EOSLIB.LIB.SA,
næsten i slutningen) afhænger at, at dette er tilfældet.
Generelt kan det siges, at uklarhederne opstår, fordi det
ikke er klart, hvad "representation" for en adaptable array-variabel
er: Parret (pointer,^ længde) eller de elementer, pointeren peger på?
Det er i øvrigt helt generelt, at der er forvirring omkring adaptable
arrays, fordi man ikke skelner skarpt mellem disse to ting. Måske burde
man ændre syntaksen lidt, så man i
$#klæb blok-start kopier
var adap : ^^ÆÅ arrtype;
skelner mellem
adap (henviser til parret (pointer, længde))
og
adap^^ (henviser til elementerne)
så f.eks.
adap^^Æ17Å
$#blok-slut formatter klæb
er et enkelt element af en adaptable array. På denne måde lægger man
sig tættere op ad den måde, pointere og de tilhørende målvariable
håndteres på.
^UAfsnit 4 (side 15)^u
"External name" i entry-definitioner benyttes ikke i de
Eos-tekster, vi har.
^UAfsnit 4.4 (side 17)^u
Hvis en entry-implementation skal svare til en tidligere
givet entry-definition, skal denne entry-definition vel tilhøre
samme objekt-type som implementationen?
Entry-implementationens navn kan vel ikke være
"qualified"?
^UAfsnit 5 (side 19)^u
"External name" benyttes ikke i objekt-type-definitionerne
i de Eos-tekster, vi har.
Der mangler "end;" til slut i syntaksen for objekt-type-definitioner
(?)
^UAfsnit 5.1 (side 19)^u
Navnet på den pågældende objekt-type skal vel være synligt på
det sted, hvor en "qualified identifier" benyttes? Ellers opstår der
flertydigheder som f.eks. i:
$#kopier klæb blok-start
object ob1;
const c = 47;
...entries...
end;
object ob2;
entry en;
end;
program p object ob2
with record end
entry en
with record end;
var ob1 : record
c : set of char;
end;
begin
.... ob1.c ....
end;
$#formatter blok-slut
Her er "ob1.c" i næstsidste linie flertydig. "ob1.c" kan henvise
til konstanten "c" i objektet "ob1" eller til feltet "c" i posten "ob1".
Flertydigheden forsvinder dog, hvis variablen "ob1" skjuler objekttypen "ob1".
^UAfsnit 6.2 (side 20)^u
Her står intet om, hvilke navne, der kan skjule hvilke. Mon ikke
man kan opdele navnene i fire klasser svarende til de fire afsnit i afsnit
6.2, og så regne med, at hvis to entiteter med samme navn findes i hver sin
klasse, er det entiteten fra den klasse, der nævnes senest, der er synlig
i objekt-implementationen? Således vil f.eks. et feltnavn i "local
kernel pointer record" (tredie afsnit)
kunne skjule navnet på en objekt-indgang, hvis
dette "arves" fra en objekt-type-definition (andet afsnit).
^UAfsnit 8.2 (side 25)^u
Her nævnes det, at "if the type of the kernel pointer variable
has an object type target, the entry identifiers defined in the corresponding
object type definition can be referred directly even if they are redefined".
Det synes klart, at dette gælder, når bruger et indgangsnavn
til at angive, hvilken indgang, der
skal kaldes. Gælder det også, når man bruger et udtryk?
Dvs. kan man i dette udtryk referere direkte til indgangsnavnene
for den pågældende objekttype (uden "qualification")?
Hvis ikke, er følgende programstump flertydig:
$#kopier klæb blok-start
object ob1;
entry en1;
end;
object ob2;
entry en2;
end;
program p object ob1
with record k : ^^^^ob2 end
entry en1
with record end;
const en2 = 1007;
begin
k.en2(....)
end;
$#formatter blok-slut
I den næstsidste linie kan "k.en2" have den syntaktiske struktur
$#klæb blok-start kopier
<kernel pointer variable> . <entry identifier>
eller
<kernel pointer variable> . <expression>
$#blok-slut formatter klæb
siden indgangsnavnet "en2" også kan optræde som et udtryk (som vil
give indgangens nummer som resultat).
Da syntaksen således er flertydig, skal semantikken være den
samme for begge muligheder. Ellers har vi en flertydig konstruktion.
Hvis "en2" opfattes som en "entry identifier", vil f.eks. indgang
nummer 1 bliver kaldt. Hvis "en2" opfattes som et udtryk, bliver
resultatet afhængigt af, om "en2" henviser til indgangen "en2" eller
konstanten "en2". Den eneste måde at redde den
semantiske entydighed på, er at lade
"en2" henvise til indgangen også i dette tilfælde - dvs. at den
ovenfor citerede sætning skal gælde også når man bruger et udtryk.
Så vil det for øvrigt være naturligt, at ikke alene navne på
indgange, men alle lokale navne defineret i objekt-type-definitionen,
kan benyttes uden "qualification" i udtrykket.
Det ville nok være bedre at fjerne den syntaktiske flertydighed,
f.eks. ved at kræve en parentes rundt om et eventuelt udtryk?
^UAfsnit 8.2.2 og 8.2.3 (side 26)^u
Vedrørende subsegment-argumenter (afsnit 8.2.2):
Hvis argumentet er en "target variable", som er en "adaptable
target", må man være opmærksom på, at implementationen er nødt til
at foretage en implicit "mapseg"-operation for få fat i datasegmentets
længde. Denne længde er en nødvendig del af den beskrivelse af
subsegment-argumentet, som skal overgives til kernen.
Ville det ikke være mere rimeligt at lade
programmøren skrive en tilsvarende "mapping-with"-sætning explicit?
Bemærk, at tilsvarende komplikationer ^Kikke^k opstår i
forbindelse med værdi-argumenter (afsnit 8.2.3), da disse ikke kan
være "target variables" (se afsnit 3.2.4,
"(2,3,4) Data Segment Targets", side 13).
^UAfsnit 9.1 (side 28)^u
Angående synonymer for "array slices": Man skal formodentlig
holde sig fra at bruge "new", "dispose", "push" og "bind" på
sådanne synonymer?
Angående "mapping with": Man kan godt ændre den involverede
kerne-pointer i with-sætningens krop, men så kan man ikke
længere bruge den mappede variabel som subsegment-argument (jeg kan
i hvert fald ikke se, hvordan det skulle kunne implementeres).
«eof»