-- AMModel.mesa
-- Last Modified On October 25, 1982 11:00 am By Paul Rovner
-- HOLES: nested procedures. nested configs. multiple sections of the same source.

DIRECTORY
Rope USING [ROPE],
RTBasic USING [Type],
TimeStamp USING [Stamp],
WorldVM USING [World];

AMModel: DEFINITIONS = { OPEN Rope, RTBasic, WorldVM;

-- TYPEs

Class: TYPE = {world, model, prog, interface, proc, statement}; -- objects of concern herein

Source: TYPE = REF SourceObj; -- range in a source file
SourceObj: TYPE = RECORD[ fileName: ROPENIL, -- without path, e.g. foo.mesa
class: Class,
versionStamp: TimeStamp.Stamp,
sourceRange: SELECT tag: * FROM
entire => [],
field => [firstCharIndex: CharIndex ← 0,
lastCharIndex: CharIndex ← 0
-- lastCharIndex < firstCharIndex
-- means empty range
]
ENDCASE
];

CharIndex: TYPE = INT; -- into a source file. The first char has index = 0.

IRIndex: TYPE = INT; -- into an interface instance.
-- The first item has index = 1 (AMTypes convention).

Section: TYPE = REF SectionObj;
SectionObj: TYPE; -- opaque
-- A Section represents one of:
-- binder output bundle for a config [class = model]
-- (someday modeller output bundle for a model)
-- compiler output bundle for a prog module [class = prog]
-- compiler output bundle for a DEFs module [class = interface]
-- compiler output bundle for a proc [class = proc]
-- compiler output bundle for a statement [class = statement]

Context: TYPE = REF ANY; -- Context should be opaque, but convenient this way for now
-- A Context represents one of:
-- world [class = world]
-- loadstate entry [class = model]
-- global frame [class = prog]
-- interface record [class = interface]
-- local frame [class = proc]
-- local frame and PC [class = statement]

PartialInterfaceInstance: TYPE = RECORD[ir: Context--class = interface--,
usingList: LIST OF IRIndex];


-- PROCs ...


RootContext: PROC[world: World] RETURNS[Context];
-- a "rootContext" represents a "loadstate" model of an entire running Cedar world.
-- Immediate children are its top-level Contexts: loadstate entries for
-- individually loaded program modules and bound configs (someday models).
-- Truth: ContextClass[RootContext] = world.


-- ... dealing with Source

SourceFileName: PROC[source: Source] RETURNS[ROPE] =
INLINE {RETURN[source.fileName]};

SourceClass: PROC[source: Source] RETURNS[Class] =
INLINE {RETURN[source.class]};

SourceVersion: PROC[source: Source] RETURNS[TimeStamp.Stamp] =
INLINE {RETURN[source.versionStamp]};

SourceSection: PROC[source: Source, context: --worldRoot or model--Context]
RETURNS[section: Section, contexts: LIST OF --prog--Context];
-- Use SourceSection to figure out (given a proc or statement source location)
-- where to place a breakpoint (and in which world).
-- The list of prog Contexts returned by SourceSection is meaningful for
-- prog, proc and statement sources. It will be ordered "most-recently-loaded first".
-- Strictly speaking, a source can have multiple sections: one for each set of "SectionParams".
-- Someday we'll accommodate this, but not this week.


-- ... dealing with Sections

SectionClass: PROC[section: Section] RETURNS[Class];

SectionName: PROC[section: Section] RETURNS[ROPE];
-- e.g. config name, prog or interface module name, proc name;
-- for statements: procName.<FGIndex>

SectionType: PROC[section: Section] RETURNS[--procedure--Type];
-- Implemented only for proc sections

SectionVersion: PROC[section: Section] RETURNS[TimeStamp.Stamp];

SectionSource: PROC[section: Section] RETURNS[Source];
-- param to creator of section.

SectionParams: PROC[section: Section]
RETURNS[LIST OF --interface-- Type];
-- ditto (e.g. DIRECTORY entries)
-- Will be implemented only for model, prog and interface sections.

SectionChildren: PROC[section: Section, proc: PROC[Section] RETURNS[stop: BOOL]]
RETURNS[ans: Section ← NIL--NIL if not stopped--];
-- an enumerator.
-- children: modules of a model, procs of a module, statements of a proc

ParentSection: PROC[section: Section] RETURNS[Section];
-- container:
-- prog module for a proc
-- proc for a statement


-- ... dealing with Contexts
-- Entry to this stuff:
-- a tv for a global frame (TypeClass = globalFrame) has class = prog
-- a tv for a local frame (TypeClass = localFrame) has class = proc

ContextClass: PROC[context: Context] RETURNS[Class];

ContextWorld: PROC[context: Context] RETURNS[World];

ContextName: PROC[context: Context] RETURNS[ROPE];
-- world => worldName
-- model => <configName>:ConfigIndex#<index in loadstate>
-- prog => <progName>:gfh#<gfh>
-- interface => <interface name>
-- proc => <procName>:fh#<fh>
-- statement => <ContextName[proc]>:FGT#<index in fgt>

MostRecentNamedContext: PROC[name: ROPE, context: --world or model--Context]
RETURNS[Context];
-- EXAMPLE USAGE: given a module name and a world context, this returns
-- a Context for the most recently loaded global frame for a program with that name.
-- name must identify
-- a model or prog (someday interface) if context identifies a world, or
-- a prog (someday interface) if context identifies a model.
-- The format of the name should be the same as that produced by ContextName,
-- with elided fields meaning "don't care".
-- The result will be either a model or prog (someday interface) context.

NamedContexts: PROC[name: ROPE,
context: --worldRoot or model--Context,
proc: PROC[Context] RETURNS[stop: BOOL]]
RETURNS[Context--NIL if not stopped--];
-- an enumerator.
-- Like MostRecentNamedContext, but gets 'em all.

ContextSection: PROC[context: Context] RETURNS[Section];
--param to creator of context

ParentContext: PROC[context: Context] RETURNS[Context];
-- world => NIL
-- model => world
-- prog => model
-- proc => prog
-- statement => proc

ContextChildren: PROC[context: Context, proc: PROC[Context] RETURNS[stop: BOOL]]
RETURNS[Context--NIL if not stopped--];
-- an enumerator
-- world -> models or progs (TVs for global frames),
-- model -> progs,
-- proc -> statement (proc will be called only once)


-- ... dealing with PartialInterfaceInstances

Imports: PROC[context: Context]
RETURNS[LIST OF PartialInterfaceInstance];
-- Implemented only for model and prog contexts

Exports: PROC[context: Context]
RETURNS[LIST OF PartialInterfaceInstance];
-- Implemented only for model and prog contexts

}.