QuadIOImpl.mesa
Copyright Ó 1987 by Xerox Corporation. All rights reserved.
Don Curry, May 1, 1987 2:20:03 pm PDT
Last Edited by: Louis Monier April 2, 1987 4:47:55 pm PST
DIRECTORY
AMBridge, AMTypes, Interpreter,
Convert, FS, IO, QuadIO, SymTab;
QuadIOImpl: CEDAR PROGRAM
IMPORTS
AMBridge, Interpreter,
Convert, FS, IO, SymTab
EXPORTS QuadIO =
BEGIN
Word: TYPE = LONG CARDINAL;
QuadFileFormat: PUBLIC ERROR = CODE;
ReadFile:  PUBLIC PROC[fileName: IO.ROPE] RETURNS[mem: QuadIO.Memory] = {
quadFile: IO.STREAMFS.StreamOpen[fileName];
count:  INT ← 0;
list:  LIST OF QuadIO.MemWord ← NIL;
mem ← NEW[QuadIO.MemoryRec ← [sym: SymTab.Create[]]];
DO
Skip: PROC [source: IO.STREAM, c: CHAR] ~
{[] ← IO.SkipWhitespace[source]; IF IO.GetChar[source] # c THEN QuadFileFormat};
tokenKind: IO.TokenKind;
token:   IO.ROPE;
add, data: Word;
[tokenKind, token] ← quadFile.GetCedarTokenRope[! IO.EndOfStream => EXIT];
SELECT tokenKind FROM
tokenDECIMAL,
tokenOCTAL,
tokenHEX  => {
add ← Convert.CardFromRope[token];
data ← 0;
Skip[quadFile, '/];
THROUGH [0..4) DO data ← data*100H + quadFile.GetCard[] ENDLOOP;
list ← CONS[[add, data], list];
count ← count+1};
tokenID   => {
Skip[quadFile, '=];
add ← quadFile.GetCard[];
[]←SymTab.Store[mem.sym, token, TVFromRef[NEW[Word ← add]]]};
tokenEOF  => EXIT;
ENDCASE   => QuadFileFormat;
ENDLOOP;
quadFile.Close[];
mem.wds ← NEW[QuadIO.MemWords[count]];
FOR i: INT DECREASING IN [0..count) DO mem.wds[i] ← list.first; list ← list.rest ENDLOOP};
InterpAddr: PUBLIC PROC[addRope: IO.ROPE, mem: QuadIO.Memory] RETURNS[add: Word] = {
result:   AMTypes.TV;
errorRope: IO.ROPE;
noResult:  BOOL;
refCard:  REF;
[result, errorRope, noResult] ← Interpreter.Evaluate[addRope, NIL, LIST[mem.sym]];
IF noResult THEN {add ← 0; SIGNAL Signal[errorRope]; RETURN[add]};
refCard ← RefFromTV[result];
WITH refCard SELECT FROM
word: REF Word    => {RETURN[word^]};
card: REF LONG CARDINAL => {RETURN[card^]};
int: REF INT     => {IF int^<0 THEN ERROR; RETURN[int^]};
ENDCASE       => ERROR};
TVFromRef: PROC [ref: REF] RETURNS [AMTypes.TV] = TRUSTED
{RETURN [AMBridge.TVForReferent[ref]]};
RefFromTV: PROC [tv: REF] RETURNS [REF] = {
IF tv=NIL THEN RETURN [NIL];
IF ~ISTYPE [tv, AMTypes.TV] THEN ERROR;
TRUSTED {RETURN [AMBridge.SomeRefFromTV[tv]]} };
Signal: SIGNAL[msg: IO.ROPE] = CODE;
END.