<<--File: ExprReadImpl.mesa>> <> DIRECTORY ExprRead, FS, IO, Rope, SymTab; ExprReadImpl: CEDAR PROGRAM IMPORTS FS, IO, Rope, SymTab EXPORTS ExprRead = BEGIN OPEN ExprRead; ReadFile: PUBLIC PROC [fileName: Rope.ROPE] RETURNS [tab: SymTab.Ref _ SymTab.Create[]] ~ { <> ENABLE { IO.EndOfStream => GOTO done; IO.Error => GOTO done; }; stream: FS.STREAM _ FS.StreamOpen[fileName, $read]; tokenKind: IO.TokenKind; key, value, gets, semi: Rope.ROPE; [tokenKind, key, ] _ IO.GetCedarTokenRope[stream]; WHILE tokenKind # tokenERROR DO --AND tokenKind # tokenEOF DO [tokenKind, gets, ] _ IO.GetCedarTokenRope[stream]; IF tokenKind # tokenSINGLE AND ~Rope.Equal[gets, "_"] THEN Error[Rope.Cat["Expecting _, got: ", gets]]; -- [tokenKind, value, ] _ IO.GetCedarTokenRope[stream]; value _ IO.GetRopeLiteral[stream]; IF tokenKind = tokenERROR OR tokenKind = tokenEOF THEN Error["Unexpected end of file"]; [] _ SymTab.Store[tab, key, value]; [tokenKind, semi, ] _ IO.GetCedarTokenRope[stream]; IF ~tokenKind # tokenSINGLE AND Rope.Equal[gets, ";"] THEN Error[Rope.Cat["Expecting ;, got: ", semi]]; [tokenKind, key, ] _ IO.GetCedarTokenRope[stream]; <<-- IF tokenKind = tokenSINGLE AND Rope.Equal[key, "."] THEN tokenKind _ tokenEOF;>> ENDLOOP; EXITS done => NULL; }; FetchRope: PUBLIC PROC [tab: SymTab.Ref, key: Rope.ROPE, missingOK: BOOLEAN] RETURNS [found: BOOLEAN, val: Rope.ROPE] ~ { <> ref: REF; [found, ref] _ SymTab.Fetch[tab, key]; IF ~missingOK AND ~found THEN Error[Rope.Cat["No value for token: ", key, "on fetch"]]; IF found THEN val _ NARROW[ref]; }; FetchBool: PUBLIC PROC [tab: SymTab.Ref, key: Rope.ROPE, missingOK: BOOLEAN] RETURNS [found: BOOLEAN, val: BOOLEAN] ~ { <> ref: REF; [found, ref] _ SymTab.Fetch[tab, key]; IF ~missingOK AND ~found THEN Error[Rope.Cat["No value for token: ", key, "on fetch"]]; IF found THEN { ropeValue: Rope.ROPE; ropeValue _ NARROW[ref]; IF Rope.Equal[ropeValue, "TRUE"] THEN val _ TRUE ELSE IF Rope.Equal[ropeValue, "FALSE"] THEN val _ FALSE ELSE Error[Rope.Cat["Invalid value for: ", key, "was", ropeValue]]; }; }; Error: PUBLIC ERROR [msg: Rope.ROPE _ NIL] = CODE; END.