DIRECTORY Atom USING [GetPName, GetProp, MakeAtom, PutProp, PutPropOnList], BasicTime USING [GMT, Now], ProcessProps USING [AddPropList, GetProp], RefTab USING [Create, Fetch, Ref, Store], Rope USING [FromRefText, Replace, ROPE, Size], Scheme, SchemeRegistry USING [], SymTab USING [Create, EachPairAction, Fetch, Pairs, Ref, Store]; SchemeSupportImpl: CEDAR MONITOR IMPORTS Atom, BasicTime, ProcessProps, RefTab, Rope, Scheme, SymTab EXPORTS Scheme, SchemeRegistry ~ BEGIN OPEN Scheme; ROPE: TYPE ~ Rope.ROPE; ICar: PROC [any: Any] RETURNS [Any] ~ INLINE { RETURN [WITH any SELECT FROM pair: Pair => pair.car ENDCASE => Car[any]] }; ICdr: PROC [any: Any] RETURNS [Any] ~ INLINE { RETURN [WITH any SELECT FROM pair: Pair => pair.cdr ENDCASE => Cdr[any]] }; SymbolFromRope: PUBLIC PROC [rope: ROPE] RETURNS [Symbol] ~ {RETURN[Atom.MakeAtom[rope]]}; RopeFromSymbol: PUBLIC PROC [symbol: Symbol] RETURNS [ROPE] ~ {RETURN[Atom.GetPName[symbol]]}; Complain: PUBLIC ERROR [object: Any, msg: ROPE] ~ CODE; GetUserEnvironment: PUBLIC SIGNAL RETURNS [env: Environment] ~ CODE; SpecialsRep: TYPE ~ RECORD [false, true, endOfFile, unspecified, undefined: Any, emptyString: String]; GetSpecials: PROC RETURNS [REF SpecialsRep] ~ { WITH Atom.GetProp[atom: $SchemeSpecialValues, prop: $SchemeSpecialValues] SELECT FROM s: REF SpecialsRep => RETURN [s]; ENDCASE => { s: REF SpecialsRep ~ NEW[SpecialsRep ¬ [ false: NEW[BOOL ¬ FALSE], true: NEW[BOOL ¬ TRUE], endOfFile: NEW[{eof} ¬ eof], unspecified: NEW[{unspecified} ¬ unspecified], undefined: NEW[{undefined} ¬ undefined], emptyString: NEW[StringRep ¬ [base: NIL]] ]]; Atom.PutProp[atom: $SchemeSpecialValues, prop: $SchemeSpecialValues, val: s]; RETURN [s] }; }; specials: REF SpecialsRep ~ GetSpecials[]; false: PUBLIC Any ~ specials.false; true: PUBLIC Any ~ specials.true; endOfFile: PUBLIC Any ~ specials.endOfFile; unspecified: PUBLIC Any ~ specials.unspecified; undefined: PUBLIC Any ~ specials.undefined; emptyString: PUBLIC String ~ specials.emptyString; StringFromRope: PUBLIC PROC [rope: ROPE] RETURNS [String] ~ { RETURN [IF Rope.Size[rope] = 0 THEN emptyString ELSE NEW[StringRep ¬ [base: rope]]] }; RopeFromString: PUBLIC PROC [string: String] RETURNS [ROPE] ~ { IF string.buffer = NIL OR string.buffer.length = 0 THEN NULL ELSE { string.base ¬ Rope.Replace[base: string.base, start: string.where, len: string.buffer.length, with: Rope.FromRefText[string.buffer]]; string.buffer.length ¬ 0; }; RETURN [string.base] }; Car: PUBLIC PROC [any: Any] RETURNS [Any] ~ { WITH any SELECT FROM pair: Pair => RETURN [pair.car]; list: LIST OF REF ANY => RETURN [list.first]; ENDCASE => Complain[any, "not a pair"]; }; Cdr: PUBLIC PROC [any: Any] RETURNS [Any] ~ { WITH any SELECT FROM pair: Pair => RETURN [pair.cdr]; list: LIST OF REF ANY => RETURN [list.rest]; ENDCASE => Complain[any, "not a pair"]; }; Cons: PUBLIC PROC [a, b: Any] RETURNS [Pair] ~ { RETURN [NEW[PairRep ¬ [a, b]]] }; ListLength: PUBLIC PROC [a: Any] RETURNS [n: INT ¬ 0] ~ { DO WITH a SELECT FROM p: Pair => { n ¬ n + 1; a ¬ p.cdr }; lora: LIST OF REF ANY => { n ¬ n + 1; a ¬ lora.rest }; ENDCASE => IF a = NIL THEN EXIT ELSE { Complain[a, "not a proper list"] } ENDLOOP; }; Reverse: PUBLIC PROC [a: Any] RETURNS [Any] ~ { r: Any ¬ NIL; FOR each: Any ¬ a, ICdr[each] UNTIL each = NIL DO r ¬ Cons[ICar[each], r]; ENDLOOP; RETURN [r] }; VectorFromList: PUBLIC PROC [a: Any] RETURNS [Any] ~ { len: NAT ~ ListLength[a]; v: SimpleVector ~ NEW[SimpleVectorRep[len]]; FOR i: NAT IN [0..len) DO v[i] ¬ ICar[a]; a ¬ ICdr[a] ENDLOOP; RETURN [v] }; VectorLength: PUBLIC PROC [a: Any] RETURNS [INT] ~ { WITH a SELECT FROM v: SimpleVector => RETURN [v.length]; v: Vector => RETURN [v.length]; ENDCASE => Complain[a, "not a vector"]; }; VectorRef: PUBLIC PROC [a: Any, i: INT] RETURNS [Any] ~ { WITH a SELECT FROM v: SimpleVector => { IF i IN [0..v.length) THEN RETURN [v[i]] }; v: Vector => { IF i IN [0..v.length) THEN RETURN [v.ref[v, i]] }; ENDCASE => Complain[a, "not a vector"]; Complain[MakeFixnum[i], "index out of bounds"]; }; VectorSet: PUBLIC PROC [a: Any, i: INT, value: Any] ~ { WITH a SELECT FROM v: SimpleVector => { IF i IN [0..v.length) THEN {v[i] ¬ value; RETURN} }; v: Vector => { IF i IN [0..v.length) THEN {v.set[v, i, value]; RETURN} }; ENDCASE => Complain[a, "not a vector"]; Complain[MakeFixnum[i], "index out of bounds"]; }; LookupVariableValue: PUBLIC PROC [variable: Any, env: Environment] RETURNS [Any] ~ { FOR e: Environment ¬ env, e.parent WHILE e # NIL DO IF e.names = NIL THEN { WITH e[0] SELECT FROM tab: RefTab.Ref => { WITH RefTab.Fetch[tab, variable].val SELECT FROM pair: Pair => { IF pair.cdr = undefined THEN Complain[variable, "undefined variable"] ELSE RETURN [pair.cdr]; }; ENDCASE => NULL; }; ENDCASE => ERROR; } ELSE { FOR i: NAT DECREASING IN [0..e.names.length) DO IF variable = e.names[i] THEN RETURN [e[i]]; ENDLOOP; }; ENDLOOP; Complain[variable, "undefined variable"]; }; SetVariableValue: PUBLIC PROC [variable: Any, value: Any, env: Environment] RETURNS [BOOL] ~ { FOR e: Environment ¬ env, e.parent WHILE e # NIL DO IF e.names = NIL THEN { WITH e[0] SELECT FROM tab: RefTab.Ref => { WITH RefTab.Fetch[tab, variable].val SELECT FROM pair: Pair => { pair.cdr ¬ value; RETURN [TRUE] } ENDCASE => NULL; }; ENDCASE => ERROR; } ELSE { FOR i: NAT DECREASING IN [0..e.names.length) DO IF variable = e.names[i] THEN { e[i] ¬ value; RETURN [TRUE] }; ENDLOOP; }; ENDLOOP; RETURN [FALSE]; }; DefineVariable: PUBLIC PROC [variable: Any, value: Any, env: Environment] ~ { WITH env[0] SELECT FROM x: RefTab.Ref => { WITH RefTab.Fetch[x, variable].val SELECT FROM binding: Pair => { binding.cdr ¬ value } ENDCASE => { [] ¬ RefTab.Store[x: x, key: variable, val: Cons[variable, value]] }; }; ENDCASE => Complain[variable, "defines must be at top level"]; }; ExportVariable: PUBLIC PROC [fromEnv, toEnv: Environment, fromName, toName: Symbol] ~ { fromTab, toTab: RefTab.Ref; found: BOOL; binding: Any; IF fromEnv.names # NIL OR toEnv.names # NIL THEN Complain[$exportVariable, "Not Implemented: export to/from a non-top-level environment"]; fromTab ¬ NARROW[fromEnv[0]]; toTab ¬ NARROW[toEnv[0]]; [found, binding] ¬ RefTab.Fetch[fromTab, fromName]; IF NOT found THEN Complain[fromName, "attempt to export an undefined variable"]; [] ¬ RefTab.Store[toTab, toName, binding]; }; DefinePrimitive: PUBLIC PROC [name: ROPE, nArgs: NAT, dotted: BOOL, proc: PROC [Primitive, Any, Any, Any, ProperList] RETURNS [Any], doc: Rope.ROPE, env: Environment, data: REF ¬ NIL, optional: NAT ¬ 0] ~ { symbol: Symbol ~ SymbolFromRope[name]; DefineVariable[variable: symbol, value: NEW[PrimitiveRep ¬ [minArgs: nArgs - optional, maxArgs: nArgs, dotted: dotted, proc: proc, doc: doc, data: data, symbol: symbol]], env: env]; }; Initializer: TYPE ~ RECORD [initProc: PROC [Environment]]; initHead: LIST OF Initializer ~ LIST[[NIL]]; lastInit: LIST OF Initializer ¬ initHead; versionRef: REF ¬ Cons[$VERSION, NEW[BasicTime.GMT ¬ BasicTime.Now[]]]; NewEnvironmentStructure: PUBLIC PROC RETURNS [userEnv: Environment] ~ { NewEnvironment: PROC [parent: Environment, id: Rope.ROPE] RETURNS [env: Environment] ~ { env ¬ NEW[EnvironmentRep[2]]; env.parent ¬ parent; env.names ¬ NIL; env.mark ¬ 100; env.values[0] ¬ RefTab.Create[]; env.values[1] ¬ StringFromRope[id]; }; userEnv ¬ NewEnvironment[NIL, "user"]; DefineVariable[ variable: SymbolFromRope["user"], value: userEnv, env: userEnv]; InitializeEnvironmentStructure[userEnv]; }; InitializeEnvironmentStructure: PUBLIC PROC [userEnv: Environment] ~ { ENABLE GetUserEnvironment => RESUME[userEnv]; IF RefTab.Fetch[x: NARROW[userEnv.values[0]], key: $VERSION].val # versionRef THEN { FOR each: LIST OF Initializer ¬ initHead.rest, each.rest UNTIL each = NIL DO each.first.initProc[userEnv]; ENDLOOP; [] ¬ RefTab.Store[x: NARROW[userEnv.values[0]], key: $VERSION, val: versionRef]; }; }; namedInitializers: SymTab.Ref -- OF LIST OF Initializer -- ~ SymTab.Create[case: FALSE]; CallNamedInitializers: PUBLIC PROC [name: ROPE, env: Environment] RETURNS [nInit: INT ¬ 0] ~ { WITH SymTab.Fetch[x: namedInitializers, key: name].val SELECT FROM initializers: LIST OF Initializer => { FOR tail: LIST OF Initializer ¬ initializers, tail.rest UNTIL tail = NIL DO tail.first.initProc[env]; nInit ¬ nInit + 1; ENDLOOP; }; ENDCASE => NULL; }; InitializationCell: TYPE ~ REF InitializationCellRep; InitializationCellRep: TYPE ~ RECORD [ head: LIST OF Initializer, last: LIST OF Initializer ]; CollectInitializers: PUBLIC PROC [name: ROPE, proc: PROC] ~ { cell: InitializationCell ¬ NEW[InitializationCellRep]; cell.last ¬ cell.head ¬ LIST[[NIL]]; ProcessProps.AddPropList[propList: Atom.PutPropOnList[propList: NIL, prop: $SchemeInitializers, val: cell], inner: proc]; IF cell.head.rest # NIL THEN { [] ¬ SymTab.Store[x: namedInitializers, key: name, val: cell.head.rest]; }; }; RegisterInit: PUBLIC ENTRY PROC [initProc: PROC [Environment]] ~ { WITH ProcessProps.GetProp[$SchemeInitializers] SELECT FROM cell: InitializationCell => { cell.last ¬ cell.last.rest ¬ LIST[[initProc]]; }; ENDCASE => { lastInit ¬ lastInit.rest ¬ LIST[[initProc]]; versionRef ¬ Cons[$VERSION, NEW[BasicTime.GMT ¬ BasicTime.Now[]]]; }; }; InitializerIsDefined: PUBLIC PROC [name: ROPE] RETURNS [BOOL] ~ { RETURN[SymTab.Fetch[namedInitializers, name].found] }; ListNamedInitializers: PUBLIC PROC RETURNS [list: ProperList ¬ NIL] ~ { EachPair: SymTab.EachPairAction = { list ¬ Cons[StringFromRope[key], list]; }; [] ¬ SymTab.Pairs[x: namedInitializers, action: EachPair] }; END. h SchemeSupportImpl.mesa Copyright Σ 1987, 1988, 1989, 1991 by Xerox Corporation. All rights reserved. Formerly part of SchemeEvalImpl.mesa Michael Plass, March 6, 1989 2:52:52 pm PST Last changed by Pavel on March 15, 1989 12:42:54 pm PST r: ReversedArgList => RETURN [r.car]; r: ReversedArgList => RETURN [r.cdr]; Registration Support Call all the initializers associated with a given name. All calls to RegisterInit while proc has control will be collected into a named table of Initializers. Normally proc will cause a Cedar module (or perhaps several) to be loaded and run. If nothing was registered, NOP since the installation probably went awry. Cedar programs call this to make themselves known to Scheme This is under control of CollectInitializers This is free-floating; add to the global list. [key: ROPE, val: SymTab.Val] RETURNS [quit: BOOL _ FALSE] ΚΤ–(cedarcode) style•NewlineDelimiter ™codešœ™Kšœ ΟeœC™NKšœ$™$K™+K™7—K˜šΟk ˜ Kšœžœ7˜AKšœ žœžœ˜Kšœ žœ˜*Kšœžœ˜)Kšœžœžœ˜.Kšœ˜Kšœžœ˜Kšœžœ4˜@—K˜KšΟnœžœž˜ Kšžœ<˜CKšžœ˜šœžœžœ˜K˜šžœžœžœ˜K˜—šŸœžœ žœ žœ˜.Kš žœžœžœžœžœ ˜HK˜K˜—šŸœžœ žœ žœ˜.Kš žœžœžœžœžœ ˜HK˜K˜—Kš Ÿœžœžœžœžœ žœ˜ZKš Ÿœžœžœžœžœžœ˜^K˜Kš Ÿœžœžœžœžœ˜7š Ÿœžœžœžœžœ˜DK˜—Kšœ žœžœL˜f•StartOfExpansion[atom: ATOM, prop: REF ANY]šŸ œžœžœžœ˜/šžœFžœž˜UKšœžœžœ˜!šžœ˜ šœžœžœ˜(Kšœžœžœžœ˜Kšœžœžœžœ˜Kšœ žœ˜Kšœ žœ˜.Kšœ žœ˜(Kšœ žœžœ˜)Kšœ˜—K–/[atom: ATOM, prop: REF ANY, val: REF ANY]šœM˜MKšžœ˜ Kšœ˜——šœ˜K˜——šœ žœ˜*K˜—Kšœžœ˜#Kšœžœ˜!Kšœ žœ˜+Kšœ žœ˜/Kšœ žœ˜+šœ žœ˜2K˜—š Ÿœžœžœžœžœ ˜=Kš žœžœžœ žœžœ˜SKšœ˜K˜—š Ÿœžœžœžœžœ˜?–M[base: ROPE, start: INT _ 0, len: INT _ 2147483647, with: ROPE _ NIL]š žœžœžœžœžœžœ˜CK˜…K˜Kšœ˜—Kšžœ˜Kšœ˜K˜—šŸœžœžœ žœ ˜-šžœžœž˜Kšœžœ ˜ Kšœžœ ™%Kš œžœžœžœžœžœ˜-Kšžœ ˜'—Kšœ˜K˜—šŸœžœžœ žœ ˜-šžœžœž˜Kšœžœ ˜ Kšœžœ ™%Kš œžœžœžœžœžœ ˜,Kšžœ ˜'—Kšœ˜K˜—š Ÿœžœžœ žœ žœžœ˜RK˜—š Ÿ œžœžœ žœžœ ˜9šžœžœžœž˜K˜$Kš œžœžœžœžœ!˜6Kš žœžœžœžœžœžœ%˜IKšžœ˜—Kšœ˜K˜—šŸœžœžœ žœ ˜/Kšœ žœ˜ šžœžœžœž˜1K˜Kšžœ˜—Kšžœ˜ Kšœ˜K˜—šŸœžœžœ žœ ˜6Kšœžœ˜Kšœžœ˜,Kš žœžœžœ žœžœ žœ˜>Kšžœ˜ Kšœ˜K˜—š Ÿ œžœžœ žœžœ˜4šžœžœž˜Kšœžœ ˜%Kšœ žœ ˜Kšžœ ˜'—Kšœ˜K˜—š Ÿ œžœžœ žœžœ ˜9šžœžœž˜Kš œžœžœžœžœ ˜@Kš œžœžœžœžœ˜AKšžœ ˜'—Kšœ/˜/Kšœ˜K˜—šŸ œžœžœ žœ˜7šžœžœž˜Kš œžœžœžœžœ˜IKš œžœžœžœžœ˜IKšžœ ˜'—Kšœ/˜/Kšœ˜K˜—šŸœžœžœ#žœ ˜Tšžœ žœžœž˜3šžœ ž˜šžœ˜šžœžœž˜˜šžœ!žœž˜0šœ˜šžœ˜Kšžœ)˜-Kšž œ ˜—Kšœ˜—Kšžœžœ˜—K˜—Kšžœžœ˜—Kšœ˜—šžœ˜šžœžœž œž˜/Kšžœžœžœ˜,Kšžœ˜—Kšœ˜——Kšžœ˜—K˜)Kšœ˜K˜—š Ÿœžœžœ/žœžœ˜^šžœ žœžœž˜3šžœ ž˜šžœ˜šžœžœž˜˜šžœ!žœž˜0Kšœ"žœžœ˜1Kšžœžœ˜—K˜—Kšžœžœ˜—Kšœ˜—šžœ˜šžœžœž œž˜/Kšžœžœžœžœ˜>Kšžœ˜—Kšœ˜——Kšžœ˜—Kšžœžœ˜K˜K˜—šŸœžœžœ2˜Mšžœžœž˜šœ˜šžœžœž˜.K˜(KšžœK˜R—Kšœ˜—Kšžœ7˜>—K˜K˜—šŸœžœžœ<˜WKšœ˜Kšœžœ˜ K˜ š žœžœžœžœžœ˜1K˜Y—Kšœ žœ ˜Kšœžœ ˜K˜3Kšžœžœžœ?˜PK˜*K˜K˜—šŸœžœžœžœ žœ žœžœ(žœžœžœžœ žœ ˜ΞKšœ&˜&Kšœ(žœŠ˜΅Kšœ˜——head™Kšœ žœžœ žœ˜:Kš œ žœžœžœžœ˜,Kšœ žœžœ˜)šœ žœžœ žœ˜GK˜—šŸœžœžœžœ˜GšŸœžœ žœžœ˜XKšœžœ˜K˜Kšœ žœ˜K˜K˜ K˜#K˜—Kšœžœ ˜&K˜šœ˜Kšœ!˜!Kšœ˜Kšœ˜—K˜Kšœ(˜(Kšœ˜K˜—šŸœžœžœ˜F–$[x: RefTab.Ref, key: RefTab.Key]šž˜Kšœžœ ˜&—šžœžœ5žœ˜Tš žœžœžœ(žœžœž˜LKšœ˜Kšžœ˜—K–7[x: RefTab.Ref, key: RefTab.Key, val: RefTab.Val]šœžœ5˜PKšœ˜—Kšœ˜K˜—–&[mod: NAT _ 17, case: BOOL _ TRUE]šœΟcœžœ˜XK˜—š Ÿœžœžœžœžœ žœ ˜^K–[x: SymTab.Ref, key: ROPE]™7šžœ3žœž˜Bšœžœžœ˜&š žœžœžœ'žœžœž˜KKšœ˜K˜Kšžœ˜—Kšœ˜—Kšžœžœ˜—Kšœ˜K˜—Kšœžœžœ˜5šœžœžœ˜&Kšœžœžœ ž˜Kšœžœžœ ˜Kšœ˜K˜—š Ÿœžœžœžœžœ˜=Kšœ Ÿ œ‘™ΊKšœžœ˜6Kšœžœžœ˜$Kšœ@žœ6˜y–1[x: SymTab.Ref, key: ROPE, val: SymTab.Val]šžœžœžœ˜K™IK˜HKšœ˜—Kšœ˜K˜—šŸ œžœž œ žœ˜BK™;šžœ+žœž˜:šœ˜KšœŸ™,Kšœžœ ˜.Kšœ˜—šžœ˜ K™.Kšœžœ ˜,Kšœžœ žœ˜BKšœ˜——Kšœ˜K˜—š Ÿœžœžœžœžœžœ˜AKšžœ-˜3Kšœ˜K˜—š Ÿœžœžœžœžœ˜G–= -- [key: ROPE, val: SymTab.Val] RETURNS [quit: BOOL _ FALSE]šŸœ˜#KšΠck9™9K˜'K˜—K˜9Kšœ˜K˜——Kšžœ˜K˜—…—%B8~