<<>> <> <> <> <> <<>> <> <<>> 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:>> <> <<>> 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.