C2CEmit.mesa
Copyright Ó 1987, 1988, 1989, 1990, 1991 by Xerox Corporation. All rights reserved.
Christian Jacobi, March 23, 1988 5:12:29 pm PST
Christian Jacobi, January 29, 1993 11:11 am PST
C2C's code emitting primitives
DIRECTORY
C2CCodePlaces USING [CodePlace],
C2CDefs,
IntCodeDefs,
IO USING [STREAM],
Rope;
C2CEmit: CEDAR DEFINITIONS =
BEGIN
ROPE: TYPE = Rope.ROPE;
Precedence: TYPE = C2CDefs.Precedence;
Code: TYPE = C2CDefs.Code;
breakChar: CHAR = '@;
--clients must not take advantage of knowledge which character is used
nest: READONLY ROPE;
unNest: READONLY ROPE;
nestNLine: READONLY ROPE;
unNestNLine: READONLY ROPE;
line: READONLY ROPE;
optionalLine: READONLY ROPE;
twoLines: READONLY ROPE;
noIndent: READONLY ROPE;
CodeOrRope: TYPE = REF;
--Rope operations
Internalize: PROC [r: ROPE] RETURNS [ROPE];
--given an external defined rope [maybe containing formatting information]
--returns internalized rope which does not fool the formatting
--Fine point:
For most procedures, ropes must not contain the formatting sequences used internally by C2CEmitImpl. This is no problem since these sequences are defined with the breakChar, which does not occur in C except as literal or comment. In those cases clients must use CComment or ExternalRopeCode to internalize the ropes.
CComment: PROC [r: ROPE] RETURNS [Code];
--given an rope returns a legal comment in C
--[removes characters prematurely terminating a comment]
--Code properties
Parentize: PROC [c: CodeOrRope] RETURNS [Code];
--put paranthesis around code
--may or may not remove nested parenthesis
ParentizeAndLn: PROC [c: CodeOrRope] RETURNS [Code];
--put paranthesis around code and some line breaks
--may or may not remove nested parenthesis
NonEmpty: PROC [c: Code] RETURNS [BOOL];
--test whether code is empty or NIL
--non destructive
NonWhiteSpace: PROC [c: Code] RETURNS [BOOL];
--test whether code is empty, NIL, or contains only whitespace
--non destructive
SetWhiteSpace: PROC [c: Code] RETURNS [sameButModifiedInPlace: Code];
--declares code to be white space only
SetArithClass: PROC [c: Code, class: IntCodeDefs.ArithClass] RETURNS [sameCode: Code];
GetArithClass: PROC [c: Code] RETURNS [class: IntCodeDefs.ArithClass];
--ArithClass used to describ the type of the actual C code; (not intendet type)
--Note: The generated C code will have the right bits, but it might not have
--the type as requested in the IntCode.
--Exception: kind=signed means type is unsigned, but gives position of sign bit.
SetPrecedence: PROC [c: Code, precedence: Precedence ¬ parenPrecedence] RETURNS [sameCode: Code];
SetAddressable: PROC [c: Code, addressable: BOOL ¬ TRUE] RETURNS [sameCode: Code];
SetIsAddress: PROC [c: Code, isAddress: BOOL ¬ TRUE] RETURNS [sameCode: Code];
--usage restricted to access of arrays as a whole
GetPrecedence: PROC [c: Code] RETURNS [precedence: Precedence];
GetAddressable: PROC [c: Code] RETURNS [addressable: BOOL];
GetIsAddress: PROC [c: Code] RETURNS [isAddress: BOOL];
--isAdress means "code is the adress of what you actually wanted"
--[~isAdress does not mean that code wouldn't be an adress]
--non destructive
SetDead: PROC [c: Code, dead: BOOL ¬ TRUE];
GetIsDead: PROC [c: Code] RETURNS [BOOL];
--dead code: the following code won't be executed, unless it starts with a label
--deadness is a hint: deadness can get lost, but must never be claimed wrongly
--concatenating code inherits deadness from last nonempty piece
--Delayed Code handling
Deref: PROC [c: Code, pointeeBits: INT] RETURNS [Code];
--makes a de-referrencing, delayed
--pointeeBits: cast any pointer type to the required pointer type pointing to pointeeBits
--like * (pointerType) (code)
--Sets precedence to unary !
--destructive
IsDelayedDeref: PROC [c: Code] RETURNS [BOOL];
--if true TakeAddr will not cause a "&" to appear!
TakeAddr: PROC [c: Code, preventCastingToWord: BOOL ¬ FALSE] RETURNS [Code];
--returns something like &c
--preventCastingToWord: code stays of type address
PreventCastingToWord: PROC [c: Code] RETURNS [Code];
--should code be of type address it will stay...
CastWord: PROC [c: CodeOrRope] RETURNS [Code];
-- puts (word) in front
-- destructive on c! if Code
-- handles precedence
-- assumes precedence high enough if ROPE
-- Client must not know whether cast is allways made or sometimes optimized away
CastRef: PROC [c: Code, pointeeBits: INT] RETURNS [Code];
-- like (pointerType) (code)
-- may be destructive on c
-- handles precedence
-- Client must not know whether cast is allways made or sometimes optimized away
SetWord: PROC [c: Code] RETURNS [Code];
-- declares c to be of type word
-- may be destructive on c
SetRef: PROC [c: Code, pointeeBits: INT] RETURNS [Code];
-- declares c to be of type ref to pointeeBits
-- may be destructive on c
--Code operations
CodeToRope: PROC [c: CodeOrRope] RETURNS [r: ROPE];
--returns rope representing Code;
--returned rope inclusive delayed state but, c is not modified
--non destructive
CodeToRopeD: PROC [c: CodeOrRope] RETURNS [r: ROPE];
--returns rope representing Code;
--returned rope inclusive delayed state
--c is destroyed and returned
RopeCode: PROC [r: ROPE ¬ NIL] RETURNS [c: Code];
--returns new code representing rope; Precedence notExpressionPrecedence
RefTextCode: PROC [r: REF TEXT ¬ NIL] RETURNS [c: Code];
--returns new code representing rope; Precedence notExpressionPrecedence
IdentCode: PROC [r: ROPE ¬ NIL] RETURNS [c: Code];
--returns new code representing rope; Precedence identPrecedence; addressable
MinPrecedence: PROC [c: Code, minimum: Precedence¬assignPrecedence] RETURNS [modifiedC: Code];
--Guarantees minimum precedence by adding parantheses
--reuses and modifies c^
BinOp: PROC [c1: Code, op: ROPE, c2: Code, precedence: Precedence ¬ commaPrecedence] RETURNS [Code];
--might or might not reuses and modifies either c^!
CopyC: PROC [c: Code] RETURNS [Code];
--makes a real, new copy of code; c^ not changed
--non destructive
Cat: PROC [c1, c2, c3, c4, c5: CodeOrRope ¬ NIL] RETURNS [Code];
--concatenates code pieces
--each code piece a rope, ref text or code for conveniance
--might or might not reuses and modifies either code pieces if is of type code
CatCall: PROC [function: ROPE, c1, c2, c3, c4, c5: CodeOrRope ¬ NIL] RETURNS [Code];
--Catenates function name, codes in parantheses and makes primary precedence
--might or might not reuses and modifies either c^!
CatRemark: PROC [c: Code, r: ROPE] RETURNS [Code];
--appends a remark to code
--might or might not reuses and modifies c^!
--adds only comment to code; does not change addressability precedence ...
CatDebugInfo: PROC [c: Code, r: ROPE, key: REF ¬ NIL] RETURNS [Code];
--Optionally appends debugging information to code (if not empty) for the purpose
--of debugging C2C. (depending on compiler switches)
--Might or might not reuses and modifies c^!
--Collection of Code
AppendCode: PROC [place: C2CCodePlaces.CodePlace, code: CodeOrRope];
--appends code to stated purpose
--code may or may not be cleared
CollectCode: PROC [place: C2CCodePlaces.CodePlace, final: BOOL ¬ FALSE] RETURNS [c: Code];
--returns the code generated for that place and empties the place
ProcessAndOutputCode: PROC [stream: IO.STREAM, lineStream: IO.STREAM, c: Code, lineChar: CHAR ¬ '\n, allowUnIndent: BOOL ¬ TRUE];
--removes formatting instructions of code
--and produces final rope
--may be destructive
END.