"======================================================================
|
|   C indented printer (?)
|
|   $Revision: 1.7.5$
|   $Date: 2000/05/28 16:56:52$
|   $Author: pb$
|
 ======================================================================"


"======================================================================
|
| Copyright 1988-92, 1994-95, 1999, 2000 Free Software Foundation, Inc.
| Written by Steve Byrne.
|
| This file is part of GNU Smalltalk.
|
| GNU Smalltalk is free software; you can redistribute it and/or modify it
| under the terms of the GNU General Public License as published by the Free
| Software Foundation; either version 2, or (at your option) any later version.
| 
| GNU Smalltalk is distributed in the hope that it will be useful, but WITHOUT
| ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
| FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
| details.
| 
| You should have received a copy of the GNU General Public License along with
| GNU Smalltalk; see the file COPYING.  If not, write to the Free Software
| Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  
|
 ======================================================================"


FileStream fileIn: Directory kernel, '/../examples/IndStream.st'!

IndentedStream subclass: #CStream
       instanceVariableNames: ''
       classVariableNames: ''
       poolDictionaries: ''
       category: 'Examples-Cool'
!

CStream comment: '
I emit indented C code.  The model that I have is that most of my 
operations emit things without the newline, leaving the newline and
consequently the indenting policy up to a few routines which make
all the indentation decisions.' !

!CStream methodsFor: 'cool hacks'!

nextPutBlock: aBlock
    aBlock value
!

!CStream methodsFor: 'accessing'!

emitBlock: aBlock
    self
	openBrace;
	nextPutBlock: aBlock;
	closeBrace
!

emitIf: expr then: aBlock
    self
	nextPutAll: 'if (';
	nextPutAll: expr;
	nextPutAll: ') ';
	emitBlock: aBlock.
!

emitElseIf: expr then: aBlock
    self
	nextPutAll: ' else ';
	emitIf: expr then: aBlock
!

emitElse: elseBlock
    self
	nextPutAll: ' else ';
	emitBlock: elseBlock.
!

emitWhile: expr do: aBlock
    self
	nextPutAll: 'while (';
	nextPutAll: expr;
	nextPutAll: ') ';
	emitBlock: aBlock.
!

emitWhile: expr
    self
	nextPutAll: 'while (';
	nextPutAll: expr;
	nextPutAll: '); '.
!

emitDo: aBlock while: expr
    self
	nextPutAll: 'do ';
	emitBlock: aBlock;
	nextPutAll: ' while (';
	nextPutAll: expr;
	nextPutAll: '); '.
!

emitFor: initExpr test: testExpr do: aBlock after: afterExpr
    self
	nextPutAll: 'for (';
	nextPutAll: initExpr;
	nextPutAll: '; ';
	nextPutAll: testExpr;
	nextPutAll: '; ';
	nextPutAll: afterExpr;
	nextPutAll: ') ';
	emitBlock: aBlock.
!

emitFor: initExpr test: testExpr after: afterExpr
    self
	nextPutAll: 'for (';
	nextPutAll: initExpr;
	nextPutAll: '; ';
	nextPutAll: testExpr;
	nextPutAll: '; ';
	nextPutAll: afterExpr;
	nextPutAll: '); '.
!

emitDecl: type var: var
    self nextPutAll: type; tabTo: 20; nextPutAll: var; nextPut: $;.
!

emitStmt: stmt
    self nextPutAll: stmt; nextPut: $; .
!

emitLineComment: text
    self tabTo: 40; emitComment: text.
!

emitComment: text
    self nextPutAll: '/* '; nextPutAll: text; nextPutAll: ' */'.
!

openBrace
    self nextPut: ${; nl.
    self pushLevel.
!

closeBrace
    self popLevel.
    self nextPut: $}; nl.
! !

"
| s |
    s := CStream on: Transcript.
    s emitBlock: 
	[ s emitDecl: 'int' var: 'foo'; nl; nl.
    
	  s emitIf: 'foo > 3' then: 
	      [ s emitStmt: 'foo++'; nl.
		s emitIf: 'foo < 5' then:
		    [ s emitStmt: 'foo <<= 2'; nl.
		      s emitIf: 'foo & 0xff' then: [
			 s emitStmt: 'foo *= 5'; nl.
			 ].
		    ].
		s emitStmt: 'foo = sin(foo)'; 
		 emitLineComment: 'perhaps a bit unrealistic'; nl.
	      ].
	].
!
"
    
