page@swan.ulowell.edu (Bob Page) (03/08/89)
Submitted-by: monty@brahms.Berkeley.EDU (Joe Montgomery) Posting-number: Volume 89, Issue 28 Archive-name: languages/zc.1 This is zc, a modified version of hcc (the Sozobon-C compiler by Johann Ruegg) from Fred Fish disk 171. I have made some minor modifications to get it to work with A68K and Blink. Also included is zcc, a unix-style front end for zc/a68k/blink. # This is a shell archive. # Remove everything above and including the cut line. # Then run the rest of the file through sh. #----cut here-----cut here-----cut here-----cut here----# #!/bin/sh # shar: Shell Archiver # Run the following text with /bin/sh to create: # bstok.h # cookie.h # flags.h # gen.h # nodes.h # ops.h # param.h # sttok.h # tok.h # tytok.h # zc.doc # zcc.doc # zc.readme # zcc.readme # makefile # zcc.c # This archive created: Tue Mar 7 21:51:16 1989 cat << \SHAR_EOF > bstok.h /* Copyright (c) 1988 by Sozobon, Limited. Author: Johann Ruegg * * Permission is granted to anyone to use this software for any purpose * on any computer system, and to redistribute it freely, with the * following restrictions: * 1) No charge may be made other than reasonable charges for reproduction. * 2) Modified versions must be clearly marked as such. * 3) The authors are not responsible for any harmful consequences * of using this software, even if they result from defects in it. * * bstok.h * * basic token values * (some compilers cant do enums, so use defines) */ #ifndef ENUMS #define BADTOK 0 #define ID 1 #define ICON 2 #define FCON 3 #define SCON 4 #define DPARAM 6 /* parameter to #define */ #define EOFTOK 7 #define POSTINC 8 /* DOUBLE '+' is pre-inc */ #define POSTDEC 9 /* DOUBLE '-' is pre-dec */ #define TCONV 10 /* coertion */ #define TSIZEOF 11 /* sizeof(type expr) */ #define NL 12 #define WS 13 /* white space */ #define SCON2 14 /* <string> */ #define PTRDIFF 0x18 #define PTRADD 0x19 #define PTRSUB 0x1a #define ARROW 0x1b #define LTEQ 0x1c #define GTEQ 0x1d #define NOTEQ 0x1e #else enum { BADTOK, ID, ICON, FCON, SCON, DPARAM, EOFTOK, POSTINC, POSTDEC, TCONV, TSIZEOF, NL, WS, SCON2, PTRDIFF, PTRADD, PTRSUB, ARROW, LTEQ, GTEQ, NOTEQ }; #endif #define ASSIGN 0x100+ /* add to char of op */ #define DOUBLE 0x80+ #define UNARY 0x200+ #define STAR (UNARY '*') /* used a lot */ #define isassign(x) (x >= 0x100) SHAR_EOF cat << \SHAR_EOF > cookie.h /* Copyright (c) 1988 by Sozobon, Limited. Author: Johann Ruegg * * Permission is granted to anyone to use this software for any purpose * on any computer system, and to redistribute it freely, with the * following restrictions: * 1) No charge may be made other than reasonable charges for reproduction. * 2) Modified versions must be clearly marked as such. * 3) The authors are not responsible for any harmful consequences * of using this software, even if they result from defects in it. * * cookie.h */ /* restrictions on type */ #define R_INTEGRAL 1 #define R_FLOATING 2 #define R_POINTER 4 #define R_STRUCT 8 #define R_ARITH (R_INTEGRAL|R_FLOATING) #define R_SCALAR (R_ARITH|R_POINTER) #define R_ASSN (R_SCALAR|R_STRUCT) /* cookies */ #define FORSIDE 1 #define FORPUSH 2 #define FORCC 3 #define FORIMA 4 #define FORADR 5 #define FORINIT 6 #define IND0 7 #define RETSTRU 8 /* eval flags derived from cookie */ #define NOVAL_OK 1 /* value is optional */ #define CC_OK 2 /* just setting cond. codes okay */ #define IMMA_OK 4 /* immediate OREG is okay */ SHAR_EOF cat << \SHAR_EOF > flags.h /* Copyright (c) 1988 by Sozobon, Limited. Author: Johann Ruegg * * Permission is granted to anyone to use this software for any purpose * on any computer system, and to redistribute it freely, with the * following restrictions: * 1) No charge may be made other than reasonable charges for reproduction. * 2) Modified versions must be clearly marked as such. * 3) The authors are not responsible for any harmful consequences * of using this software, even if they result from defects in it. * * flags.h * * token or e_flags flags */ #define CAN_U 2 /* can be unary op */ #define CAN_AS 4 /* can be op-assign */ #define SPECIAL 8 /* special token beginner ("'/*) */ #define SEE_U 0x10 /* for ICON */ #define SEE_L 0x20 /* for ICON */ #define C_NOT_A 0x40 /* commutative but not associative */ #define C_AND_A 0x80 /* commutative and associative */ #define IMMEDID 0x100 /* Ptr to XXX ID which is really Array of XXX or Fun ret XXX */ #define CHILDNM 0x200 /* my name is my (left) child's name */ #define SIDE_CC 0x400 /* cc set as side effect of op. */ #define RCHILDNM 0x800 /* my name is my (right) child's name */ SHAR_EOF cat << \SHAR_EOF > gen.h /* Copyright (c) 1988 by Sozobon, Limited. Author: Johann Ruegg * * Permission is granted to anyone to use this software for any purpose * on any computer system, and to redistribute it freely, with the * following restrictions: * 1) No charge may be made other than reasonable charges for reproduction. * 2) Modified versions must be clearly marked as such. * 3) The authors are not responsible for any harmful consequences * of using this software, even if they result from defects in it. * * gen.h */ #include "cookie.h" /* parameters for case */ #define C_SIMPLE 8 /* use simple if n <= this */ #define C_RATIO 3 /* use table if max-min/n <= this */ /* branch types */ /* designed so that pairs (i,i+1) with odd i represent opposites */ #define B_EQ 1 #define B_NE 2 #define B_LT 3 #define B_GE 4 #define B_LE 5 #define B_GT 6 #define B_YES 7 #define B_NO 8 #define B_ULT 9 #define B_UGE 10 #define B_ULE 11 #define B_UGT 12 /* derived nodes */ /* re-use stmt keywords for now */ #ifndef ENUMS #define ONAME 'a' #define OREG 'b' #define REGVAR 'c' #define PUSHER 'd' #define CMPBR 'e' #define FIELDAS 'f' #else enum { ONAME = 'a', OREG, REGVAR, PUSHER, CMPBR, FIELDAS }; #endif #define BR_TOK 'i' /* evaluation order values */ #define EV_NONE 0 #define EV_LEFT 1 #define EV_RIGHT 2 #define EV_LR 3 #define EV_RL 4 #define EV_LRSEP 5 /* left then right, but seperate */ SHAR_EOF cat << \SHAR_EOF > nodes.h /* Copyright (c) 1988 by Sozobon, Limited. Author: Johann Ruegg * * Permission is granted to anyone to use this software for any purpose * on any computer system, and to redistribute it freely, with the * following restrictions: * 1) No charge may be made other than reasonable charges for reproduction. * 2) Modified versions must be clearly marked as such. * 3) The authors are not responsible for any harmful consequences * of using this software, even if they result from defects in it. * * nodes.h */ /* * stuff common to all nodes */ #define COMMON int cflags; \ int fill; \ union node *left; \ union node *right; \ union node *tptr; \ union node *nm_ext; \ char cname[NMSIZE] #define n_flags e.cflags #define n_left e.left #define n_next e.left #define n_right e.right #define n_tptr e.tptr #define n_nmx e.nm_ext #define n_name e.cname /* * expression (and symbol table) node */ struct enode { COMMON; int token; /* must be same place as tnode */ int eflags; char etype; /* type of node */ char sc; char eprec; char rno; union { long vival; long voffs; double vfval; } vu; char fldw, fldof; /* use if cant do fields */ /* unsigned fldw:6, fldof:6; /* use fields just so we know fields work */ }; #define e_token e.token #define e_flags e.eflags #define e_prec e.eprec #define e_rno e.rno #define e_type e.etype #define e_ival e.vu.vival #define e_offs e.vu.voffs #define e_fval e.vu.vfval #define e_sc e.sc #define e_fldw e.fldw #define e_fldo e.fldof /* for e_flags values, see tok.h */ /* values for e_type */ #define E_LEAF 0 /* no descendants */ #define E_UNARY 1 /* left node is expr, no right node */ #define E_BIN 2 /* left and right are expr */ #define E_SPEC 3 /* special '(', '[', '.', '->', ... */ /* * code generation node */ struct gnode { COMMON; int token; int eflags; char etype; char sc; /* all of above fields must match first fields in enode! */ char needs; /* registers needed */ char grno; /* register used in ret value */ char basety; /* type FLOAT, UNS, INT or AGREG */ char basesz; /* size 1,2,4 or 3 -> see bsize */ char gr1, gr2; char *betwc; /* code for between L and R */ long goffs; /* offsets for OREG, ONAME */ union gu { long bsize; /* AGREG size or misc. */ struct { /* int gfldw:6, gfldo:6; /* field info */ char gfldw, gfldo; /* use if no fields */ } gfl; } gu; }; #define g_token g.token #define g_flags g.eflags #define g_type g.etype #define g_sc g.sc #define g_needs g.needs #define g_rno g.grno #define g_offs g.goffs #define g_betw g.betwc #define g_ty g.basety #define g_sz g.basesz #define g_code g.tptr #define g_bsize g.gu.bsize #define g_fldw g.gu.gfl.gfldw #define g_fldo g.gu.gfl.gfldo #define g_r1 g.gr1 #define g_r2 g.gr2 /* types of operands -- ordered in cast strength order */ #define ET_S 1 /* signed integer */ #define ET_U 2 /* unsigned integer */ #define ET_F 3 /* float or double */ #define ET_A 4 /* aggregate */ /* * type list node */ struct tnode { COMMON; int token; /* must be same place as enode */ int tflags; char aln; /* alignment needed */ long tsize; }; #define t_token t.token #define t_flags t.tflags #define t_size t.tsize #define t_aln t.aln /* * name extension node */ struct nmext { COMMON; char nmx[NMXSIZE-NMSIZE]; /* name extension (with name)*/ }; #define x_nm x.nmx /* * block info node */ struct bnode { COMMON; union node *syms; union node *tags; int regs; /* reg alloc mask */ long lsize; /* size of locals */ int tmsize; /* max tmps used for 1 expr */ }; #define b_syms b.syms #define b_tags b.tags #define b_regs b.regs #define b_size b.lsize #define b_tsize b.tmsize /* * node to hold case for switch generation */ struct cnode { COMMON; int c_value; /* value for case */ int c_label; /* case label or label label */ int c_def; /* label defined */ }; #define c_defined c.c_def #define c_casev c.c_value #define c_casel c.c_label union node { struct enode e; struct tnode t; struct nmext x; struct bnode b; struct cnode c; struct gnode g; }; typedef union node NODE; typedef NODE *NODEP; /* defines for n_flags */ #define N_BRKPR 1 /* break printnode recursion */ #define N_COPYT 2 /* tptr is a copy */ #define N_ISFREE 4 /* node is on free list (error check) */ NODEP allocnode(); SHAR_EOF cat << \SHAR_EOF > ops.h /* Copyright (c) 1988 by Sozobon, Limited. Author: Johann Ruegg * * Permission is granted to anyone to use this software for any purpose * on any computer system, and to redistribute it freely, with the * following restrictions: * 1) No charge may be made other than reasonable charges for reproduction. * 2) Modified versions must be clearly marked as such. * 3) The authors are not responsible for any harmful consequences * of using this software, even if they result from defects in it. * * ops.h * * defines of allowed operands * 'E' means Dreg or OREG or ONAME or (if on left) ICON * 'Q' means ICON which is 1 to 8 * ONE means ICON which is 1 */ #define DOPD 1 #define AOPD 2 #define MOPD 4 #define IOPD 8 #define DOPA 0x10 #define AOPA 0x20 #define MOPA 0x40 #define IOPA 0x80 #define DOPM 0x100 #define AOPM 0x200 #define MOPM 0x400 #define IOPM 0x800 #define QOPD 0x1000 #define ONEOPM 0x2000 #define ASSOC 0x4000 #define EOPD (DOPD|MOPD|IOPD) #define DOPE (DOPD|DOPM) #define IOPE (IOPD|IOPM) #define EOPA (DOPA|MOPA|IOPA) SHAR_EOF cat << \SHAR_EOF > param.h /* Copyright (c) 1988 by Sozobon, Limited. Author: Johann Ruegg * * Permission is granted to anyone to use this software for any purpose * on any computer system, and to redistribute it freely, with the * following restrictions: * 1) No charge may be made other than reasonable charges for reproduction. * 2) Modified versions must be clearly marked as such. * 3) The authors are not responsible for any harmful consequences * of using this software, even if they result from defects in it. * * param.h * * basic parameters */ #ifndef MMCC #define MMCC 0 #endif #ifndef CC68 #define CC68 0 #endif #ifndef dLibs #define dLibs 0 #endif #undef NULL #define NULL 0L #define ENUMS 1 /* define if host compiler can do enums */ #define DEBUG 1 #define NHASH 32 #define ROPEN "r" #define WOPEN "w" #define FLTFORM "%.3g" #define MAXSTR 256 #define MAXINCL 10 #define NMSIZE 12 /* must be at least 12 */ #define NMXSIZE 32 /* sizes of basic types */ #ifndef NOLONGS #define SIZE_C 1 /* char */ #define SIZE_I 2 /* int */ #define SIZE_S 2 /* short */ #define SIZE_L 4 /* long */ #define SIZE_U 2 /* unsigned */ #define SIZE_F 4 /* float */ #define SIZE_D 4 /* double */ #define SIZE_P 4 /* pointer */ #define MAXINT 0x7fffL #define MININT -0x8000 #define MAXUNS 0xffffL #else #define SIZE_C 1 /* char */ #define SIZE_I 4 /* int */ #define SIZE_S 2 /* short */ #define SIZE_L 4 /* long */ #define SIZE_U 4 /* unsigned */ #define SIZE_F 4 /* float */ #define SIZE_D 4 /* double */ #define SIZE_P 4 /* pointer */ #define MAXINT 0x7fffffff #endif /* alignment requirements */ #define ALN_C 0 /* char */ #define ALN_I 1 /* int */ #define ALN_S 1 /* short */ #define ALN_L 1 /* long */ #define ALN_U 1 /* unsigned */ #define ALN_F 1 /* float */ #define ALN_D 1 /* double */ #define ALN_P 1 /* pointer */ #define STACKALN 1 /* usage for registers */ #define DRV_START 3 #define DRV_END 7 #define AREG 8 #define ARV_START AREG+3 #define ARV_END AREG+5 /* definition of stack frame */ #define ARG_BASE 8 #define LOC_BASE 0 /* need for own buffers (ALCYON hack ) ? */ #define NEEDBUF 0 SHAR_EOF cat << \SHAR_EOF > sttok.h /* Copyright (c) 1988 by Sozobon, Limited. Author: Johann Ruegg * * Permission is granted to anyone to use this software for any purpose * on any computer system, and to redistribute it freely, with the * following restrictions: * 1) No charge may be made other than reasonable charges for reproduction. * 2) Modified versions must be clearly marked as such. * 3) The authors are not responsible for any harmful consequences * of using this software, even if they result from defects in it. * * sttok.h * * statement keyword tokens */ #ifndef ENUMS #define K_GOTO 'a' #define K_RETURN 'b' #define K_BREAK 'c' #define K_CONTINUE 'd' #define K_IF 'e' #define K_ELSE 'f' #define K_FOR 'g' #define K_DO 'h' #define K_WHILE 'i' #define K_SWITCH 'j' #define K_CASE 'k' #define K_DEFAULT 'l' #define K_ASM 'm' #define K_SIZEOF 'n' #else enum { K_GOTO = 'a', K_RETURN, K_BREAK, K_CONTINUE, K_IF, K_ELSE, K_FOR, K_DO, K_WHILE, K_SWITCH, K_CASE, K_DEFAULT, K_ASM, K_SIZEOF, }; #endif SHAR_EOF cat << \SHAR_EOF > tok.h /* Copyright (c) 1988 by Sozobon, Limited. Author: Johann Ruegg * * Permission is granted to anyone to use this software for any purpose * on any computer system, and to redistribute it freely, with the * following restrictions: * 1) No charge may be made other than reasonable charges for reproduction. * 2) Modified versions must be clearly marked as such. * 3) The authors are not responsible for any harmful consequences * of using this software, even if they result from defects in it. * * tok.h * * establish token values */ struct tok { char *name; int tnum; long ival; double fval; char prec; int flags; }; #include "flags.h" #include "bstok.h" #define is_sclass(x) (x >= K_EXTERN && x <= K_STATIC) #define is_tadj(x) (x >= K_LONG && x <= K_UNSIGNED) #define is_btype(x) (x >= K_INT && x <= K_VOID) #define is_tykw(x) (x >= K_EXTERN && x <= K_STRUCT) #define is_stkw(x) (x >= K_GOTO && x <= K_ASM) #define is_brast(x) (x >= K_GOTO && x <= K_CONTINUE) #define is_blkst(x) (x >= K_IF && x <= K_SWITCH) #define is_lblst(x) (x >= K_CASE && x <= K_DEFAULT) #include "tytok.h" #include "sttok.h" /* modifier seen flags */ #define SAW_SHORT 1 #define SAW_LONG 2 #define SAW_UNS 4 SHAR_EOF cat << \SHAR_EOF > tytok.h /* Copyright (c) 1988 by Sozobon, Limited. Author: Johann Ruegg * * Permission is granted to anyone to use this software for any purpose * on any computer system, and to redistribute it freely, with the * following restrictions: * 1) No charge may be made other than reasonable charges for reproduction. * 2) Modified versions must be clearly marked as such. * 3) The authors are not responsible for any harmful consequences * of using this software, even if they result from defects in it. * * tytok.h * * keyword token values */ #ifndef ENUMS #define K_EXTERN 'A' #define K_AUTO 'B' #define K_REGISTER 'C' #define K_TYPEDEF 'D' #define K_STATIC 'E' #define ENUM_SC K_STATIC+1 /* storage class for enum item */ #define HERE_SC K_STATIC+2 /* storage class for glb def */ #define FIRST_SC K_EXTERN #define LAST_SC K_STATIC #define T_UCHAR 'F' #define T_ULONG 'G' #define K_LONG 'H' #define K_SHORT 'I' #define K_UNSIGNED 'J' #define K_INT 'K' #define K_CHAR 'L' #define K_FLOAT 'M' #define K_DOUBLE 'N' #define K_VOID 'O' #define FIRST_BAS T_UCHAR #define LAST_BAS K_VOID #define K_UNION 'P' #define K_ENUM 'Q' #define K_STRUCT 'R' #else #define FIRST_SC K_EXTERN #define LAST_SC K_STATIC #define FIRST_BAS T_UCHAR #define LAST_BAS K_VOID enum { K_EXTERN = 'A', K_AUTO, K_REGISTER, K_TYPEDEF, K_STATIC, ENUM_SC, HERE_SC, T_UCHAR, T_ULONG, K_LONG, K_SHORT, K_UNSIGNED, K_INT, K_CHAR, K_FLOAT, K_DOUBLE, K_VOID, K_UNION, K_ENUM, K_STRUCT }; #endif SHAR_EOF cat << \SHAR_EOF > zc.doc ZC(1) ZC NAME zc -Sozobon C compiler ported to the amiga. Ver 1.01 by Johann Ruegg. modified by Joe Montgomery Dec 1988. SYNOPSIS zc [ options ] [file.c's ] DESCRIPTION Zc is a c compiler for the amiga. It is as far as I know a K & R compatible compiler. Zc takes <file>.c and creates a Motorola compatible assembly source whose default name is <file>.s . include files are looked for in the directory specified by the manx environment variable INCLUDE. Simply use the command set INCLUDE=includedir from the CLI or place it in your startup-sequence. Below: are the options available at present. -Dxxxx Define xxxx same as a #define xxxx in the source file -Uxxxx Undefine xxxx same as a #undefine xxxx in the source file -Ixxxx Include Directory = xxxx -P profiler. Places a call to mcount before calling main. You had better not use this for now. -Oxxxx outputfile name = xxxx -V display compiler version -? Help -C force Data,Bss into Chip memory -F force Data,Bss into Fast memory -Exxxx errorfile. Zc writes the number of errors into this file. This is used by the compiler front end in order to determine whether to start the assembler a68k. BUGS See zc.readme. Joe Montgomery UC Berkeley Math Dept. monty@brahms.berkeley.edu SHAR_EOF cat << \SHAR_EOF > zcc.doc ZCC(1) ZCC NAME zcc A unix style front end for the Sozobon C compiler(by Johann Ruegg) ported to the Amiga. Ver 1.01 A68K a Motorola Compatible 68000 Assembler for the Amiga. Blink a Software Distillery Linker Ver 6.5 for the Amiga. SYNOPSIS zcc [ options ] [file.c's ] [files.s] [files.o] DESCRIPTION Zcc is a unix style c front end for the Amiga. It will compile all .c files creating .s files, assemble all .s files creating .o files and link all .o files creating an executable with the same name as the first file minus the extension. Zcc will call zc to compile all .c files. If an error occurs then zcc will abort and will not call the assembler A68K or the linker Blink. If a successful compile is done then a68k is called and afterwards the .s file is deleted. If all the files have been compiled and/or assembled then Blink is called. Zcc will call a68k to assemble all .s files. The source will not be deleted upon completion. Zcc looks to see if the following environment variables have been set and if so then uses them otherwise default directories will be used. Env Var Default Description CCEXEC c: directory containing zc,a68k,blink CCTEMP ram: location for temporay .s file only used for .c files which will be assembled. INCLUDE directory to find the include files CCLIB lib: directory containing BothStartup.obj amiga.lib and any other libraries that will be used OPTIONS -Dxxxx define xxxx -Uxxxx undefine xxxx -C data->chip -F data->fast -S don't use startups -T don't use amiga.lib -A don't assemble -c don't link -Ixxxx include dir -V printout actions only -lxxxx use library CCLIBxxxx.lib SEEALSO zc.doc BUGS See zc.readme. Joe Montgomery UC Berkeley Math Dept. monty@brahms.berkeley.edu SHAR_EOF cat << \SHAR_EOF > zc.readme zc c - compiler revised by Joe Montgomery dec 1988. (monty@brahms.berkeley.edu) This is a modified version of hcc the Sozobon-C compiler by Johann Ruegg. The documentation released with the compiler states the following: * Permission is granted to anyone to use this software for any purpose * on any computer system, and to redistribute it freely, with the * following restrictions: * 1) No charge may be made other than reasonable charges for reproduction. * 2) Modified versions must be clearly marked as such. * 3) The authors are not responsible for any harmful consequences * of using this software, even if they result from defects in it. I can only add that I can not be held responsible for any harmful consequences as well. I hope that this goes a long way toward the goal of having a freely distributable c compiler for the amiga. I have modified hcc so that it generates code compatible with a68k. I have not been able to test this adequately as I do not have the amiga.lib. However I will get it hopefully within a few weeks and then begin to do some more checking. It does seem to to generate assembly language files that a68k does not complain about. There are some problems however: One I don't know Motorola 68000 assem or the directives. A68k did not have much documentation so I guessed about the use of some. I used XREF for externally defined labels XDEF for global defines, and DC,DS for data storage. I hope my usage is correct. Further a68k requires the SECTIONS DATA and BSS to be named so I used DATA & BSS for those names. This may be a problem or not. I do know that hcc doesn't generate a XREF or public direc for functions or variables which are external to the file. It expects the assembler to figure this out. a68k does not like this. I tried to remedy both these problems to some extent. The code has 0 comments and as I do not have a printer, I found it difficult to make any major changes, so I caused the compiler to generate a XREF label for every function call. Not good, hopefully I can get that working latter. For the variables, I was able to get it to generate XREF's for externally defined global variables, however external variables within a function are not declared to be XREF. I tried to label most of the changes I made with the comment /* JMM ... The following files were modified: Revised main.c to use Amiga File System Naming Conventions Added ?,C,F,E switches. ? help C force data,bss into Chip memory F force data,bss into Fast memory Exxxx use xxxx as errorfile. writes the number of errors to the file Oxxxx use xxxx as the output file instead of the default file. Revised out.c to use MOTOROLA assembly directives in order to be compatible with C.Gibbs a68k assembler & blink Added END statement Changed .comm label,size to label DC.x 0 .even to CNOP 2,0 .globl to XDEF .text to CODE CODE [CHIP | FAST] .data to DATA DATA [CHIP | FAST] .bss to BSS BSS Revised d2.c so that externs are declared as XREF ----- Revised g2.c & gen.c to declare all called functions XREF (will need to change this to declare only external functions) I also wrote a front end called zcc that automatically calls a68k if no errors and then blink. It is somewhat a unix style front end but I don't know all the options available. for zcc and zc, if you type zcc ? or zc ? it will list the various options.(one exception is that zc doesn't list -E as an option.) Again, I hope to correct the above problems as well as adding more options. One not of caution, zc expects all options to be upper case. I did not change this as it uses all the lower case options for debug purposes. Perhaps in the future I will change this. Please let me know of any problems, and I will attempt to fix them. Thanks, for all the great PD and FD software out there. Hope you can get some use out of this. Thanks again, Joe SHAR_EOF cat << \SHAR_EOF > zcc.readme To create zcc simply compile and link zcc.c. Note zcc.c is freely distributable. Joe Montgomery monty@brahms.berkeley.edu SHAR_EOF cat << \SHAR_EOF > makefile OBJS = d2.o decl.o expr.o fix.o fun.o g2.o gen.o gsub.o gunk.o \ main.o md.o nodes.o out.o p2.o pre.o tok.o subs.o H = bstok.h cookie.h flags.h gen.h nodes.h ops.h param.h \ sttok.h tok.h tytok.h RM = delete CFLAGS = -c CC = cc AFLAGS = -o LD = ln LDFLAGS = LIBS = -lm32 -lc32 .c.o: $(CC) $(CFLAGS) $*.c Zc : $(OBJS) $(LD) $(LDFLAGS) -o $@ $(OBJS) $(LIBS) $(OBJS) : $(H) clean: $(RM) *.o clobber: $(RM) *.o SHAR_EOF cat << \SHAR_EOF > zcc.c /* preprocessor for zc (formerly hcc) , a68k assembler, blink */ #include <stdio.h> #define toupper( x ) ( x > 'Z' ? x - ('a'-'A'): x ) char *malloc(); extern char *getenv(); /* flags if 1 then will allow that operation * to be performed on a file */ short dozc,doa68k,doblink,dodebug,debug; short blinkxref,startup,standardblinklib; doexec( x,errmsg,file ) char x[],*errmsg,*file; { if( debug ){ printf("%s\n",x); return(1); } if( ! Execute(x,0L,0L) ){ printf(errmsg,file); quit(); } return(1); } char libdir[32]; /* librarys' dir */ char cmddir[32]; /* zc,a68k,blink 's dir */ char xrefname[128]; /* blink xref file output */ char blinklibs[128]; /* blink lib direc */ char blinkname[128]; /* output file from a68k */ char a68kname[128]; /* output file from zc */ char zcopts[128]; /* zc options for each phase */ char a68kopts[128]; /* a68k options */ char zctemp[128]; /* CCTEMP dir */ char blinkopts[128]; /* blink options */ char buf[256]; /* command line */ char buf2[256]; /* scratch buf */ /* memory allocation/deallocation routines */ struct mem { struct mem *prev; long len; char *memory; } *curmem; char *jmalloc(n) long n; { char *buf; struct mem *memlist; buf=(char *)malloc( n+(long )sizeof(struct mem)); if(!buf){ printf("cc: outofmemory\n"); quit(); } memlist=(struct mem *)buf; memlist->len=n; memlist->memory=buf+sizeof(struct mem); memlist->prev=curmem; curmem=memlist; return(memlist->memory); } quit() { jfree(); exit(0); } jfree(){ struct mem *nxmem; while(curmem != NULL){ nxmem=curmem->prev; free(curmem); /* frees all the memory we so graciously gobbled up */ curmem=nxmem; } }/*end of jfree */ /********************************************************* Handles file list compiles,assembles,links **********************************************************/ /* lists of source file names, as well as type of operation */ struct filenm{ struct filenm *next; struct filenm *prev; short ab; /* abnormal file name */ short zc; /* 1 if .c file */ short a68k; /* 1 if .s file */ char *name; }*files,*curfile; #define copystring( x ) (char *)strcpy( jmalloc( (long )len((char *) x )), x ) /* adds a file to the file list * computes whether an compile and/or assembly will be done * also determines whether this is an abnormal file name. * If so then only a link will be done on the file */ struct filenm *addfile(name) char name[]; { long l; struct filenm *newfile; char *filename; newfile = (struct filenm *)jmalloc(sizeof(struct filenm)); newfile->prev = curfile; newfile->next = NULL; /* last file so far */ if(curfile) curfile->next = newfile; else files = newfile; curfile = newfile; filename = (char *) copystring( (char *)name); curfile->name=filename; /* contains the new filename */ l=len(filename); curfile->ab=0; /* assume it is normal until proven otherwise */ curfile->zc=0; curfile->a68k=0; if(filename[l-2] == '.'){ if(filename[l-1]== 'c'){ curfile->zc = 1; curfile->a68k=1; }else if (filename[l-1] == 'a' || filename[l-1] == 's'){ curfile->a68k=1; }else if(filename[l-1] != 'o') curfile->ab = 1; /* abnormal file name */ }else curfile->ab = 1; /* abnormal file name */ }/* end of addfile */ long len(x) char x[]; { long i; for(i=0; x[i] != 0 ; i++); return(i); } char *tofiletype(nm,buffer,ext1,ext2) char nm[],buffer[],ext1[],ext2; { long l; strcpy(buffer,nm); l=len(buffer); if(l < 2 || ( buffer[l-2] != '.') ){ strcat(buffer,ext1); return(buffer); } if(ext2) buffer[l-1] = ext2; else buffer[l-2] = '\0'; /* must be executable */ return(buffer); }/*end of tofiletype */ #define toassem( x ) tofiletype( x ,a68kname,".s ",'s') #define tolink( x ) tofiletype( x ,blinkname,".o ",'o') #define toexec( x ) tofiletype( x ,blinkname,".lnk ",'\0') doerrors() { FILE *err; int nmerrors; if( (err=fopen("ram:zc.errors","r"))==NULL) return(); nmerrors=0; fscanf(err,"%d",&nmerrors); close(err); if(nmerrors) quit(); return(); /* no errors thank goodness */ } /* this assembles the file */ assemfile(nm,outnm) char nm[],outnm[]; { strcpy(buf,cmddir); strcat(buf,"a68k <* >* "); strcat(buf,a68kopts); strcat(buf,"-o"); strcat(buf,outnm); strcat(buf," "); strcat(buf,nm); Chk_Abort(); doexec(buf,"cc: assemble error: %s\n",nm); }/*end of assemfile*/ /* compiles and/or assembles the files in the file list */ compilefiles(){ struct filenm *file; char nm[]; file=files; while(file){ toassem(file->name);/* use this as the input to a68k * unless updated below */ if(file->zc && dozc ){ strcpy(buf,cmddir); strcat(buf,"zc >* <* -Eram:zc.errors "); strcat(buf,zcopts); strcat(buf," "); if( (file->a68k && doa68k) || file->ab){ strcat(buf," -O"); if(file->a68k && doa68k) strcpy(buf2,zctemp); /* use temp file if doing an assemble */ else buf2[0]='\0'; strcat(buf2,file->name); strcat(buf,toassem(buf2));/* use designated outputfile */ } strcat(buf," "); strcat(buf,file->name); Chk_Abort(); doexec(buf,"cc: compile error: %s\n",file->name);/* start compiler */ doerrors(); /* read error file to see if any errors */ } /* compiled okay */ if(file->a68k && doa68k){ assemfile(a68kname,tolink(file->name)); /* assemble file */ if(file->zc){ /* if was a c file remove .s file */ strcpy(buf,"c:delete >* <* "); strcat(buf,a68kname); Chk_Abort(); doexec(buf,"cc: delete error: %s\n",a68kname); } } file=file->next;/* get next file */ }/* done with this file, compile & assemble next */ }/* done with files */ linkfiles(){ struct filenm *file; char nm[]; if(!doblink || files == NULL ) return();/* don't do anything if not supposed to */ file=files; strcpy(buf,cmddir); strcat(buf,"blink <* >* "); if(startup){ strcat(buf,libdir); strcat(buf,"BothStartup.obj "); } while(file){ strcat(buf,tolink(file->name));/* build linker list */ file = file->next; strcat(buf," "); } strcat(buf," TO "); strcat(buf,toexec(files->name));/* use first file name */ strcat(buf," LIB "); strcat(buf,blinklibs); if(standardblinklib){ strcat(buf,libdir); strcat(buf,"amiga.lib "); } if(!dodebug) strcat(buf," NODEBUG "); if(blinkxref){ strcat(buf," XREF "); strcat(buf,xrefname); } Chk_Abort(); doexec(buf,"cc: linker error:\n",NULL); printf("cc: executable is %s \n",toexec(files->name)); }/* done linking it */ help() { printf("cc: Version 1.0 Preprocessor for \n%s%s%s%s%s%s%s%s%s%s%s%s%s", " cc: Sozobon-C compiler, \n", " as: a68k C.Gibbs Motorola Compatible Assembler, and\n", " blink: Software Distillery Linker \n", " looks for lib:amiga.lib and lib:BothStartup.obj \n", " Syntax:\n", " cc [OPTIONS] <files.c> <files.s> <files.o> \n\n", " Options:\n", " -Dxxxx define xxxx, -Uxxxx undefine xxxx\n", " -C data->chip, -F data->fast\n", " -S don't use startups, -T don't use amiga.lib\n", " -A don't assemble, -c don't link\n", " -Ixxxx include dir, -V printout actions only\n", " -lxxxx use library lib:xxxx.lib\n"); } main(argc,argv) int argc; char *argv[]; { int i, l; char *s; printf("cc: \n"); if(argc < 2 || argv[1][0] == '?'){ help(); exit(0); } startup=standardblinklib=1;/* use BothStartup.obj & amiga.lib */ blinklibs[0]='\0'; /* blink lib direc */ blinkname[0]='\0'; /* output file from a68k */ a68kname[0]='\0'; /* output file from zc */ zcopts[0]='\0'; /* zc options for each phase */ a68kopts[0]='\0'; /* a68k options */ zctemp[0]='\0'; /* CCTEMP dir */ blinkopts[0]='\0'; /* blink options */ buf[0]='\0'; /* command line */ buf2[0]='\0'; /* scratch buf */ dodebug=debug=0; dozc=doa68k=doblink=1;/* will compile,assem,link unless told otherwise*/ curmem=NULL;/* haven't grabbed any memory yet*/ files=NULL; curfile=NULL; blinkxref=0; strcpy(xrefname," "); if( getenv("CCLIB") ){ strcpy(libdir," "); strcat(libdir,getenv("CCLIB")); /* get libdirector */ }else strcpy(libdir," lib:"); /* default directory */ if( ! getenv("CCEXEC") ) strcpy(cmddir,"c:"); else{ strcpy(cmddir,getenv("CCEXEC")); /*dir for zc,a68k,blink */ } if( getenv("CCTEMP") ){ strcpy(zctemp,getenv("CCTEMP")); }else{ printf("cc:Warning, environment variable CCTEMP unset\n Using ram: \n"); strcpy(zctemp,"ram:"); } if( ! getenv("INCLUDE")){ printf("cc: Warning, environment variable INCLUDE unset\n"); }else{ strcpy(a68kopts," -I"); strcat(a68kopts,getenv("INCLUDE") ); } for(i = 1; i < argc; i++){/* parse arguments */ Chk_Abort(); /* Do options */ if(argv[i][0] == '+'){ s = argv[i]; switch(s[1]){ default: printf("cc: No + switches allowed\n"); break; } }else if(argv[i][0] == '-' ){ s = argv[i]; switch(s[1]){ case 'A': case 'a': doblink = doa68k = 0; break; case 'C': /* force data into chip memory */ strcat(zcopts," -C "); break; case 'c': doblink = 0; break; case 'd': case 'D': strcat(zcopts," -D"); strcat(zcopts,&s[2]); break; case 'F': strcat(zcopts," -F "); break; case 'i': case 'I': strcat(zcopts," -I"); strcat(zcopts,&s[2]); break; case 'l': strcat(blinklibs," -l"); strcat(blinklibs,&s[2]); strcat(blinklibs," "); break; case 'T': standardblinklib=0; /* don't use amiga.lib */ break; case 'S': startup = 0;/* don't use BothStartup.obj */ break; case 'u': case 'U': strcat(zcopts," -U"); strcat(zcopts,&s[2]); break; case 'v': case 'V': debug = 1; break; default: printf("bad option: \"%s\"\n", argv[i]); exit(1); break; } }else /* argument wasn't an option so must be a file */ addfile(argv[i]);/* add filename to list of files */ }/* done with parsing arguments */ compilefiles(); /* compile all the files */ linkfiles(); /* link all the files */ quit();/* cleanup mess and go home */ } SHAR_EOF # End of shell archive exit 0 -- Bob Page, U of Lowell CS Dept. page@swan.ulowell.edu ulowell!page Have five nice days.