DIRECTORY Rope USING [ROPE, Fetch, FromChar, Length, Substr, Concat], IO USING [STREAM, NUL, PutF, rope, TokenKind, GetCedarTokenRope], Atom USING [MakeAtom], Convert USING [RopeFromInt, IntFromRope], RussellRuntime USING [RTError, RTValue, RTTuple, MkTuple, SelectFromTuple, QueryTuple, RTCodeBody, PrependValue, PrependProc], RussellInterp; RussellInitEnvImpl: CEDAR PROGRAM IMPORTS Rope, IO, Atom, Convert, RussellRuntime EXPORTS RussellInterp = BEGIN OPEN RussellRuntime ; RussellMkInitEnv: PUBLIC PROCEDURE [in: IO.STREAM, out: IO.STREAM] RETURNS [RTTuple] = BEGIN stdout: REF IO.STREAM; stdin: REF IO.STREAM; initEnv: RTTuple; stdin _ NEW[ IO.STREAM _ in ]; stdout _ NEW[ IO.STREAM _ out ]; initEnv _ MkTuple[name~$stdin, value~stdin]; initEnv _ PrependProc[tuple~initEnv, name~$getString, body~GetStringBody]; initEnv _ PrependValue[tuple~initEnv, name~$stdout, value~stdout]; initEnv _ PrependProc[tuple~initEnv, name~$putString, body~PutStringBody]; initEnv _ PrependValue[tuple~initEnv, name~$character, value~characterCluster]; initEnv _ PrependValue[tuple~initEnv, name~$characterString, value~characterStringCluster]; initEnv _ PrependValue[tuple~initEnv, name~$boolean, value~booleanCluster]; initEnv _ PrependValue[tuple~initEnv, name~$integer, value~integerCluster]; RETURN[ initEnv ] END ; -- RussellMkInitEnv GetStringBody: PRIVATE RTCodeBody = BEGIN token: Rope.ROPE; tokenKind: IO.TokenKind; stdin: IO.STREAM; WITH arg SELECT FROM rs: REF IO.STREAM => stdin _ rs^ ; ENDCASE => ERROR RTError[$badArg]; [token~token, tokenKind~tokenKind] _ IO.GetCedarTokenRope[stream~stdin]; SELECT tokenKind FROM tokenERROR, tokenEOF => RETURN[ NIL ] ; ENDCASE => RETURN[ NEW[ Rope.ROPE _ token ]] END ; -- GetStringBody PutStringBody: PRIVATE RTCodeBody = BEGIN r: Rope.ROPE; stdout: IO.STREAM; WITH SelectFromTuple[arg,$string] SELECT FROM rr: REF Rope.ROPE => r _ rr^ ; ENDCASE => ERROR RTError[$badArg]; WITH SelectFromTuple[arg,$stream] SELECT FROM rs: REF IO.STREAM => stdout _ rs^ ; ENDCASE => ERROR RTError[$badArg]; IO.PutF[stdout, "%g", IO.rope[r]]; RETURN[ NIL ] END ; -- PutStringBody booleanCluster: RTTuple; -- Initialized below. booleanValType: RTValue _ NIL; trueValue: RTValue _ NIL; -- Initialized below to MkTuple[name~$t, value~NIL]; falseValue: RTValue _ NIL; BooleanAndBody: PRIVATE RTCodeBody = BEGIN a: BOOL _ QueryTuple[tuple~SelectFromTuple[arg,$a], name~$t]; b: BOOL _ QueryTuple[tuple~SelectFromTuple[arg,$b], name~$t]; RETURN[ IF a AND b THEN trueValue ELSE falseValue ] END ; -- BooleanAndBody BooleanOrBody: PRIVATE RTCodeBody = BEGIN a: BOOL _ QueryTuple[tuple~SelectFromTuple[arg,$a], name~$t]; b: BOOL _ QueryTuple[tuple~SelectFromTuple[arg,$b], name~$t]; RETURN[ IF a OR b THEN trueValue ELSE falseValue ] END ; -- BooleanOrBody BooleanNotBody: PRIVATE RTCodeBody = BEGIN RETURN[ IF QueryTuple[tuple~arg, name~$t] THEN trueValue ELSE falseValue ] END ; -- BooleanNotBody characterCluster: RTTuple; -- Initialized below. characterValType: RTValue _ NIL; CharacterFromIntBody: PRIVATE RTCodeBody = BEGIN i: INT; WITH arg SELECT FROM ri: REF INT => i _ ri^ ; ENDCASE => ERROR RTError[$badType]; RETURN[ NEW[ CHAR _ (IO.NUL + i) ]]; END ; -- CharacterFromIntBody CharacterToIntBody: PRIVATE RTCodeBody = BEGIN c: CHAR; WITH arg SELECT FROM rc: REF CHAR => c _ rc^ ; ENDCASE => ERROR RTError[$badType]; RETURN[ NEW[ INT _ (c - IO.NUL) ]]; END ; -- CharacterToIntBody CharacterFromStringBody: PRIVATE RTCodeBody = BEGIN r: Rope.ROPE; WITH arg SELECT FROM rr: REF Rope.ROPE => r _ rr^ ; ENDCASE => ERROR RTError[$badType]; IF Rope.Length[r] = 0 THEN ERROR RTError[$nullString]; RETURN[ NEW[ CHAR _ Rope.Fetch[r] ]]; END ; -- CharacterFromStringBody CharacterToStringBody: PRIVATE RTCodeBody = BEGIN c: CHAR; WITH arg SELECT FROM rc: REF CHAR => c _ rc^ ; ENDCASE => ERROR RTError[$badType]; RETURN[ NEW[ Rope.ROPE _ Rope.FromChar[c] ]]; END ; -- CharacterToStringBody characterStringCluster: RTTuple; -- Initialized below. characterStringValType: RTValue _ NIL; emptyCharacterStringValue: RTValue; -- Initialized below. CharacterStringLengthBody: PRIVATE RTCodeBody = BEGIN r: Rope.ROPE; WITH arg SELECT FROM rr: REF Rope.ROPE => r _ rr^ ; ENDCASE => ERROR RTError[$badType]; RETURN[ NEW[ INT _ Rope.Length[r] ] ] END ; -- CharacterStringLengthBody CharacterStringSubstrBody: PRIVATE RTCodeBody = BEGIN string: Rope.ROPE; start: INT; length: INT; WITH SelectFromTuple[arg,$string] SELECT FROM rr: REF Rope.ROPE => string _ rr^ ; ENDCASE => ERROR RTError[$badType]; WITH SelectFromTuple[arg,$start] SELECT FROM ri: REF INT => start _ ri^ ; ENDCASE => ERROR RTError[$badType]; WITH SelectFromTuple[arg,$length] SELECT FROM ri: REF INT => length _ ri^ ; ENDCASE => ERROR RTError[$badType]; RETURN[ NEW[ Rope.ROPE _ Rope.Substr[string, start, length] ] ] END ; -- CharacterStringSubstrBody CharacterStringConcatBody: PRIVATE RTCodeBody = BEGIN a: Rope.ROPE; b: Rope.ROPE; WITH SelectFromTuple[arg,$a] SELECT FROM rr: REF Rope.ROPE => a _ rr^ ; ENDCASE => ERROR RTError[$badType]; WITH SelectFromTuple[arg,$b] SELECT FROM rr: REF Rope.ROPE => b _ rr^ ; ENDCASE => ERROR RTError[$badType]; RETURN[ NEW[ Rope.ROPE _ Rope.Concat[a, b] ] ] END ; -- CharacterStringConcatBody integerCluster: RTTuple; -- Initialized below. integerValType: RTValue _ NIL; lowPredefinedInteger: INT ~ 0; highPredefinedInteger: INT ~ 1024; PredefinedInteger: TYPE = INT [lowPredefinedInteger..highPredefinedInteger]; predefinedIntegerValue: ARRAY PredefinedInteger OF RTValue; MkPredefinedIntegerValues: PRIVATE PROCEDURE [] = BEGIN i: INT; FOR i _ lowPredefinedInteger, i+1 WHILE i <= highPredefinedInteger DO predefinedIntegerValue[i] _ NEW[ INT _ i ] ENDLOOP END ; -- MkPredefinedIntegerValues MkIntegerValue: PRIVATE PROCEDURE [n: INT] RETURNS [RTValue] = INLINE BEGIN RETURN [ IF (n >= lowPredefinedInteger) AND (n <= highPredefinedInteger) THEN predefinedIntegerValue[n] ELSE NEW[ INT _ n ] ] END ; -- MkIntegerValue IntegerAddBody: PRIVATE RTCodeBody = BEGIN a, b: INT; WITH SelectFromTuple[arg,$a] SELECT FROM ri: REF INT => a _ ri^ ; ENDCASE => ERROR RTError[$badType]; WITH SelectFromTuple[arg,$b] SELECT FROM ri: REF INT => b _ ri^ ; ENDCASE => ERROR RTError[$badType]; RETURN[ MkIntegerValue[a+b] ] END ; -- IntegerAddBody IntegerSubtractBody: PRIVATE RTCodeBody = BEGIN a, b: INT; WITH SelectFromTuple[arg,$a] SELECT FROM ri: REF INT => a _ ri^ ; ENDCASE => ERROR RTError[$badType]; WITH SelectFromTuple[arg,$b] SELECT FROM ri: REF INT => b _ ri^ ; ENDCASE => ERROR RTError[$badType]; RETURN[ MkIntegerValue[a-b] ] END ; -- IntegerSubtractBody IntegerMultiplyBody: PRIVATE RTCodeBody = BEGIN a, b: INT; WITH SelectFromTuple[arg,$a] SELECT FROM ri: REF INT => a _ ri^ ; ENDCASE => ERROR RTError[$badType]; WITH SelectFromTuple[arg,$b] SELECT FROM ri: REF INT => b _ ri^ ; ENDCASE => ERROR RTError[$badType]; RETURN[ MkIntegerValue[a*b] ] END ; -- IntegerMultiplyBody IntegerDivideBody: PRIVATE RTCodeBody = BEGIN a, b: INT; WITH SelectFromTuple[arg,$a] SELECT FROM ri: REF INT => a _ ri^ ; ENDCASE => ERROR RTError[$badType]; WITH SelectFromTuple[arg,$b] SELECT FROM ri: REF INT => b _ ri^ ; ENDCASE => ERROR RTError[$badType]; RETURN[ MkIntegerValue[a/b] ] END ; -- IntegerDivideBody IntegerLessBody: PRIVATE RTCodeBody = BEGIN a, b: INT; WITH SelectFromTuple[arg,$a] SELECT FROM ri: REF INT => a _ ri^ ; ENDCASE => ERROR RTError[$badType]; WITH SelectFromTuple[arg,$b] SELECT FROM ri: REF INT => b _ ri^ ; ENDCASE => ERROR RTError[$badType]; RETURN[ IF a < b THEN trueValue ELSE falseValue ] END ; -- IntegerLessBody IntegerLeqBody: PRIVATE RTCodeBody = BEGIN a, b: INT; WITH SelectFromTuple[arg,$a] SELECT FROM ri: REF INT => a _ ri^ ; ENDCASE => ERROR RTError[$badType]; WITH SelectFromTuple[arg,$b] SELECT FROM ri: REF INT => b _ ri^ ; ENDCASE => ERROR RTError[$badType]; RETURN[ IF a <= b THEN trueValue ELSE falseValue ] END ; -- IntegerLeqBody IntegerEqBody: PRIVATE RTCodeBody = BEGIN a, b: INT; WITH SelectFromTuple[arg,$a] SELECT FROM ri: REF INT => a _ ri^ ; ENDCASE => ERROR RTError[$badType]; WITH SelectFromTuple[arg,$b] SELECT FROM ri: REF INT => b _ ri^ ; ENDCASE => ERROR RTError[$badType]; RETURN[ IF a = b THEN trueValue ELSE falseValue ] END ; -- IntegerEqBody IntegerNeqBody: PRIVATE RTCodeBody = BEGIN a, b: INT; WITH SelectFromTuple[arg,$a] SELECT FROM ri: REF INT => a _ ri^ ; ENDCASE => ERROR RTError[$badType]; WITH SelectFromTuple[arg,$b] SELECT FROM ri: REF INT => b _ ri^ ; ENDCASE => ERROR RTError[$badType]; RETURN[ IF a # b THEN trueValue ELSE falseValue ] END ; -- IntegerNeqBody IntegerGeqBody: PRIVATE RTCodeBody = BEGIN a, b: INT; WITH SelectFromTuple[arg,$a] SELECT FROM ri: REF INT => a _ ri^ ; ENDCASE => ERROR RTError[$badType]; WITH SelectFromTuple[arg,$b] SELECT FROM ri: REF INT => b _ ri^ ; ENDCASE => ERROR RTError[$badType]; RETURN[ IF a >= b THEN trueValue ELSE falseValue ] END ; -- IntegerGeqBody IntegerGreaterBody: PRIVATE RTCodeBody = BEGIN a, b: INT; WITH SelectFromTuple[arg,$a] SELECT FROM ri: REF INT => a _ ri^ ; ENDCASE => ERROR RTError[$badType]; WITH SelectFromTuple[arg,$b] SELECT FROM ri: REF INT => b _ ri^ ; ENDCASE => ERROR RTError[$badType]; RETURN[ IF a > b THEN trueValue ELSE falseValue ] END ; -- IntegerGreaterBody IntegerToStringBody: PRIVATE RTCodeBody = BEGIN n: INT; WITH arg SELECT FROM ri: REF INT => n _ ri^ ; ENDCASE => ERROR RTError[$badType]; RETURN[ NEW[ Rope.ROPE _ Convert.RopeFromInt[n] ]]; END ; -- IntegerToStringBody IntegerFromStringBody: PRIVATE RTCodeBody = BEGIN r: Rope.ROPE; WITH arg SELECT FROM rr: REF Rope.ROPE => r _ rr^ ; ENDCASE => ERROR RTError[$badType]; RETURN[ MkIntegerValue[ Convert.IntFromRope[r] ] ]; END ; -- IntegerFromStringBody trueValue _ MkTuple[name~$t, value~NIL]; falseValue _ NIL; booleanCluster _ MkTuple[name~$val, value~booleanValType]; booleanCluster _ PrependValue[tuple~booleanCluster, name~$false, value~falseValue]; booleanCluster _ PrependValue[tuple~booleanCluster, name~$true, value~trueValue]; booleanCluster _ PrependProc[tuple~booleanCluster, name~$not, body~BooleanNotBody]; booleanCluster _ PrependProc[tuple~booleanCluster, name~$and, body~BooleanAndBody]; booleanCluster _ PrependProc[tuple~booleanCluster, name~$or, body~BooleanOrBody]; characterCluster _ MkTuple[name~$val, value~characterValType]; characterCluster _ PrependProc[tuple~characterCluster, name~$fromInt, body~CharacterFromIntBody]; characterCluster _ PrependProc[tuple~characterCluster, name~$toInt, body~CharacterToIntBody]; characterCluster _ PrependProc[tuple~characterCluster, name~$fromString, body~CharacterFromStringBody]; characterCluster _ PrependProc[tuple~characterCluster, name~$toString, body~CharacterToStringBody]; characterStringCluster _ MkTuple[name~$val, value~characterStringValType]; emptyCharacterStringValue _ NIL; characterStringCluster _ PrependValue[tuple~characterStringCluster, name~$empty, value~emptyCharacterStringValue]; characterStringCluster _ PrependProc[tuple~characterStringCluster, name~$length, body~CharacterStringLengthBody]; characterStringCluster _ PrependProc[tuple~characterStringCluster, name~$substr, body~CharacterStringSubstrBody]; characterStringCluster _ PrependProc[tuple~characterStringCluster, name~$concat, body~CharacterStringConcatBody]; MkPredefinedIntegerValues[]; integerCluster _ MkTuple[name~$val, value~integerValType]; integerCluster _ PrependProc[tuple~integerCluster, name~Atom.MakeAtom["*"], body~IntegerMultiplyBody]; integerCluster _ PrependProc[tuple~integerCluster, name~Atom.MakeAtom["/"], body~IntegerDivideBody]; integerCluster _ PrependProc[tuple~integerCluster, name~$toString, body~IntegerToStringBody]; integerCluster _ PrependProc[tuple~integerCluster, name~$fromString, body~IntegerFromStringBody]; integerCluster _ PrependProc[tuple~integerCluster, name~$less, body~IntegerLessBody]; integerCluster _ PrependProc[tuple~integerCluster, name~$leq, body~IntegerLeqBody]; integerCluster _ PrependProc[tuple~integerCluster, name~$eq, body~IntegerEqBody]; integerCluster _ PrependProc[tuple~integerCluster, name~$neq, body~IntegerNeqBody]; integerCluster _ PrependProc[tuple~integerCluster, name~$geq, body~IntegerGeqBody]; integerCluster _ PrependProc[tuple~integerCluster, name~$greater, body~IntegerGreaterBody]; integerCluster _ PrependProc[tuple~integerCluster, name~Atom.MakeAtom["-"], body~IntegerSubtractBody]; integerCluster _ PrependProc[tuple~integerCluster, name~Atom.MakeAtom["+"], body~IntegerAddBody]; END . ²RussellInitEnvImpl.mesa Russell84 interpreter initial environment construction. In this module are predefined types. These are not an essential part of the language, but they provide such nice features as integer arithmetic and I/O. Last Edited by: Demers, March 13, 1984 9:08:27 pm PST Creating an initial environment The following procedure builds an initial environment with standard input and output streams as supplied. Everything bound in an environment is immutable, but may be a location. The locations bound in initial environments created by separate calls to RussellMkInitEnv are guaranteed not to alias (except possibly for the standard input and output streams themselves). Note most types are constructed once, at module initialization, and are shared in all initial environments. The standard input stream. The representation is a Cedar IO.STREAM. The only operation is reading a string. [ env: RTTuple, arg: RTValue, ip: REF ANY ] RETURNS[RTValue] Russell type: func[ inputStream -> characterString.val ] The standard output stream. The representation is a Cedar IO.STREAM. The only operation is printing a string. [ env: RTTuple, arg: RTValue, ip: REF ANY ] RETURNS[RTValue] Russell type: func[ [string:characterString.val, stream:outputStream] -> [] ] The boolean cluster The representation is {t:[]}, with the usual Boolean operations provided in the cluster. [ env: RTTuple, arg: RTValue, ip: REF ANY ] RETURNS[RTValue] Russell type: func[ [a:val,b:val] -> val ] [ env: RTTuple, arg: RTValue, ip: REF ANY ] RETURNS[RTValue] Russell type: func[ [a:val,b:val] -> val ] [ env: RTTuple, arg: RTValue, ip: REF ANY ] RETURNS[RTValue] Russell type: func[ val -> val ] The character cluster The representation is Cedar CHAR. The only operations are conversions to integer and characterString. [ env: RTTuple, arg: RTValue, ip: REF ANY ] RETURNS[RTValue] Russell type: func[ integer.val -> val ] [ env: RTTuple, arg: RTValue, ip: REF ANY ] RETURNS[RTValue] Russell type: func[ val -> integer.val ] [ env: RTTuple, arg: RTValue, ip: REF ANY ] RETURNS[RTValue] Russell type: func[ characterString.val -> val ] [ env: RTTuple, arg: RTValue, ip: REF ANY ] RETURNS[RTValue] Russell type: func[ val -> characterString.val ] The characterString cluster The representation is Cedar Rope.ROPE. [ env: RTTuple, arg: RTValue, ip: REF ANY ] RETURNS[RTValue] Russell type: func[ characterString.val -> integer.val ] [ env: RTTuple, arg: RTValue, ip: REF ANY ] RETURNS[RTValue] Russell type: func[ [string:characterString.val, start:integer.val, length:integer.val] -> characterString.val ] [ env: RTTuple, arg: RTValue, ip: REF ANY ] RETURNS[RTValue] Russell type: func[ [a:characterString.val, b:characterString.val] -> characterString.val ] The integer cluster The representation is Cedar INT, with the usual operations provided in the cluster. [ env: RTTuple, arg: RTValue, ip: REF ANY ] RETURNS[RTValue] Russell type: func[ [a:val,b:val] -> val ] [ env: RTTuple, arg: RTValue, ip: REF ANY ] RETURNS[RTValue] Russell type: func[ [a:val,b:val] -> val ] [ env: RTTuple, arg: RTValue, ip: REF ANY ] RETURNS[RTValue] Russell type: func[ [a:val,b:val] -> val ] [ env: RTTuple, arg: RTValue, ip: REF ANY ] RETURNS[RTValue] Russell type: func[ [a:val,b:val] -> val ] [ env: RTTuple, arg: RTValue, ip: REF ANY ] RETURNS[RTValue] Russell type: func[ [a:val,b:val] -> boolean.val ] [ env: RTTuple, arg: RTValue, ip: REF ANY ] RETURNS[RTValue] Russell type: func[ [a:val,b:val] -> boolean.val ] [ env: RTTuple, arg: RTValue, ip: REF ANY ] RETURNS[RTValue] Russell type: func[ [a:val,b:val] -> boolean.val ] [ env: RTTuple, arg: RTValue, ip: REF ANY ] RETURNS[RTValue] Russell type: func[ [a:val,b:val] -> boolean.val ] [ env: RTTuple, arg: RTValue, ip: REF ANY ] RETURNS[RTValue] Russell type: func[ [a:val,b:val] -> boolean.val ] [ env: RTTuple, arg: RTValue, ip: REF ANY ] RETURNS[RTValue] Russell type: func[ [a:val,b:val] -> boolean.val ] [ env: RTTuple, arg: RTValue, ip: REF ANY ] RETURNS[RTValue] Russell type: func[ val -> characterString.val ] [ env: RTTuple, arg: RTValue, ip: REF ANY ] RETURNS[RTValue] Russell type: func[ characterString.val -> val ] Create Boolean cluster. Create character cluster. Create characterString cluster. Create integer cluster. Ê%– "Cedar" style˜head1™IbodyšœÒ™ÒL™5unitšÏk ˜ Icodešœœœ+˜;Nšœœœœ,˜ANšœœ ˜Nšœœ˜)Nšœœj˜~Nšœ˜—šÏnœ ˜!Nšœ(˜/Nšœ˜šœ˜š˜Nšœ˜N˜—™LšœÞ™Þšžœœœœœœœ ˜Tšœ˜Nšœœ˜Nšœœ˜N˜Mšœœœœ˜Nšœ œœœ ˜ Nšœ,˜,NšœJ˜JNšœB˜BNšœJ˜JNšœO˜ONšœ[˜[NšœK˜KNšœK˜KNšœ ˜NšœÏc˜———™Lšœœœ*™Qšž œœ ˜!Nšœ"œœœ ™˜>Nšœa˜aNšœ]˜]Nšœg˜gNšœc˜c—™MšœJ˜JNšœœ˜ Nšœr˜rNšœq˜qNšœq˜qNšœq˜q—™N˜Mšœ:˜:Nšœf˜fNšœd˜dNšœ]˜]Nšœa˜aNšœU˜UNšœS˜SNšœQ˜QNšœS˜SNšœS˜SNšœ[˜[Nšœf˜fNšœa˜a—Mšœ˜————…—0€TW