RiscAssembler.ThreeC4
Copyright Ó 1987 by Xerox Corporation. All rights reserved.
Bill Jackson (bj) May 27, 1987 7:49:06 pm PDT
Lucy Hederman July 15, 1987 4:52:11 pm PDT
RiscAssemblerParser: Control Module;
RiscAssemblerToken: Module = Begin
Tokens
{ "NOOP" "GOTO" ":" ";" "." } : SimpleTokens;
id: GenericToken = "tokenID";
End;
RiscAssemblerCG: Module = Begin
goal: NonTerminal Builds Program;
for goal ← program
Buildprogram;
program: NonTerminal Builds Program;
for program.list ← list "."
BuildProgram.list[list];
list: NonTerminal Builds List;
for list.statement ← statement
BuildList.statement[statement];
for list.dangle ← statement ";"
BuildList.dangle[statement];
for list.cons ← statement ";" list
BuildList.cons[statement, list];
statement: NonTerminal Builds Statement;
for statement.label ← label ":" statement
BuildStatement.label[label, statement];
for statement.op ← op
BuildStatement.op[op];
for statement.oprand ← op rand
BuildStatement.oprand[op, rand];
label: NonTerminal Builds Label;
for label.id ← id
BuildLabel.id[id];
op: NonTerminal Builds Op;
for op.noop ← "NOOP"
BuildOp.noop[];
for op.goto ← "GOTO"
BuildOp.goto[];
rand: NonTerminal Builds Rand;
for rand.id ← id
BuildRand.id[id];
End;
RiscAssemblerAG: Module = Begin
Program: AbstractType[ ];
Program.list: AbstractProduction [ List ];
List: AbstractType[ ];
List.statement: AbstractProduction [ Statement ];
List.dangle: AbstractProduction [ Statement ];
List.cons: AbstractProduction [ Statement, List ];
Statement: AbstractType[ ];
Statement.label: AbstractProduction [ Label, Statement ];
Statement.op: AbstractProduction [ Op ];
Statement.oprand: AbstractProduction [ Op, Rand ];
Label: AbstractType[ ];
Label.id: AbstractProduction [ id ];
Op: AbstractType[ ];
Op.noop: AbstractProduction [ ];
Op.goto: AbstractProduction [ ];
Rand: AbstractType[ ];
Rand.id: AbstractProduction [ id ];
End;
RiscAssemblerDoit: Module = Begin
Program
for Program.list: AbstractProduction [ List ]
let Assemble[tree] ← < codeBody, symbolTable, nextAddress >
where codeBody ← CodeSequence[List, symbolTable]
where < symbolTable, nextAddress > ← SymbolTable[List, initialTable, initialAddress]
where initialAddress ← CodeOrigin[]
where initialTable ← InitialSymbolTable[]
;
List
for List.statement: AbstractProduction [ Statement ]
let SymbolTable[tree, initialTable, initialAddress] ←
SymbolTable[Statement, initialTable, initialAddress]
let CodeSequence[tree, symbolTable] ← CodeSequence[Statement, symbolTable]
;
for List.dangle: AbstractProduction [ Statement ]
let SymbolTable[tree, initialTable, initialAddress] ←
SymbolTable[Statement, initialTable, initialAddress]
let CodeSequence[tree, symbolTable] ← CodeSequence[Statement, symbolTable]
We might want to issue a warning here about the null statement!
;
for List.cons: AbstractProduction [ Statement, List ]
let SymbolTable[tree, initialTable, initialAddress] ←
SymbolTable[List, newTable, nextAddress]
where < newTable, nextAddress> ← SymbolTable[Statement, initialTable, initialAddress]
let CodeSequence[tree, symbolTable] ← CodeConcat[first, rest]
where rest ← CodeSequence[List, symbolTable]
where first ← CodeSequence[Statement, symbolTable]
;
Statement
for Statement.label: AbstractProduction [ Label, Statement ]
let SymbolTable[tree, initialTable, initialAddress] ← SymbolTable[Statement, newTable, nextAddress]
where newTable ← SymbolConcat[initialTable, entry]
where entry ← NotePosition[Label, initialAddress, definedAt]
where nextAddress ← Succ[initialAddress]
where definedAt ← SourcePosition[Label]
where len ← SourceLength[Label]
let CodeSequence[tree, symbolTable] ← CodeSequence[Statement, symbolTable]
;
for Statement.op: AbstractProduction [ Op ]
let SymbolTable[tree, initialTable, initialAddress] ← < newTable, nextAddress >
where newTable ← SymbolCopy[initialTable]
where nextAddress ← Succ[initialAddress]
let CodeSequence[tree, symbolTable] ← InstructionSequence[segment]
where segment ← Instruction[Op]
;
for Statement.oprand: AbstractProduction [ Op, Rand ]
let SymbolTable[tree, initialTable, initialAddress] ← < newTable, nextAddress >
where newTable ← SymbolCopy[initialTable]
where nextAddress ← Succ[initialAddress]
let CodeSequence[tree, symbolTable] ← InstructionSequence[segment]
where segment ← InstructionRand[Op, label]
where label ← Index[Rand, symbolTable]
;
Label
for Label.id: AbstractProduction [ id ]
let NotePosition[tree, address, definedAt] ← NewLabel[id, address, definedAt]
There's a lie here in that the "initialTable" is being augmented with an entry for the new symbol which contains only the text, but that can be fixed later...
;
Op
for Op.noop: AbstractProduction [ ]
let Instruction[tree] ← Code[Opcode.noop]
let InstructionRand[tree, index] ← CodeRandFirewall[Opcode.noop, index]
;
for Op.goto: AbstractProduction [ ]
let Instruction[tree] ← CodeFirewall[Opcode.goto]
let InstructionRand[tree, index] ← CodeRand[Opcode.goto, index]
;
Rand
for Rand.id: AbstractProduction [ id ]
let Index[tree, symbolTable] ← SymbolIndex[symbolTable, id]
;
End;
RiscAssemblerAT: Module = Begin
Program: AbstractType [ Assemble ];
List: AbstractType [ SymbolTable, CodeSequence ];
Statement: AbstractType [ SymbolTable, CodeSequence ];
Label: AbstractType [ NotePosition ];
Op: AbstractType [ Instruction, InstructionRand ];
Rand: AbstractType [ Index ];
End;
RiscAssemblerTree: Module = Begin
Recursive Functions
Assemble:
TreeRecursiveFunction [ Tree ]
Returns [ EncodingSequence.program, Table.all, INT.nextAddress ];
the primary (synthesis) operation of the assembler, produces a code sequence, a symbol table, and the length of the code sequence (represented as start+len=last+1). Note that this is a two pass operations where the symbol table is constructed in pass 1, and the code sequence is produced in pass 2 (where children recieve the symbol table as an inherited value).
SymbolTable:
TreeRecursiveFunction [ Tree, Table.old, INT.first ]
Returns [ Table.new, INT.next ];
the operation which produces values for symbols by synthesizing representations (virtual addresses in INT's) as values for symbolic labels
NotePosition:
TreeRecursiveFunction [ Tree, INT.address, INT.definedAt ]
Returns [ LabelInstance.id ];
a noop which provides us with the ability to recognize positions of GenericTokens(id)
CodeSequence:
TreeRecursiveFunction [ Tree, Table ]
Returns [ EncodingSequence.list ];
the gradual synthesis of the module/program via concatenation of Instruction Sequences.
Instruction:
TreeRecursiveFunction [ Tree ]
Returns [ Encoding.instr ];
the encoding of a primitive operation for the "machine".
InstructionRand:
TreeRecursiveFunction [ Tree, LabelInstance.id ]
Returns [ Encoding.instr ];
the encoding of a primitive operation (with operand) for the "machine".
Index:
TreeRecursiveFunction [ Tree, Table ]
Returns [ LabelInstance.index ];
the virtual program counter for instructions.
End;
RiscAssemblerBase: Module = Begin
Cedar Primitives
INT: CedarType;
ROPE: CedarType From Rope;
LabelInstance: CedarType From RiscAssembler;
Encoding: CedarType From RiscAssembler;
EncodingSequence: CedarType From RiscAssembler;
Table: CedarType From RedBlackTree;
Succ:
CedarFunction [ INT.val ]
Returns [ INT.succ ]
From RiscAssembler;
Base Functions
Opcode: EnumeratedBaseType = { noop, goto };
CodeConcat:
BaseFunction [ EncodingSequence.left, EncodingSequence.right ]
Returns [ EncodingSequence.list ];
InstructionSequence:
BaseFunction [ Encoding.instr ]
Returns [ EncodingSequence.list ];
Code:
BaseFunction [ Opcode.op ]
Returns [ Encoding.instr ];
CodeFirewall:
BaseFunction [ Opcode.op ]
Returns [ Encoding.instr ];
CodeRand:
BaseFunction [ Opcode.op, LabelInstance.index ]
Returns [ Encoding.instr ];
CodeRandFirewall:
BaseFunction [ Opcode.op, LabelInstance.index ]
Returns [ Encoding.instr ];
SymbolCopy:
BaseFunction [ Table.old ]
Returns [ Table.new ]
SharedReps [ Table.old ];
SymbolConcat:
BaseFunction [ Table.old, LabelInstance.entry ]
Returns [ Table.new ]
SharedReps [ Table.old ];
CodeOrigin:
BaseFunction [ ]
Returns [ INT.origin ];
InitialSymbolTable:
BaseFunction [ ]
Returns [ Table.new ];
NewLabel:
BaseFunction [ id, INT.address, INT.definedAt ]
Returns [ LabelInstance.id ];
SymbolIndex:
BaseFunction [ Table, id.label ]
Returns [ LabelInstance.index ];
End.
eof...