+EMHOME = ../../..
+MODLIB = $(EMHOME)/modules/lib
+INCL = -I$(EMHOME)/modules/h
GFILES= occam.g
PRIMARY= occam.o Lpars.o keytab.o lex.yy.o code.o em.o
SECUNDARY= symtab.o expr.o builtin.o
TERTIARY= report.o
LLOPT=
-LIBRARY= -lln libemk.a libsystem.a
+LIBRARY= $(MODLIB)/libem_mes.a $(MODLIB)/libemk.a \
+ $(MODLIB)/libprint.a $(MODLIB)/libstring.a \
+ $(MODLIB)/libsystem.a -lln
+CFLAGS = -O $(INCL)
+HSRC = code.h em.h expr.h sizes.h symtab.h token.h
+CSRC = builtin.c code.c em.c expr.c keytab.c report.c symtab.c
-all:
- make dummy
+all: dummy
make oc
dummy: $(GFILES)
lex.yy.c: lex.l
lex lex.l
+install: all
+ rm -f $(EMHOME)/lib/em_occam
+ cp oc $(EMHOME)/lib/em_occam
+
+cmp: all
+ -cmp oc $(EMHOME)/lib/em_occam
+
+pr:
+ @pr Makefile $(HSRC) occam.g lex.l $(CSRC)
+
+opr:
+ make pr | opr
+
+clean:
+ rm -f lex.yy.c occam.c *.o oc
+
$(PRIMARY): Lpars.h
occam.o keytab.o: token.h
occam.o $(SECUNDARY): symtab.h expr.h
-#include <stdio.h>
#include "symtab.h"
#include "expr.h"
#include "sizes.h"
info.vc.st.builtin=file;
info.vc.offset=0;
- insert(file, T_CHAN|T_ARR|T_BUILTIN, _NFILE, info);
+ insert(file, T_CHAN|T_ARR|T_BUILTIN, 20, &info);
info.vc.st.builtin=file;
info.vc.offset=0;
- insert("input", T_CHAN|T_BUILTIN, 1, info);
+ insert("input", T_CHAN|T_BUILTIN, 1, &info);
info.vc.st.builtin=file;
info.vc.offset=wz+pz;
- insert("output", T_CHAN|T_BUILTIN, 1, info);
+ insert("output", T_CHAN|T_BUILTIN, 1, &info);
info.vc.st.builtin=file;
info.vc.offset=2*(wz+pz);
- insert("error", T_CHAN|T_BUILTIN, 1, info);
+ insert("error", T_CHAN|T_BUILTIN, 1, &info);
/* DEF EOF= -1, TEXT= -2, RAW= -3: */
info.const=new_const(-1L);
- insert("EOF", T_CONST|T_BUILTIN, 0, info);
+ insert("EOF", T_CONST|T_BUILTIN, 0, &info);
info.const=new_const(-2L);
- insert("TEXT", T_CONST|T_BUILTIN, 0, info);
+ insert("TEXT", T_CONST|T_BUILTIN, 0, &info);
info.const=new_const(-3L);
- insert("RAW", T_CONST|T_BUILTIN, 0, info);
+ insert("RAW", T_CONST|T_BUILTIN, 0, &info);
/* PROC open(VAR fd, VALUE name[], mode[])= .... : */
info.proc.st.builtin="b_open";
info.proc.pars=open_list;
- insert("open", T_PROC|T_BUILTIN, 0, info);
+ insert("open", T_PROC|T_BUILTIN, 0, &info);
/* PROC close(VALUE fd)= .... : */
info.proc.st.builtin="b_close";
info.proc.pars=close_list;
- insert("close", T_PROC|T_BUILTIN, 0, info);
+ insert("close", T_PROC|T_BUILTIN, 0, &info);
/* PROC exit(VALUE code)= .... : */
info.proc.st.builtin="b_exit";
info.proc.pars=exit_list;
- insert("exit", T_PROC|T_BUILTIN, 0, info);
+ insert("exit", T_PROC|T_BUILTIN, 0, &info);
}
-#include <stdio.h>
#include "sizes.h"
#include "Lpars.h"
-#include "em_arith.h"
-#include "em_label.h"
+#include <em.h>
#include "em.h"
/* This file is used to shield code.c as much as possible from em dependant
* word or double word arith.
*/
-int wz, pz;
+int wz = 4, pz = 4, vz = 4;
+int Lflag;
static Lab=0;
char *malloc();
void openfile(file) char *file;
{
- C_open(file);
+ if (C_open(file) < 0) {
+ fatal("Could not open output file");
+ }
}
void meswp()
{
- C_mes_begin(2);
- C_cst((arith) wz);
- C_cst((arith) pz);
- C_mes_end();
+ C_ms_emx((arith) wz, (arith) pz);
}
void maxdes()
lab=malloc(strlen(name)+(1+sizeof(int)*3+1));
/* That is: P<L><name>\0 */
- sprintf(lab, "P%d", L);
+ sprint(lab, "P%d", L);
n=lab+strlen(lab);
void lor0() { C_lor((arith) 0); }
void lxa(offset) int offset; { C_lxa((arith) offset); }
void lxl(offset) int offset; { C_lxl((arith) offset); }
-void meserr() { C_mes_begin(0); C_mes_end(); }
+void meserr() { C_ms_err(); }
void ngi() { C_ngi((arith) vz); }
void pro(lab) char *lab; { C_pro_narg(lab); }
void ret(size) int size; { C_ret((arith) size); }
char *itoa(i) long i;
{
static char a[sizeof(long)*3];
- sprintf(a, "%D", i);
+ sprint(a, "%ld", i);
return a;
}
static oldline=0;
extern yylineno;
+ if (Lflag) return;
if (yylineno!=oldline)
C_lin((arith) (oldline=yylineno));
}
static void do_fil(f) struct ftree *f;
{
+ if (Lflag) return;
if (f->lab==0) {
dot_label(new_dot_label(&f->lab));
- C_rom_scon(f->file, (arith) strlen(f->file));
+ C_rom_scon(f->file, (arith) (strlen(f->file)+1));
}
C_fil_dlb((label) f->lab);
}
void main_fil(), init(), openfile(), closefile(), maxdes();
void par_begin(), par_fork(), par_end(), resumenext(), no_deadlock();
+extern int Lflag;
static char c[7];
if (' '<tk && tk<='~')
- sprintf(c, "'%c'", tk);
+ sprint(c, "'%c'", tk);
else
- sprintf(c, "'*#%02x'", tk);
+ sprint(c, "'*#%02x'", tk);
return c;
} else {
switch (tk) {
return keyname(tk);
case IDENTIFIER:
if (inst) {
- sprintf(fake_id, "_%d", ++fake_cnt);
+ sprint(fake_id, "_%d", ++fake_cnt);
token.t_sval=strcpy(malloc(strlen(fake_id)+1),
fake_id);
return "IDENTIFIER";
static char qopc[5];
for (i=0; op[i]!=tk; i++) ;
- sprintf(qopc, "'%s'", opc[i]);
+ sprint(qopc, "'%s'", opc[i]);
return qopc;
}
}
#include "expr.h"
#include "code.h"
#include "sizes.h"
+#include <system.h>
+#include <em.h>
#define MAXERRORS 10 /* Maximum number of insert/delete errors */
sym_down();
var_memory(&info, T_VAR, 1);
*s=insert(index,
- T_VAR|T_REP|T_USED|T_ASSIGNED, 1, info);
+ T_VAR|T_REP|T_USED|T_ASSIGNED, 1, &info);
}
;
]?
{ chan_memory(&info, arr_siz);
chan_init(&info, arr_siz);
- insert(name, type, arr_siz, info);
+ insert(name, type, arr_siz, &info);
}
;
}
]?
{ var_memory(&info, type, arr_siz);
- insert(name, type, arr_siz, info);
+ insert(name, type, arr_siz, &info);
}
;
{ if (!constant(e) && !arr_constant(e))
nonconst("expression in constant definition");
info.const=e;
- insert(name, T_CONST|T_USED, 0, info);
+ insert(name, T_CONST|T_USED, 0, &info);
}
;
{ type|=T_ARR; }
]?
{ pars_add(aapars, type&(T_TYPE|T_ARR),
- insert(name, type|T_PARAM, 0, none));
+ insert(name, type|T_PARAM, 0, &none));
}
;
}:
PROC IDENTIFIER { branch(&OVER);
proc=insert(token.t_sval,
- T_PROC|T_RECURS, 0, none);
+ T_PROC|T_RECURS, 0, &none);
old_min_offset=min_offset;
sym_down();
prologue(proc);
%lexical scanner;
{
int err=0;
-#include <stdio.h>
main(argc, argv) register argc; register char **argv;
{
- wz= (argc>1 && strcmp(argv[1], "4")==0) ? 4 : 2;
- pz= (argc>2 && strcmp(argv[2], "4")==0) ? 4 : wz;
+ while (argc > 1 && argv[1][0] == '-') {
+ do_option(&argv[1][1]);
+ argc--;
+ argv++;
+ }
leader();
occam();
exit(err);
}
+do_option(text)
+ char *text;
+{
+ extern int Lflag;
+
+ switch(*text++) {
+
+ default:
+ fatal("illegal option: %c", *--text);
+
+ case 'L' : /* no fil/lin */
+ Lflag++;
+ break;
+ case 'V' : /* set object sizes and alignment requirements */
+ {
+ arith size, align;
+ char c;
+
+ while (c = *text++) {
+ size = txt2int(&text);
+ switch (c) {
+ case 'w': /* word */
+ if (size != (arith)0)
+ wz = size;
+ break;
+ case 'p': /* pointer */
+ if (size != (arith)0)
+ pz = size;
+ break;
+ case 'l': /* long */
+ if (size != (arith)0)
+ vz = size;
+ break;
+ default:
+ fatal("-V: bad type indicator %c\n", c);
+ }
+ }
+ break;
+ }
+ }
+}
+
+int
+txt2int(tp)
+ char **tp;
+{
+ /* the integer pointed to by *tp is read, while increasing
+ *tp; the resulting value is yielded.
+ */
+ register int val = 0, ch;
+
+ while (ch = **tp, ch >= '0' && ch <= '9') {
+ val = val * 10 + ch - '0';
+ (*tp)++;
+ }
+ return val;
+}
+
LLmessage(tk) register tk;
{
static errors=0;
if (tk==0)
warning("syntax error: bad token %s (deleted)", tokenname(LLsymb, 0));
else { /* tk<0 */
- fprintf(stderr, "Compiler stack overflow. Compiler ends.");
- err=1; trailer(); exit(1);
+ warning("syntax error: garbage at end of program");
}
if (++errors==MAXERRORS) {
- fprintf(stderr, "Too many insert/delete errors. Compiler ends.\n");
+ fprint(STDERR, "Too many insert/delete errors. Compiler ends.\n");
err=1; trailer(); exit(1);
}
}
-#include <stdio.h>
+#include <system.h>
extern int err, yylineno;
extern char *curr_file;
report(fmt, arg1, arg2, arg3) char *fmt;
{
- fprintf(stderr, "%s (%d) F: ", curr_file, yylineno);
- fprintf(stderr, fmt, arg1, arg2, arg3);
- putc('\n', stderr);
+ fprint(STDERR, "%s (%d) F: ", curr_file, yylineno);
+ fprint(STDERR, fmt, arg1, arg2, arg3);
+ fprint(STDERR,"\n");
err=1;
}
warning(fmt, arg1, arg2, arg3) char *fmt, *arg1;
{
- fprintf(stderr, "%s (%d) E: ", curr_file, yylineno);
- fprintf(stderr, fmt, arg1, arg2, arg3);
- putc('\n', stderr);
+ fprint(STDERR, "%s (%d) E: ", curr_file, yylineno);
+ fprint(STDERR, fmt, arg1, arg2, arg3);
+ fprint(STDERR,"\n");
+}
+
+fatal(fmt, arg1, arg2, arg3) char *fmt, *arg1;
+{
+ fprint(STDERR, "%s (%d) X: ", curr_file, yylineno);
+ fprint(STDERR, fmt, arg1, arg2, arg3);
+ fprint(STDERR,"\n");
+ exit(1);
}
/* Variable size, wordsize, pointer size. Offsets for local variables. */
-#define vz 4
-extern int wz, pz;
+extern int wz, pz, vz;
extern int curr_level, curr_offset, min_offset;
struct symbol *insert(name, type, arr_siz, info)
char *name;
int type, arr_siz;
- union type_info info;
+ union type_info *info;
/* Inserts an object with given name and other info into the current symbol
* tree. A pointer is returned to the inserted symbol so that more info may
* or changed. Nil is returned on redeclaration.
type|=T_USED; /* are always used */
ps->type=type;
ps->arr_siz=arr_siz;
- ps->info=info;
+ ps->info= *info;
ps->left=ps->right=nil;
*aps=ps;
tab=tab->global;
}
report("%s not declared", name);
- return insert(name, T_NOTDECL, 0, none);
+ return insert(name, T_NOTDECL, 0, &none);
}
void check_recursion(proc)