-- JunoToCedarImpl.mesa
-- Last Edited by: Gnelson, December 10, 1983 7:05 pm

DIRECTORY JunoToCedar, AMBridge, AMTypes, BBApply, BBContext, RTBasic, WorldVM;

JunoToCedarImpl: PROGRAM
IMPORTS AMBridge, AMTypes, BBApply, BBContext, WorldVM
EXPORTS JunoToCedar =
BEGIN OPEN JunoToCedar;
TypedVariable: TYPE = RTBasic.TypedVariable;
Type: TYPE = RTBasic.Type;
GetProc: PUBLIC PROC [pi: ProcIdentifier] RETURNS [success: BOOL, proc: Proc] =
TRUSTED BEGIN
w: BBContext.Context ← BBContext.ContextForWorld[WorldVM.LocalWorld[]];
p: TypedVariable;
[, p] ← BBContext.GlobalFrameSearch[context: w, frameName: pi.moduleName, itemName: pi.procName];
IF p = NIL THEN RETURN [FALSE, NIL];
IF AMTypes.TypeClass[AMTypes.UnderType[AMTypes.TVType[p]]] # procedure THEN RETURN [FALSE, NIL];
TRUSTED {proc ← AMBridge.TVToProc[p]};
success ← TRUE;
END;
Apply: PUBLIC PROC[p: Proc, args: ParameterList] RETURNS [success: BOOL, results: ParameterList] =
TRUSTED BEGIN
pAsTV: TypedVariable ← AMBridge.TVForProc[p];
argsType: Type ← AMTypes.Domain[AMTypes.TVType[pAsTV]];
resultsType: Type;
argsAsTV: TypedVariable ← AMTypes.New[argsType];
resultsAsTV: TypedVariable;
SELECT AMTypes.TypeClass[argsType] FROM
nil => NULL;
record, structure => BEGIN
FOR i: INT IN [1 .. AMTypes.NComponents[argsType]] DO
arg: TypedVariable ← AMTypes.IndexToTV[argsAsTV, i];
actual: TypedVariable;
mismatch: BOOLEANFALSE;
IF args = NIL THEN RETURN [FALSE, NIL];
{foo: REF =
SELECT TRUE FROM
args.first = NIL
OR ISTYPE[args.first, LIST OF REF]
OR ISTYPE[args.first, ROPE]
OR ISTYPE[args.first, ATOM]
OR ISTYPE[args.first, REF TEXT]
=> NEW[REF ← args.first],
TRUE => args.first
ENDCASE => ERROR;
actual ← AMBridge.TVForReferent[foo]};
AMTypes.Assign[arg, actual !AMTypes.Error => {mismatch ← TRUE; -- this is because Cedar won't let us simply RETURN here-- CONTINUE}];
IF mismatch THEN RETURN [FALSE, NIL];
args ← args.rest;
ENDLOOP;
IF args # NIL THEN RETURN [FALSE, NIL];
END;
ENDCASE => ERROR;
resultsAsTV ← BBApply.ApplyProcToRecord[proc: pAsTV, args: argsAsTV];
resultsType ← AMTypes.TVType[resultsAsTV];
results ← NIL;
SELECT AMTypes.TypeClass[resultsType] FROM
nil => NULL;
record, structure => BEGIN
FOR i: INT DECREASING IN [1 .. AMTypes.NComponents[resultsType]] DO
result: TypedVariable ← AMTypes.IndexToTV[resultsAsTV, i];
temp: REF ← AMBridge.RefFromTV[AMTypes.Copy[result]];
IF ISTYPE[temp, REF LIST OF REF]
OR ISTYPE[temp, REF ROPE]
OR ISTYPE[temp, REF ATOM]
OR ISTYPE[temp, REF REF TEXT]
THEN temp ← NARROW[temp, REF REF]^;
results ← CONS[temp, results];
ENDLOOP;
END;
ENDCASE => ERROR;
success ← TRUE;
END;
Test: PROC[n: INT, m: INT] RETURNS [INT] = {RETURN [n + m]};
END.