-- file codedefs.mesa
-- last modified by Sweet, November 15, 1979  12:48 PM

  AltoDefs: FROM "altodefs" USING [BYTE, wordlength],
  ControlDefs: FROM "controldefs" USING [ControlLink, MaxFrameSize],
  Literals: FROM "literals" USING [LTIndex, STIndex],
  Symbols: FROM "symbols" USING [BTIndex, ContextLevel, HTIndex, ISEIndex, ISENull, lZ, RecordSEIndex],
  SymbolSegment: FROM "symbolsegment" USING [ByteIndex],
  Table: FROM "table" USING [Base, Limit, Notifier];

  BEGIN OPEN Literals, Symbols;

  Lexeme: TYPE = RECORD [
    lexvalue: SELECT lextag: * FROM
      literal => [
    	SELECT littag: * FROM
	  word => [lexlti: LTIndex],
	  string => [lexsti: STIndex],
      se => [lexsei: ISEIndex],
      bdo => [lexbdoi: VarIndex],
      stack => [lexsti: StackIndex],

  NullLex: se Lexeme = Lexeme[se[Symbols.ISENull]];

  MoveDirection: TYPE = {load, store};

  VarSpace: TYPE = {faddr, frame, frameup, caddr, code, link, linkup, stack, const, pdesc};

  VarTag: TYPE = {o, bo, bdo, ind};

  VarComponent: TYPE = RECORD [
    wSize: CARDINAL ← 0 | NULL,
    bSize: [0..AltoDefs.wordlength) ← 0 | NULL,
    space: SELECT tag: VarSpace FROM
      frame => [
	immutable: BOOLEAN ← FALSE,
	level: ContextLevel ← lZ,
	wd: CARDINAL ← 0,
	bd: [0..AltoDefs.wordlength) ← 0],
      code => [wd: CARDINAL ← 0, bd: [0..AltoDefs.wordlength) ← 0],
      faddr => [wd: CARDINAL, level: ContextLevel],
      frameup => [
	level: ContextLevel ← lZ,
        pwSize: [1..2] ← 1,
	immutable: BOOLEAN ← FALSE,
	wd: CARDINAL ← 0,
	delta: [0..ControlDefs.MaxFrameSize) ← 0],
      caddr, link => [wd: CARDINAL],
      linkup => [
	delta: [0..ControlDefs.MaxFrameSize) ← 0],
      stack => [
	bd: [0..AltoDefs.wordlength) ← 0,
	wd: CARDINAL ← 0,
	sti: StackIndex],
      const => [bd: [0..AltoDefs.wordlength) ← 0, d1, d2: UNSPECIFIED ← NULL],
      pdesc => [desc: ControlDefs.ControlLink], -- unrelocated control link

  VarItem: TYPE = RECORD [ -- not many of these around at any given time
    free: BOOLEAN ← FALSE, -- required by allocator
    body: SELECT tag: VarTag FROM
      o => [var: VarComponent],
      bo => [offset, base: VarComponent],
      bdo => [offset, base, disp: VarComponent],
      ind => [
        offset, base, index: VarComponent,
	simple: BOOLEAN,
        packinfo: SELECT packtag: * FROM
          packed => [grain: [1..AltoDefs.wordlength)],
          notPacked => [eWords: [0..ControlDefs.MaxFrameSize)],

  VarIndex: TYPE = Table.Base RELATIVE POINTER [0..Table.Limit) TO VarItem;
  OVarIndex: TYPE = Table.Base RELATIVE POINTER [0..Table.Limit)
    TO o VarItem;
  BoVarIndex: TYPE = Table.Base RELATIVE POINTER [0..Table.Limit)
    TO bo VarItem;
  BdoVarIndex: TYPE = Table.Base RELATIVE POINTER [0..Table.Limit)
    TO bdo VarItem;
  IndVarIndex: TYPE = Table.Base RELATIVE POINTER [0..Table.Limit)
    TO ind VarItem;
  VarNull: VarIndex = LOOPHOLE[Table.Limit-1];

  RelativePC: TYPE = [0..77777B];
  CCInfoType: TYPE = {generating, binding, coding};
  CodeChunkType: TYPE = {code, label, jump, other};

	free: BOOLEAN,
	pad: [0..1], -- this is NOT a fill field
	flink, blink: CCIndex,
	ccvalue: SELECT cctag: CodeChunkType FROM
	  code => [
		realinst, minimalStack: BOOLEAN,
		inst: AltoDefs.BYTE,
		aligned: BOOLEAN,
		isize: [0..3],
		fill: [0..7B],
		sourcefileindex: SymbolSegment.ByteIndex,
		parameters: ARRAY [1..1) OF WORD],
	  label => [
		labelseen: BOOLEAN,
		labelinfo: SELECT OVERLAID CCInfoType FROM
		  generating => [filltoword, jumplist: JumpCCIndex],
		  binding => [minPC, maxPC: RelativePC],
		  coding => [filltoword, pc: RelativePC],
	  jump => [
		jsize: [0..7],
		jtype: JumpType,
		jparam: AltoDefs.BYTE,
		fixedup, completed: BOOLEAN,
		destlabel: LabelCCIndex,
		forward: BOOLEAN,
		  generating => [filltoword, thread: JumpCCIndex],
		  binding => [minPC, maxPC: RelativePC],
		  coding => [filltoword, pc: RelativePC],
	  other => [obody: SELECT otag: * FROM
	    table => [
		btab: BOOLEAN,
		tablecodebytes: [0..7],
		taboffset: INTEGER],
	    startbody, endbody => [
		index: BTIndex],
	    source => [index: SymbolSegment.ByteIndex],

  NULLfileindex: SymbolSegment.ByteIndex = 177777B;

  CCIndex: TYPE = Table.Base RELATIVE POINTER [0..Table.Limit) TO CCItem;
  CCNull: CCIndex = LOOPHOLE[Table.Limit-1];
  JumpCCIndex: TYPE = Table.Base RELATIVE POINTER [0..Table.Limit) TO jump CCItem;
  JumpCCNull: JumpCCIndex = LOOPHOLE[Table.Limit-1];
  LabelCCIndex: TYPE = Table.Base RELATIVE POINTER [0..Table.Limit) TO label CCItem;
  LabelCCNull: LabelCCIndex = LOOPHOLE[Table.Limit-1];
  CodeCCIndex: TYPE = Table.Base RELATIVE POINTER [0..Table.Limit) TO code CCItem;
  CodeCCNull: CodeCCIndex = LOOPHOLE[Table.Limit-1];
  OtherCCIndex: TYPE = Table.Base RELATIVE POINTER [0..Table.Limit) TO other CCItem;
  TableCCIndex: TYPE = Table.Base RELATIVE POINTER [0..Table.Limit) TO table other CCItem;
  TableCCNull: TableCCIndex = LOOPHOLE[Table.Limit-1];

  CompareClass: TYPE = {word, byte};

  JumpType: TYPE =
	{JumpE, JumpN, JumpL, JumpGE, JumpG, JumpLE,
	UJumpL, UJumpGE, UJumpG, UJumpLE, ZJumpE, ZJumpN, 
	Jump, JumpA, JumpC, JumpCA, JumpRet,

  EXLabelRecord: TYPE = RECORD [
	free: BOOLEAN,
	thread: EXLRIndex,
	labelcc: CARDINAL,
	labelhti: HTIndex,
	labelcci: LabelCCIndex];

  EXLRIndex: TYPE = Table.Base RELATIVE POINTER [0..Table.Limit) TO EXLabelRecord;
  EXLRNull: EXLRIndex = LOOPHOLE[Table.Limit-1];

  StackIndex: TYPE = Table.Base RELATIVE POINTER [0..Table.Limit) TO
  StackNull: StackIndex = LAST[StackIndex];

  StackItem: TYPE = RECORD [
    free: BOOLEAN ← FALSE,
    uplink, downlink: StackIndex ← StackNull,
    data: SELECT tag:* FROM
      mark => [label: LabelCCIndex],
      onStack => [
	alsoLink: BOOLEAN ← FALSE,
	tLevel: Symbols.ContextLevel ← lZ,
	tOffset: TempAddr ← NULL],
      inTemp => [
	tLevel: Symbols.ContextLevel,
	tOffset: TempAddr],
      inLink => [link: AltoDefs.BYTE],

-- if alsoTemp for onStack element, it has been previously dumped
--   by the stack machinery into the given temp.

  StackPos: TYPE = [0..EvalStackSize);

  StackLocRec: TYPE = RECORD [SELECT tag:* FROM
    onStack => [depth: CARDINAL],
    inTemp => [
      tSize: TempSize,
      tLevel: Symbols.ContextLevel,
      tOffset: TempAddr],
    inLink => [link: [0..256)],
    mixed => NULL,

-- StackLocRec semantics:
--  obtained by lr: StackLocRec ← Stack.Loc[s, count];
--	Tag		Meaning
--	onStack		The "count" words are all on the stack.
--			  There are "depth" words above them in the model
--	inTemp		The "count" words are in contiguous temporaries
--	inLink		"count" = 1 and value is in link "link"
--	mixed		None of the above

  EvalStackSize: INTEGER = 8;
  MaxParmsInStack: INTEGER = EvalStackSize-3;

  TempAddr: TYPE = [0..ControlDefs.MaxFrameSize);
  TempSize: TYPE = [0..ControlDefs.MaxFrameSize);

  TempStateRecord: TYPE = RECORD[
	pendtemplist, templist, heaplist: ISEIndex,
	tempctxlvl: ContextLevel,
	tempstart, framesz: INTEGER];

  CaseCVState: TYPE = {single, singleLoaded, multi, none};

  ConsDestination: TYPE = RECORD [
    bd: [0..AltoDefs.wordlength) ← NULL,
    bSize: [0..AltoDefs.wordlength) ← NULL,
    inFrame: BOOLEAN ← FALSE, -- can store directly into frame
    fLevel: Symbols.ContextLevel ← NULL,
    pLength: [1..2] ← 1,
    ignoreSafen: BOOLEAN ← FALSE,
    fOffset: CARDINAL ← NULL, -- offset of first word of record
    pLoaded: BOOLEAN ← FALSE, -- pointer already on virtual stack
    pSti: StackIndex ← NULL, -- the sti of the pointer if pLoaded
    pDelta: INTEGER ← 0, -- word offset into record of pointer
    pLink: BOOLEAN ← FALSE, -- pointer also in a link
    pLevel: Symbols.ContextLevel ← lZ, -- if not lZ, then ptr is in temp
    pOffset: TempAddr ← NULL, -- frame offset of temp or link
    remaining: CARDINAL ← 0,
    wSize: CARDINAL ← NULL

  StatementStateRecord: TYPE = RECORD [
    retLabel, comRetLabel: LabelCCIndex,
    outRecord: RecordSEIndex,
    pendtemplist: ISEIndex,
    stkPtr: UNSPECIFIED,
    inlineFileIndex: SymbolSegment.ByteIndex];

  ChunkIndex: TYPE = Table.Base RELATIVE POINTER [0..Table.Limit);

  AddressNotify, AJumpsNotify, CallsNotify, CgenUtilNotify,
  ConstructorNotify, CrossJumpNotify, DJumpsNotify, DriverNotify,
  ExpressionNotify, FinalNotify, FlowNotify, FlowExpressionNotify,
  OutCodeNotify, PeepholeNotify, StackImplNotify,
  StatementNotify, StoreNotify, TempNotify, VarBasicsNotify,
  VarMoveNotify, VarUtilsNotify: Table.Notifier;

  Address, AJumps, Calls, CgenUtil, Constructor, CrossJump, DJumps, Driver, Expression, Final, Flow, FlowExpression, OpTable, OutCode, PeepholeQ, PeepholeU, PeepholeZ, StackImpl, Statement, Store, Temp, VarBasics, VarMove, VarUtils: PROGRAM;