/* parse.c 718b */ XDef parse(Par p) { switch (p->alt) { case ATOM: /* parse ATOM and return 718c */ return mkDef(mkExp(parseexp(p))); case LIST: /* parse LIST and return 718d */ { Parlist pl = p->u.list; if (pl == NULL) error("%p: empty list", p); if (nthPL(pl, 0)->alt == ATOM) { Name first = nthPL(pl, 0)->u.atom; if (first == strtoname("define")) { /* parse define and return 719a */ Name name; Lambda l; if (lengthPL(pl) != 4 || nthPL(pl, 1)->alt != ATOM || nthPL( pl, 2)->alt != LIST) error("%p: usage: (define fun (args) body)", p); name = nthPL(pl, 1)->u.atom; l.formals = getnamelist(p, nthPL(pl, 2)->u.list); l.body = parseexp(nthPL(pl, 3)); return mkDef(mkDefine(name, l)); } if (first == strtoname("val")) { /* parse val and return 719b */ Exp var, exp; if (lengthPL(pl) != 3) error("%p: usage: (val var exp)", p); var = parseexp(nthPL(pl, 1)); if (var->alt != VAR) error("%p: usage: (val var exp) (bad variable)", p); exp = parseexp(nthPL(pl, 2)); return mkDef(mkVal(var->u.var, exp)); } if (first == strtoname("use")) { /* parse use and return 719c */ if (lengthPL(pl) != 2 || nthPL(pl, 1)->alt != ATOM) error("%p: usage: (use filename)", p); return mkUse(nthPL(pl, 1)->u.atom); } if (first == strtoname("check-expect")) { /* parse check-expect and return 719d */ { Exp check, expect; if (lengthPL(pl) != 3) error("%p: usage: (check-expect exp exp)", p); check = parseexp(nthPL(pl, 1)); expect = parseexp(nthPL(pl, 2)); return mkTest(mkCheckExpect(check, expect)); } } if (first == strtoname("check-error")) { /* parse check-error and return 719e */ { Exp check; if (lengthPL(pl) != 2) error("%p: usage: (check-error exp)", p); check = parseexp(nthPL(pl, 1)); return mkTest(mkCheckError(check)); } } } return mkDef(mkExp(parseexp(p))); } } assert(0); return NULL; }
/* * The parser needs to take concrete syntax, check to * see that it is well formed, and produce abstract * syntax. It provides the [[readtop]] function. * * At the top level, parsing amounts to looking for top * level constructs and passing the rest of the work to * [[parseexp]], which parses the input into [[Exp]]s. * <parse.c>= */ static XDef parse(Par p) { switch (p->alt) { case ATOM: /* * If we have a name, we treat it as an expression. * <parse [[atom]] and return the result>= */ return mkDef(mkExp(parseexp(p))); case LIST: /* * If we have a list, we need to look for [[define]], * [[val]], and [[use]]. * <parse [[list]] and return the result>= */ { Name first; Parlist pl = p->u.list; if (pl == NULL) error("%p: empty list", p); if (nthPL(pl, 0)->alt != ATOM) error("%p: first item of list not name", p); first = nthPL(pl, 0)->u.atom; if (first == strtoname("define")) { /* * Parsing definitions requires checking the argument * counts and then parsing the subpieces. For function * definitions, we could check that formal parameters * have distinct names, but that check is part of the * operational semantics for function definition. * <parse [[define]] and return the result>= */ if (lengthPL(pl) != 4 || nthPL(pl, 1)->alt != ATOM || nthPL(pl, 2)->alt != LIST) error("%p: usage: (define fun (formals) body)", p); { Name name = nthPL(pl, 1)->u.atom; Namelist formals = getnamelist(name, p, nthPL(pl, 2)->u.list); Exp body = parseexp(nthPL(pl, 3)); return mkDef(mkDefine(name, mkUserfun(formals, body))); } } if (first == strtoname("val")) { /* * <parse [[val]] and return the result>= */ Exp var, exp; if (lengthPL(pl) != 3) error("%p: usage: (val var exp)", p); var = parseexp(nthPL(pl, 1)); if (var->alt != VAR) error("%p: usage: (val var exp) (bad variable)", p); exp = parseexp(nthPL(pl, 2)); return mkDef(mkVal(var->u.var, exp)); } if (first == strtoname("use")) { /* * <parse [[use]] and return the result>= */ if (lengthPL(pl) != 2 || nthPL(pl, 1)->alt != ATOM) error("%p: usage: (use filename)", p); return mkUse(nthPL(pl, 1)->u.atom); } if (first == strtoname("check-expect")) { /* * <parse [[check-expect]] and return the result>= */ Exp check, expect; if (lengthPL(pl) != 3) error("%p: usage: (check-expect exp exp)", p); check = parseexp(nthPL(pl, 1)); expect = parseexp(nthPL(pl, 2)); return mkTest(mkCheckExpect(check, expect)); } if (first == strtoname("check-error")) { /* * <parse [[check-error]] and return the result>= */ Exp check; if (lengthPL(pl) != 2) error("%p: usage: (check-error exp)", p); check = parseexp(nthPL(pl, 1)); return mkTest(mkCheckError(check)); } return mkDef(mkExp(parseexp(p))); } } assert(0); return NULL; }
int main(int argc, char *argv[]) { printf("Threaded Ticket Seller - Project 3\n"); // Garbage seller is used to hold persons that // have been processed by the other sellers // we have to wait on possible frustrated users // threads have cleared or they may crash when their // data is freed garbage = createSeller(HIGH, 11); // finish creation of the concert hall hall.isSoldOut = FALSE; hall.hasStarted = FALSE; hall.lock = (pthread_mutex_t *) malloc(sizeof(pthread_mutex_t)); pthread_mutex_init(hall.lock,NULL); pthread_mutex_init(&outputLock,NULL); if (argc == 2) { if (argv[1][0] == 'T') { // do self test printf("Self Test\n"); mkTest(); printf("Self test succeeded\n"); exit(0); } int N = atoi(argv[1]); printf("Run with %d customers per ticket seller\n", N); //Create Sellers Seller *allSellers[NUM_SELLERS]; allSellers[0] = createSeller(HIGH, 0); int i; for (i = 1; i < 4; i++) { allSellers[i] = createSeller(MEDIUM, i); } for(i = 1; i < 7; i++){ allSellers[i+3] = createSeller(LOW, i + 3); } //declare person pointer Person *p; int sellerNum; //create thread when adding person to the Seller que pthread_t personThreadId[NUM_SELLERS*N]; //create thread for putting people into concert hall pthread_t sellerThreadId[NUM_SELLERS]; pthread_t timerTID; pthread_create(&timerTID,NULL,&timer,NULL); for (sellerNum = 0; sellerNum < NUM_SELLERS; sellerNum++) { pthread_create(&sellerThreadId[sellerNum], NULL, &sellTickets, (void *) allSellers[sellerNum]); for(i = 0; i < N; i++) { p = createPerson(allSellers[sellerNum]); //p->arrival = 0; pthread_create(&personThreadId[sellerNum*N+i], NULL, &addPerson, (void *) p); } } closeDoorsIn60Minutes(); waitForSellersToFinish(allSellers,NUM_SELLERS); } else { printf("Usage:\n"); printf("threadSeller [T|number]\n"); printf(" T - run self test without any threading\n"); printf(" number - number of customers per ticket seller\n"); printf(" full threaded simulation\n"); } printf("Exiting threadSeller\n"); return 0; }
/* parse.c 694a */ static XDef parse(Par p) { switch (p->alt) { case ATOM: /* parse [[atom]] and return the result 694b */ return mkDef(mkExp(parseexp(p))); case LIST: /* parse [[list]] and return the result 694c */ { Name first; Parlist pl = p->u.list; if (pl == NULL) error("%p: empty list", p); if (nthPL(pl, 0)->alt != ATOM) error("%p: first item of list not name", p); first = nthPL(pl, 0)->u.atom; if (first == strtoname("define")) { /* parse [[define]] and return the result */ if (lengthPL(pl) != 5 || nthPL(pl, 1)->alt != ATOM || nthPL(pl, 2)->alt != LIST || nthPL(pl, 3)->alt != LIST) error("%p: usage: (define fun (formals) (locals) body)", p); { Name name = nthPL(pl, 1)->u.atom; Namelist formals = getnamelist(name, p, nthPL(pl, 2)->u.list); Namelist locals = getnamelist(name, p, nthPL(pl, 3)->u.list); Exp body = parseexp(nthPL(pl, 4)); return mkDef(mkDefine(name, mkUserfun(formals, locals, body))); } } if (first == strtoname("val")) { /* parse [[val]] and return the result 695c */ Exp var, exp; if (lengthPL(pl) != 3) error("%p: usage: (val var exp)", p); var = parseexp(nthPL(pl, 1)); if (var->alt != VAR) error("%p: usage: (val var exp) (bad variable)", p); exp = parseexp(nthPL(pl, 2)); return mkDef(mkVal(var->u.var, exp)); } if (first == strtoname("use")) { /* parse [[use]] and return the result 695d */ if (lengthPL(pl) != 2 || nthPL(pl, 1)->alt != ATOM) error("%p: usage: (use filename)", p); return mkUse(nthPL(pl, 1)->u.atom); } if (first == strtoname("check-expect")) { /* parse [[check-expect]] and return the result 695e */ Exp check, expect; if (lengthPL(pl) != 3) error("%p: usage: (check-expect exp exp)", p); check = parseexp(nthPL(pl, 1)); expect = parseexp(nthPL(pl, 2)); return mkTest(mkCheckExpect(check, expect)); } if (first == strtoname("check-error")) { /* parse [[check-error]] and return the result 696a */ Exp check; if (lengthPL(pl) != 2) error("%p: usage: (check-error exp)", p); check = parseexp(nthPL(pl, 1)); return mkTest(mkCheckError(check)); } return mkDef(mkExp(parseexp(p))); } } assert(0); return NULL; }